dialog.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. """ \
  2. Base class for Dialogs. Also contains a few useful utility functions
  3. """
  4. # dialog.py
  5. # Python class for Dialog Boxes in PythonWin.
  6. import win32ui
  7. import win32con
  8. # sob - 2to3 doesn't see this as a relative import :(
  9. from pywin.mfc import window
  10. def dllFromDll(dllid):
  11. " given a 'dll' (maybe a dll, filename, etc), return a DLL object "
  12. if dllid==None:
  13. return None
  14. elif type('')==type(dllid):
  15. return win32ui.LoadLibrary(dllid)
  16. else:
  17. try:
  18. dllid.GetFileName()
  19. except AttributeError:
  20. raise TypeError("DLL parameter must be None, a filename or a dll object")
  21. return dllid
  22. class Dialog(window.Wnd):
  23. " Base class for a dialog"
  24. def __init__( self, id, dllid=None ):
  25. """ id is the resource ID, or a template
  26. dllid may be None, a dll object, or a string with a dll name """
  27. # must take a reference to the DLL until InitDialog.
  28. self.dll=dllFromDll(dllid)
  29. if type(id)==type([]): # a template
  30. dlg=win32ui.CreateDialogIndirect(id)
  31. else:
  32. dlg=win32ui.CreateDialog(id, self.dll)
  33. window.Wnd.__init__(self, dlg)
  34. self.HookCommands()
  35. self.bHaveInit = None
  36. def HookCommands(self):
  37. pass
  38. def OnAttachedObjectDeath(self):
  39. self.data = self._obj_.data
  40. window.Wnd.OnAttachedObjectDeath(self)
  41. # provide virtuals.
  42. def OnOK(self):
  43. self._obj_.OnOK()
  44. def OnCancel(self):
  45. self._obj_.OnCancel()
  46. def OnInitDialog(self):
  47. self.bHaveInit = 1
  48. if self._obj_.data:
  49. self._obj_.UpdateData(0)
  50. return 1 # I did NOT set focus to a child window.
  51. def OnDestroy(self,msg):
  52. self.dll = None # theoretically not needed if object destructs normally.
  53. # DDX support
  54. def AddDDX( self, *args ):
  55. self._obj_.datalist.append(args)
  56. # Make a dialog object look like a dictionary for the DDX support
  57. def __bool__(self):
  58. return True
  59. def __len__(self): return len(self.data)
  60. def __getitem__(self, key): return self.data[key]
  61. def __setitem__(self, key, item): self._obj_.data[key] = item# self.UpdateData(0)
  62. def keys(self): return list(self.data.keys())
  63. def items(self): return list(self.data.items())
  64. def values(self): return list(self.data.values())
  65. # XXX - needs py3k work!
  66. def has_key(self, key): return key in self.data
  67. class PrintDialog(Dialog):
  68. " Base class for a print dialog"
  69. def __init__(self, pInfo, dlgID,
  70. printSetupOnly = 0,
  71. flags=(win32ui.PD_ALLPAGES|
  72. win32ui.PD_USEDEVMODECOPIES|
  73. win32ui.PD_NOPAGENUMS|
  74. win32ui.PD_HIDEPRINTTOFILE|
  75. win32ui.PD_NOSELECTION),
  76. parent=None,
  77. dllid=None):
  78. self.dll=dllFromDll(dllid)
  79. if type(dlgID)==type([]): # a template
  80. raise TypeError("dlgID parameter must be an integer resource ID")
  81. dlg=win32ui.CreatePrintDialog(dlgID, printSetupOnly,
  82. flags, parent,
  83. self.dll)
  84. window.Wnd.__init__(self, dlg)
  85. self.HookCommands()
  86. self.bHaveInit = None
  87. self.pInfo = pInfo
  88. # init values (if PrintSetup is called, values still available)
  89. flags = pInfo.GetFlags()
  90. self['toFile'] = (flags&win32ui.PD_PRINTTOFILE != 0)
  91. self['direct'] = pInfo.GetDirect()
  92. self['preview'] = pInfo.GetPreview()
  93. self['continuePrinting'] = pInfo.GetContinuePrinting()
  94. self['curPage'] = pInfo.GetCurPage()
  95. self['numPreviewPages'] = pInfo.GetNumPreviewPages()
  96. self['userData'] = pInfo.GetUserData()
  97. self['draw'] = pInfo.GetDraw()
  98. self['pageDesc'] = pInfo.GetPageDesc()
  99. self['minPage'] = pInfo.GetMinPage()
  100. self['maxPage'] = pInfo.GetMaxPage()
  101. self['offsetPage'] = pInfo.GetOffsetPage()
  102. self['fromPage'] = pInfo.GetFromPage()
  103. self['toPage'] = pInfo.GetToPage()
  104. # these values updated after OnOK
  105. self['copies'] = 0
  106. self['deviceName'] = ''
  107. self['driverName'] = ''
  108. self['printAll'] = 0
  109. self['printCollate'] = 0
  110. self['printRange'] = 0
  111. self['printSelection'] = 0
  112. def OnInitDialog(self):
  113. self.pInfo.CreatePrinterDC() # This also sets the hDC of the pInfo structure.
  114. return self._obj_.OnInitDialog()
  115. def OnCancel(self):
  116. del self.pInfo
  117. def OnOK(self):
  118. '''DoModal has finished. Can now access the users choices'''
  119. self._obj_.OnOK()
  120. pInfo = self.pInfo
  121. # user values
  122. flags = pInfo.GetFlags()
  123. self['toFile'] = (flags&win32ui.PD_PRINTTOFILE != 0)
  124. self['direct'] = pInfo.GetDirect()
  125. self['preview'] = pInfo.GetPreview()
  126. self['continuePrinting'] = pInfo.GetContinuePrinting()
  127. self['curPage'] = pInfo.GetCurPage()
  128. self['numPreviewPages'] = pInfo.GetNumPreviewPages()
  129. self['userData'] = pInfo.GetUserData()
  130. self['draw'] = pInfo.GetDraw()
  131. self['pageDesc'] = pInfo.GetPageDesc()
  132. self['minPage'] = pInfo.GetMinPage()
  133. self['maxPage'] = pInfo.GetMaxPage()
  134. self['offsetPage'] = pInfo.GetOffsetPage()
  135. self['fromPage'] = pInfo.GetFromPage()
  136. self['toPage'] = pInfo.GetToPage()
  137. self['copies'] = pInfo.GetCopies()
  138. self['deviceName'] = pInfo.GetDeviceName()
  139. self['driverName'] = pInfo.GetDriverName()
  140. self['printAll'] = pInfo.PrintAll()
  141. self['printCollate'] = pInfo.PrintCollate()
  142. self['printRange'] = pInfo.PrintRange()
  143. self['printSelection'] = pInfo.PrintSelection()
  144. del self.pInfo
  145. class PropertyPage(Dialog):
  146. " Base class for a Property Page"
  147. def __init__( self, id, dllid=None, caption=0 ):
  148. """ id is the resource ID
  149. dllid may be None, a dll object, or a string with a dll name """
  150. self.dll = dllFromDll(dllid)
  151. if self.dll:
  152. oldRes = win32ui.SetResource(self.dll)
  153. if type(id)==type([]):
  154. dlg=win32ui.CreatePropertyPageIndirect(id)
  155. else:
  156. dlg=win32ui.CreatePropertyPage(id, caption)
  157. if self.dll:
  158. win32ui.SetResource(oldRes)
  159. # dont call dialog init!
  160. window.Wnd.__init__(self, dlg)
  161. self.HookCommands()
  162. class PropertySheet(window.Wnd):
  163. def __init__(self, caption, dll=None, pageList=None ):# parent=None, style,etc):
  164. " Initialize a property sheet. pageList is a list of ID's "
  165. # must take a reference to the DLL until InitDialog.
  166. self.dll=dllFromDll(dll)
  167. self.sheet = win32ui.CreatePropertySheet(caption)
  168. window.Wnd.__init__(self, self.sheet)
  169. if not pageList is None:
  170. self.AddPage(pageList)
  171. def OnInitDialog(self):
  172. return self._obj_.OnInitDialog()
  173. def DoModal(self):
  174. if self.dll:
  175. oldRes = win32ui.SetResource(self.dll)
  176. rc = self.sheet.DoModal()
  177. if self.dll:
  178. win32ui.SetResource(oldRes)
  179. return rc
  180. def AddPage(self, pages):
  181. if self.dll:
  182. oldRes = win32ui.SetResource(self.dll)
  183. try: # try list style access
  184. pages[0]
  185. isSeq = 1
  186. except (TypeError,KeyError):
  187. isSeq = 0
  188. if isSeq:
  189. for page in pages:
  190. self.DoAddSinglePage(page)
  191. else:
  192. self.DoAddSinglePage(pages)
  193. if self.dll:
  194. win32ui.SetResource(oldRes)
  195. def DoAddSinglePage(self, page):
  196. "Page may be page, or int ID. Assumes DLL setup "
  197. if type(page)==type(0):
  198. self.sheet.AddPage(win32ui.CreatePropertyPage(page))
  199. else:
  200. self.sheet.AddPage(page)
  201. # define some app utility functions.
  202. def GetSimpleInput(prompt, defValue='', title=None ):
  203. """ displays a dialog, and returns a string, or None if cancelled.
  204. args prompt, defValue='', title=main frames title """
  205. # uses a simple dialog to return a string object.
  206. if title is None: title=win32ui.GetMainFrame().GetWindowText()
  207. # 2to3 insists on converting 'Dialog.__init__' to 'tkinter.dialog...'
  208. DlgBaseClass = Dialog
  209. class DlgSimpleInput(DlgBaseClass):
  210. def __init__(self, prompt, defValue, title ):
  211. self.title=title
  212. DlgBaseClass.__init__(self, win32ui.IDD_SIMPLE_INPUT)
  213. self.AddDDX(win32ui.IDC_EDIT1,'result')
  214. self.AddDDX(win32ui.IDC_PROMPT1, 'prompt')
  215. self._obj_.data['result']=defValue
  216. self._obj_.data['prompt']=prompt
  217. def OnInitDialog(self):
  218. self.SetWindowText(self.title)
  219. return DlgBaseClass.OnInitDialog(self)
  220. dlg=DlgSimpleInput( prompt, defValue, title)
  221. if dlg.DoModal() != win32con.IDOK:
  222. return None
  223. return dlg['result']