You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
7.0 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. from functools import partial
  2. from gooey.gui.lang import i18n
  3. from gooey.gui.util.filedrop import FileDrop
  4. from gooey.gui.util.quoting import quote
  5. __author__ = 'Chris'
  6. from abc import ABCMeta, abstractmethod
  7. import os
  8. import wx
  9. import wx.lib.agw.multidirdialog as MDD
  10. from gooey.gui.widgets.calender_dialog import CalendarDlg
  11. class WidgetPack(object):
  12. """
  13. Interface specifying the contract to which
  14. all `WidgetPack`s will adhere
  15. """
  16. __metaclass__ = ABCMeta
  17. @abstractmethod
  18. def build(self, parent, data):
  19. pass
  20. @abstractmethod
  21. def getValue(self):
  22. pass
  23. def onResize(self, evt):
  24. pass
  25. @staticmethod
  26. def get_command(data):
  27. return data['commands'][0] if data['commands'] else ''
  28. @staticmethod
  29. def disable_quoting(data):
  30. nargs = data.get('nargs', None)
  31. if not nargs:
  32. return False
  33. return nargs not in (1, '?')
  34. class BaseChooser(WidgetPack):
  35. def __init__(self, button_text=''):
  36. self.button_text = i18n._('browse')
  37. self.option_string = None
  38. self.parent = None
  39. self.text_box = None
  40. self.button = None
  41. def build(self, parent, data):
  42. self.parent = parent
  43. self.option_string = self.get_command(data)
  44. self.text_box = wx.TextCtrl(self.parent)
  45. self.text_box.AppendText(safe_default(data, ''))
  46. self.text_box.SetMinSize((0, -1))
  47. dt = FileDrop(self.text_box)
  48. self.text_box.SetDropTarget(dt)
  49. self.button = wx.Button(self.parent, label=self.button_text, size=(73, 23))
  50. widget_sizer = wx.BoxSizer(wx.HORIZONTAL)
  51. widget_sizer.Add(self.text_box, 1, wx.EXPAND)
  52. widget_sizer.AddSpacer(10)
  53. widget_sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
  54. parent.Bind(wx.EVT_BUTTON, self.onButton, self.button)
  55. return widget_sizer
  56. def getValue(self):
  57. value = self.text_box.GetValue()
  58. if self.option_string and value:
  59. return '{0} {1}'.format(self.option_string, quote(value))
  60. else:
  61. return quote(value) if value else ''
  62. def onButton(self, evt):
  63. raise NotImplementedError
  64. def __repr__(self):
  65. return self.__class__.__name__
  66. class BaseFileChooser(BaseChooser):
  67. def __init__(self, dialog):
  68. BaseChooser.__init__(self)
  69. self.dialog = dialog
  70. def onButton(self, evt):
  71. dlg = self.dialog(self.parent)
  72. result = (self.get_path(dlg)
  73. if dlg.ShowModal() == wx.ID_OK
  74. else None)
  75. if result:
  76. self.text_box.SetValue(result)
  77. def get_path(self, dlg):
  78. return dlg.GetPath()
  79. class BaseMultiFileChooser(BaseFileChooser):
  80. def __init__(self, dialog):
  81. BaseFileChooser.__init__(self, dialog)
  82. def getValue(self):
  83. value = ' '.join(quote(x) for x in self.text_box.GetValue().split(os.pathsep) if x)
  84. if self.option_string and value:
  85. return '{} {}'.format(self.option_string, value)
  86. return value or ''
  87. def get_path(self, dlg):
  88. return os.pathsep.join(dlg.GetPaths())
  89. class MyMultiDirChooser(MDD.MultiDirDialog):
  90. def __init__(self, *args, **kwargs):
  91. super(MyMultiDirChooser, self).__init__(*args, **kwargs)
  92. def GetPaths(self):
  93. return self.dirCtrl.GetPaths()
  94. def build_dialog(style, exist_constraint=True, **kwargs):
  95. if exist_constraint:
  96. return lambda panel: wx.FileDialog(panel, style=style | wx.FD_FILE_MUST_EXIST, **kwargs)
  97. else:
  98. return lambda panel: wx.FileDialog(panel, style=style, **kwargs)
  99. FileChooserPayload = partial(BaseFileChooser, dialog=build_dialog(wx.FD_OPEN))
  100. FileSaverPayload = partial(BaseFileChooser, dialog=build_dialog(wx.FD_SAVE, False, defaultFile="Enter Filename"))
  101. MultiFileSaverPayload = partial(BaseMultiFileChooser, dialog=build_dialog(wx.FD_MULTIPLE, False))
  102. DirChooserPayload = partial(BaseFileChooser, dialog=lambda parent: wx.DirDialog(parent, 'Select Directory', style=wx.DD_DEFAULT_STYLE))
  103. DateChooserPayload = partial(BaseFileChooser, dialog=CalendarDlg)
  104. MultiDirChooserPayload = partial(BaseMultiFileChooser, dialog=lambda parent: MyMultiDirChooser(parent, title="Select Directories", defaultPath=os.getcwd(), agwStyle=MDD.DD_MULTIPLE|MDD.DD_DIR_MUST_EXIST))
  105. class TextInputPayload(WidgetPack):
  106. def __init__(self, no_quoting=False):
  107. self.widget = None
  108. self.option_string = None
  109. self.no_quoting = no_quoting
  110. def build(self, parent, data):
  111. self.option_string = self.get_command(data)
  112. if self.disable_quoting(data):
  113. self.no_quoting = True
  114. self.widget = wx.TextCtrl(parent)
  115. dt = FileDrop(self.widget)
  116. self.widget.SetDropTarget(dt)
  117. self.widget.SetMinSize((0, -1))
  118. self.widget.SetDoubleBuffered(True)
  119. self.widget.AppendText(safe_default(data, ''))
  120. return self.widget
  121. def getValue(self):
  122. if self.no_quoting:
  123. _quote = lambda value: value
  124. else:
  125. _quote = quote
  126. value = self.widget.GetValue()
  127. if value and self.option_string:
  128. return '{} {}'.format(self.option_string, _quote(value))
  129. else:
  130. return _quote(value) if value else ''
  131. def _SetValue(self, text):
  132. # used for testing
  133. self.widget.SetLabelText(text)
  134. class DropdownPayload(WidgetPack):
  135. default_value = 'Select Option'
  136. def __init__(self, no_quoting=False):
  137. self.widget = None
  138. self.option_string = None
  139. self.no_quoting = no_quoting
  140. def build(self, parent, data):
  141. self.option_string = self.get_command(data)
  142. if self.disable_quoting(data):
  143. self.no_quoting = True
  144. self.widget = wx.ComboBox(
  145. parent=parent,
  146. id=-1,
  147. value=safe_default(data, self.default_value),
  148. choices=data['choices'],
  149. style=wx.CB_DROPDOWN
  150. )
  151. return self.widget
  152. def getValue(self):
  153. if self.no_quoting:
  154. _quote = lambda value: value
  155. else:
  156. _quote = quote
  157. value = self.widget.GetValue()
  158. if value == self.default_value:
  159. return ''
  160. elif value and self.option_string:
  161. return '{} {}'.format(self.option_string, _quote(value))
  162. else:
  163. return _quote(value) if value else ''
  164. def _SetValue(self, text):
  165. # used for testing
  166. self.widget.SetLabelText(text)
  167. class CounterPayload(WidgetPack):
  168. def __init__(self):
  169. self.option_string = None
  170. self.widget = None
  171. def build(self, parent, data):
  172. self.option_string = self.get_command(data)
  173. self.widget = wx.ComboBox(
  174. parent=parent,
  175. id=-1,
  176. value=safe_default(data, ''),
  177. choices=map(str, range(1, 11)),
  178. style=wx.CB_DROPDOWN
  179. )
  180. return self.widget
  181. def getValue(self):
  182. '''
  183. Returns
  184. str(option_string * DropDown Value)
  185. e.g.
  186. -vvvvv
  187. '''
  188. dropdown_value = self.widget.GetValue()
  189. if not str(dropdown_value).isdigit():
  190. return ''
  191. arg = str(self.option_string).replace('-', '')
  192. repeated_args = arg * int(dropdown_value)
  193. return '-' + repeated_args
  194. def safe_default(data, default):
  195. # str(None) is 'None'!? Whaaaaat...?
  196. return str(data['default']) if data['default'] else default