mirror of https://github.com/chriskiehl/Gooey.git
Chris Kiehl
11 years ago
7 changed files with 388 additions and 80 deletions
Unified View
Diff Options
-
132src/app/dialogs/action_sorter.py
-
32src/app/dialogs/advanced_config.py
-
75src/app/dialogs/component_factory.py
-
152src/app/dialogs/components.py
-
71src/app/dialogs/components_unittest.py
-
1src/model/example_argparse_souce.py
-
5src/model/source_parser.py
@ -0,0 +1,132 @@ |
|||||
|
''' |
||||
|
Created on Dec 8, 2013 |
||||
|
|
||||
|
@author: Chris |
||||
|
''' |
||||
|
|
||||
|
import wx |
||||
|
from argparse import ( |
||||
|
_StoreAction, _StoreConstAction, |
||||
|
_StoreFalseAction, _StoreTrueAction, |
||||
|
_CountAction, _AppendAction) |
||||
|
|
||||
|
class ActionSorter(object): |
||||
|
''' |
||||
|
So this thing is the thing that will |
||||
|
pull out all of the "types" from the |
||||
|
argparse object and turn them into the |
||||
|
correct wx components |
||||
|
|
||||
|
COMPONENT MAP |
||||
|
Action WxWidget |
||||
|
-------------------------- |
||||
|
store TextCtrl |
||||
|
store_const CheckBox |
||||
|
store_true CheckBox |
||||
|
store_False CheckBox |
||||
|
append TextCtrl |
||||
|
count DropDown |
||||
|
choice DropDown |
||||
|
|
||||
|
_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None) |
||||
|
_StoreAction(option_strings=[], dest='filename', nargs=None, const=None, default=None, type=None, choices=None, help='filename', metavar=None) |
||||
|
_StoreTrueAction(option_strings=['-r', '--recursive'], dest='recurse', nargs=0, const=True, default=False, type=None, choices=None, help='recurse into subfolders [default: %(default)s]', metavar=None) |
||||
|
_CountAction(option_strings=['-v', '--verbose'], dest='verbose', nargs=0, const=None, default=None, type=None, choices=None, help='set verbosity level [default: %(default)s]', metavar=None) |
||||
|
_AppendAction(option_strings=['-i', '--include'], dest='include', nargs=None, const=None, default=None, type=None, choices=None, help='only include paths matching this regex pattern. Note: exclude is given preference over include. [default: %(default)s]', metavar='RE') |
||||
|
_StoreAction(option_strings=['-e', '--exclude'], dest='exclude', nargs=None, const=None, default=None, type=None, choices=None, help='exclude paths matching this regex pattern. [default: %(default)s]', metavar='RE') |
||||
|
_VersionAction(option_strings=['-V', '--version'], dest='version', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help="show program's version number and exit", metavar=None) |
||||
|
_StoreAction(option_strings=['-T', '--tester'], dest='tester', nargs=None, const=None, default=None, type=None, choices=['yes', 'no'], help=None, metavar=None) |
||||
|
_StoreAction(option_strings=[], dest='paths', nargs='+', const=None, default=None, type=None, choices=None, help='paths to folder(s) with source file(s) [default: %(default)s]', metavar='path') |
||||
|
usage: example_argparse_souce.py [-h] [-r] [-v] [-i RE] [-e RE] [-V] |
||||
|
''' |
||||
|
|
||||
|
def __init__(self, parser): |
||||
|
self._parser = parser |
||||
|
self._actions = self._parser._actions[:] # Copy all of the actions |
||||
|
|
||||
|
self._positionals = self.get_positionals(self._actions) |
||||
|
self._choices = self.get_optionals_with_choices(self._actions) |
||||
|
self._optionals = self.get_optionals_without_choices(self._actions) |
||||
|
self._booleans = self.get_flag_style_optionals(self._actions) |
||||
|
self._counters = self.get_counter_actions(self._actions) |
||||
|
|
||||
|
self._display('ActionSorter: positionals', self._positionals) |
||||
|
self._display('ActionSorter: choices', self._choices) |
||||
|
self._display('ActionSorter: optionals', self._optionals) |
||||
|
self._display('ActionSorter: booleans', self._booleans) |
||||
|
self._display('ActionSorter: counters', self._counters) |
||||
|
|
||||
|
def _display(self, _type, something): |
||||
|
for i in something: |
||||
|
print _type, i |
||||
|
|
||||
|
def get_counter_actions(self, actions): |
||||
|
''' |
||||
|
Returns all instances of type _CountAction |
||||
|
''' |
||||
|
return [action |
||||
|
for action in actions |
||||
|
if isinstance(action, _CountAction)] |
||||
|
|
||||
|
def get_positionals(self, actions): |
||||
|
''' |
||||
|
Get all required (positional) actions |
||||
|
''' |
||||
|
return [action |
||||
|
for action in actions |
||||
|
if not action.option_strings] |
||||
|
|
||||
|
def get_optionals_without_choices(self, actions): |
||||
|
''' |
||||
|
All actions which are |
||||
|
(a) Optional, but without required choices |
||||
|
(b) Not of a "boolean" type (storeTrue, etc..) |
||||
|
(c) Of type _AppendAction |
||||
|
|
||||
|
e.g. anything which has an argument style like: |
||||
|
>>> -f myfilename.txt |
||||
|
''' |
||||
|
boolean_actions = ( |
||||
|
_StoreConstAction, _StoreFalseAction, |
||||
|
_StoreTrueAction |
||||
|
) |
||||
|
return [action |
||||
|
for action in actions |
||||
|
if action.option_strings |
||||
|
and not action.choices |
||||
|
and action not in boolean_actions] |
||||
|
|
||||
|
def get_optionals_with_choices(self, actions): |
||||
|
''' |
||||
|
All optional arguments which are constrained |
||||
|
to specific choices. |
||||
|
''' |
||||
|
return [action |
||||
|
for action in actions |
||||
|
if action.choices] |
||||
|
|
||||
|
def get_flag_style_optionals(self, actions): |
||||
|
''' |
||||
|
Gets all instances of "flag" type options. |
||||
|
i.e. options which either store a const, or |
||||
|
store boolean style options (e.g. StoreTrue). |
||||
|
Types: |
||||
|
_StoreTrueAction |
||||
|
_StoreFalseAction |
||||
|
_StoreConst |
||||
|
''' |
||||
|
return [action |
||||
|
for action in actions |
||||
|
if isinstance(action, _StoreTrueAction) |
||||
|
or isinstance(action, _StoreFalseAction) |
||||
|
or isinstance(action, _StoreConstAction)] |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,152 @@ |
|||||
|
''' |
||||
|
Created on Jan 1, 2014 |
||||
|
|
||||
|
@author: Chris |
||||
|
|
||||
|
''' |
||||
|
|
||||
|
import wx |
||||
|
from argparse import ArgumentParser |
||||
|
from abc import ABCMeta, abstractmethod |
||||
|
|
||||
|
|
||||
|
class BuildException(RuntimeError): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
class AbstractComponent(object): |
||||
|
''' |
||||
|
Template pattern-y abstract class for the components. |
||||
|
Children must all implement the BuildWidget and getValue |
||||
|
methods. |
||||
|
''' |
||||
|
__metaclass__ = ABCMeta |
||||
|
|
||||
|
def __init__(self): |
||||
|
self._widget = None |
||||
|
|
||||
|
def Build(self, parent): |
||||
|
self._widget = self.BuildWidget(parent, self._action) |
||||
|
sizer = wx.BoxSizer(wx.VERTICAL) |
||||
|
|
||||
|
sizer.Add(self.CreateDestNameWidget(parent, self._action)) |
||||
|
sizer.AddSpacer(2) |
||||
|
|
||||
|
if self.HasHelpMsg(self._action): |
||||
|
sizer.Add(self.CreateHelpMsgWidget(parent, self._action)) |
||||
|
sizer.AddSpacer(2) |
||||
|
|
||||
|
if self.HasNargs(self._action): |
||||
|
sizer.Add(self.AddNargsMsg(parent, self._action)) |
||||
|
|
||||
|
sizer.Add(self._widget, 0, wx.EXPAND) |
||||
|
return sizer |
||||
|
|
||||
|
def HasHelpMsg(self, action): |
||||
|
return action.help is not None |
||||
|
|
||||
|
def HasNargs(self, action): |
||||
|
return action.nargs == '+' |
||||
|
|
||||
|
def CreateHelpMsgWidget(self, parent, action): |
||||
|
text = wx.StaticText(parent, label=action.help) |
||||
|
self.MakeDarkGrey(text) |
||||
|
return text |
||||
|
|
||||
|
def AddNargsMsg(self, parent, action): |
||||
|
msg = 'Note: at least 1 or more arguments are required' |
||||
|
return wx.StaticText(parent, label=msg) |
||||
|
|
||||
|
def CreateDestNameWidget(self, parent, action): |
||||
|
text = wx.StaticText(parent, label=str(action.dest).title()) |
||||
|
self.MakeBold(text) |
||||
|
return text |
||||
|
|
||||
|
def AssertInitialization(self, widget, clsname): |
||||
|
print self._widget |
||||
|
if not self._widget: |
||||
|
raise BuildException('%s was not correctly initialized' % clsname) |
||||
|
|
||||
|
def MakeBold(self, statictext): |
||||
|
pointsize = statictext.GetFont().GetPointSize() |
||||
|
statictext.SetFont(wx.Font(pointsize, wx.FONTFAMILY_DEFAULT, |
||||
|
wx.FONTWEIGHT_NORMAL, wx.FONTWEIGHT_BOLD, False)) |
||||
|
|
||||
|
def MakeDarkGrey(self, statictext): |
||||
|
darkgray = (54,54,54) |
||||
|
statictext.SetForegroundColour(darkgray) |
||||
|
|
||||
|
|
||||
|
@abstractmethod |
||||
|
def BuildWidget(self, parent, action): |
||||
|
''' |
||||
|
Must construct the main widget type for the Action |
||||
|
''' |
||||
|
pass |
||||
|
|
||||
|
@abstractmethod |
||||
|
def GetValue(self): |
||||
|
''' |
||||
|
Returns the state of the given widget |
||||
|
''' |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
|
||||
|
class Positional(AbstractComponent): |
||||
|
def __init__(self, action): |
||||
|
self._action = action |
||||
|
self._widget = None |
||||
|
self.contents = None |
||||
|
|
||||
|
def BuildWidget(self, parent, action): |
||||
|
return wx.TextCtrl(parent) |
||||
|
|
||||
|
def GetValue(self): |
||||
|
self.AssertInitialization(self._widget, 'Positional') |
||||
|
return self._widget.GetValue() |
||||
|
|
||||
|
|
||||
|
class Choice(AbstractComponent): |
||||
|
def __init__(self, action): |
||||
|
self._action = action |
||||
|
self._widget = None |
||||
|
self.contents = None |
||||
|
|
||||
|
def GetValue(self): |
||||
|
self.AssertInitialization() |
||||
|
return self._widget.GetValue() |
||||
|
|
||||
|
def BuildWidget(self, parent, action): |
||||
|
return wx.ComboBox( |
||||
|
parent=parent, |
||||
|
id=-1, |
||||
|
value='Select Option', |
||||
|
choices=action.choices, |
||||
|
style=wx.CB_DROPDOWN |
||||
|
) |
||||
|
|
||||
|
|
||||
|
class Optional(AbstractComponent): |
||||
|
def __init__(self, action): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
parser = ArgumentParser(description='Example Argparse Program') |
||||
|
parser.add_argument("filename", help="filename") |
||||
|
action = parser._actions[1] |
||||
|
positional = Positional(action) |
||||
|
|
||||
|
a = getattr |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,71 @@ |
|||||
|
''' |
||||
|
Created on Jan 4, 2014 |
||||
|
|
||||
|
@author: Chris |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
''' |
||||
|
|
||||
|
import wx |
||||
|
import os |
||||
|
import sys |
||||
|
import unittest |
||||
|
import components |
||||
|
from argparse import ArgumentParser |
||||
|
|
||||
|
|
||||
|
class ComponentsTest(unittest.TestCase): |
||||
|
|
||||
|
def setUp(self): |
||||
|
parser = ArgumentParser(description='Example Argparse Program') |
||||
|
parser.add_argument("filename", help="Name of the file you want to read") |
||||
|
parser.add_argument('-T', '--tester', choices=['yes','no']) |
||||
|
action = parser._actions |
||||
|
self.actions = { |
||||
|
'help' : action[0], |
||||
|
'Positional' : action[1], |
||||
|
'Choice' : action[2] |
||||
|
} |
||||
|
|
||||
|
|
||||
|
def BuildWindow(self, component): |
||||
|
|
||||
|
app = wx.PySimpleApp() |
||||
|
module_name = os.path.split(sys.argv[0])[-1] |
||||
|
frame = wx.Frame(None, -1, module_name) |
||||
|
|
||||
|
panel = wx.Panel(frame, -1, size=(320,240)) |
||||
|
component_sizer = component.Build(panel) |
||||
|
panel.SetSizer(component_sizer) |
||||
|
|
||||
|
frame.Show(True) |
||||
|
|
||||
|
print component.GetValue() |
||||
|
app.MainLoop() |
||||
|
|
||||
|
def testPositionalWidgetBuild(self): |
||||
|
self.SetupWidgetAndBuildWindow('Positional') |
||||
|
# component = components.Positional(self.actions['positional']) |
||||
|
# self.BuildWindow(component) |
||||
|
|
||||
|
def testChoiceWidgetBuild(self): |
||||
|
self.SetupWidgetAndBuildWindow('Choice') |
||||
|
|
||||
|
def SetupWidgetAndBuildWindow(self, _type): |
||||
|
component = getattr(components, _type)(self.actions[_type]) |
||||
|
self.BuildWindow(component) |
||||
|
|
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
# import sys;sys.argv = ['', 'Test.testName'] |
||||
|
unittest.main() |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
Write
Preview
Loading…
Cancel
Save