configui.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. from pywin.mfc import dialog
  2. import document
  3. import win32ui
  4. import win32con
  5. import win32api
  6. from pywin.framework.editor import GetEditorOption, SetEditorOption, DeleteEditorOption, GetEditorFontOption, SetEditorFontOption, defaultCharacterFormat, editorTemplate
  7. import pywin.scintilla.config
  8. # The standard 16 color VGA palette should always be possible
  9. paletteVGA = ( ("Black",0,0,0), ("Navy",0,0,128), ("Green",0,128,0), ("Cyan",0,128,128),
  10. ("Maroon",128,0,0), ("Purple",128,0,128), ("Olive",128,128,0), ("Gray",128,128,128),
  11. ("Silver",192,192,192), ("Blue",0,0,255), ("Lime",0,255,0), ("Aqua",0,255,255),
  12. ("Red",255,0,0), ("Fuchsia",255,0,255), ("Yellow",255,255,0), ("White",255,255,255) )
  13. ######################################################
  14. #
  15. # Property Page for editor options
  16. #
  17. class EditorPropertyPage(dialog.PropertyPage):
  18. def __init__(self):
  19. dialog.PropertyPage.__init__(self, win32ui.IDD_PP_EDITOR)
  20. self.autooptions = []
  21. self._AddEditorOption(win32ui.IDC_AUTO_RELOAD, "i", "Auto Reload", 1)
  22. self._AddEditorOption(win32ui.IDC_COMBO1, "i", "Backup Type", document.BAK_DOT_BAK_BAK_DIR)
  23. self._AddEditorOption(win32ui.IDC_AUTOCOMPLETE, "i", "Autocomplete Attributes", 1)
  24. self._AddEditorOption(win32ui.IDC_CALLTIPS, "i", "Show Call Tips", 1)
  25. self._AddEditorOption(win32ui.IDC_MARGIN_LINENUMBER, "i", "Line Number Margin Width", 0)
  26. self._AddEditorOption(win32ui.IDC_RADIO1, "i", "MarkersInMargin", None)
  27. self._AddEditorOption(win32ui.IDC_MARGIN_MARKER, "i", "Marker Margin Width", None)
  28. self["Marker Margin Width"] = GetEditorOption("Marker Margin Width", 16)
  29. # Folding
  30. self._AddEditorOption(win32ui.IDC_MARGIN_FOLD, "i", "Fold Margin Width", 12)
  31. self._AddEditorOption(win32ui.IDC_FOLD_ENABLE, "i", "Enable Folding", 1)
  32. self._AddEditorOption(win32ui.IDC_FOLD_ON_OPEN, "i", "Fold On Open", 0)
  33. self._AddEditorOption(win32ui.IDC_FOLD_SHOW_LINES, "i", "Fold Lines", 1)
  34. # Right edge.
  35. self._AddEditorOption(win32ui.IDC_RIGHTEDGE_ENABLE, "i", "Right Edge Enabled", 0)
  36. self._AddEditorOption(win32ui.IDC_RIGHTEDGE_COLUMN, "i", "Right Edge Column", 75)
  37. # Source control, etc
  38. self.AddDDX(win32ui.IDC_VSS_INTEGRATE, "bVSS")
  39. self.AddDDX(win32ui.IDC_KEYBOARD_CONFIG, "Configs", "l")
  40. self["Configs"] = pywin.scintilla.config.find_config_files()
  41. def _AddEditorOption(self, idd, typ, optionName, defaultVal):
  42. self.AddDDX(idd, optionName, typ)
  43. # some options are "derived" - ie, can be implied from others
  44. # (eg, "view markers in background" is implied from "markerMarginWidth==0"
  45. # So we don't actually store these values, but they do still get DDX support.
  46. if defaultVal is not None:
  47. self[optionName] = GetEditorOption(optionName, defaultVal)
  48. self.autooptions.append((optionName, defaultVal))
  49. def OnInitDialog(self):
  50. for name, val in self.autooptions:
  51. self[name] = GetEditorOption(name, val)
  52. # Note that these MUST be in the same order as the BAK constants.
  53. cbo = self.GetDlgItem(win32ui.IDC_COMBO1)
  54. cbo.AddString("None")
  55. cbo.AddString(".BAK File")
  56. cbo.AddString("TEMP dir")
  57. cbo.AddString("Own dir")
  58. # Source Safe
  59. bVSS = GetEditorOption("Source Control Module", "") == "pywin.framework.editor.vss"
  60. self['bVSS'] = bVSS
  61. edit = self.GetDlgItem(win32ui.IDC_RIGHTEDGE_SAMPLE)
  62. edit.SetWindowText("Sample Color")
  63. rc = dialog.PropertyPage.OnInitDialog(self)
  64. try:
  65. self.GetDlgItem(win32ui.IDC_KEYBOARD_CONFIG).SelectString(-1, GetEditorOption("Keyboard Config", "default"))
  66. except win32ui.error:
  67. import traceback
  68. traceback.print_exc()
  69. pass
  70. self.HookCommand(self.OnButSimple, win32ui.IDC_FOLD_ENABLE)
  71. self.HookCommand(self.OnButSimple, win32ui.IDC_RADIO1)
  72. self.HookCommand(self.OnButSimple, win32ui.IDC_RADIO2)
  73. self.HookCommand(self.OnButSimple, win32ui.IDC_RIGHTEDGE_ENABLE)
  74. self.HookCommand(self.OnButEdgeColor, win32ui.IDC_RIGHTEDGE_DEFINE)
  75. butMarginEnabled = self['Marker Margin Width'] > 0
  76. self.GetDlgItem(win32ui.IDC_RADIO1).SetCheck(butMarginEnabled)
  77. self.GetDlgItem(win32ui.IDC_RADIO2).SetCheck(not butMarginEnabled)
  78. self.edgeColor = self.initialEdgeColor = GetEditorOption("Right Edge Color", win32api.RGB(0xef, 0xef, 0xef))
  79. for spinner_id in (win32ui.IDC_SPIN1, win32ui.IDC_SPIN2, win32ui.IDC_SPIN3):
  80. spinner=self.GetDlgItem(spinner_id)
  81. spinner.SetRange(0,100)
  82. self.UpdateUIForState()
  83. return rc
  84. def OnButSimple(self, id, code):
  85. if code == win32con.BN_CLICKED:
  86. self.UpdateUIForState()
  87. def OnButEdgeColor(self, id, code):
  88. if code == win32con.BN_CLICKED:
  89. d = win32ui.CreateColorDialog(self.edgeColor, 0, self)
  90. # Ensure the current color is a custom color (as it may not be in the swatch)
  91. # plus some other nice gray scales.
  92. ccs = [self.edgeColor]
  93. for c in range(0xef, 0x4f, -0x10):
  94. ccs.append(win32api.RGB(c,c,c))
  95. d.SetCustomColors( ccs )
  96. if d.DoModal() == win32con.IDOK:
  97. self.edgeColor = d.GetColor()
  98. self.UpdateUIForState()
  99. def UpdateUIForState(self):
  100. folding = self.GetDlgItem(win32ui.IDC_FOLD_ENABLE).GetCheck()
  101. self.GetDlgItem(win32ui.IDC_FOLD_ON_OPEN).EnableWindow(folding)
  102. self.GetDlgItem(win32ui.IDC_FOLD_SHOW_LINES).EnableWindow(folding)
  103. widthEnabled = self.GetDlgItem(win32ui.IDC_RADIO1).GetCheck()
  104. self.GetDlgItem(win32ui.IDC_MARGIN_MARKER).EnableWindow(widthEnabled)
  105. self.UpdateData() # Ensure self[] is up to date with the control data.
  106. if widthEnabled and self["Marker Margin Width"] == 0:
  107. self["Marker Margin Width"] = 16
  108. self.UpdateData(0) # Ensure control up to date with self[]
  109. # Right edge
  110. edgeEnabled = self.GetDlgItem(win32ui.IDC_RIGHTEDGE_ENABLE).GetCheck()
  111. self.GetDlgItem(win32ui.IDC_RIGHTEDGE_COLUMN).EnableWindow(edgeEnabled)
  112. self.GetDlgItem(win32ui.IDC_RIGHTEDGE_SAMPLE).EnableWindow(edgeEnabled)
  113. self.GetDlgItem(win32ui.IDC_RIGHTEDGE_DEFINE).EnableWindow(edgeEnabled)
  114. edit = self.GetDlgItem(win32ui.IDC_RIGHTEDGE_SAMPLE)
  115. edit.SetBackgroundColor(0, self.edgeColor)
  116. def OnOK(self):
  117. for name, defVal in self.autooptions:
  118. SetEditorOption(name, self[name])
  119. # Margin width gets handled differently.
  120. if self['MarkersInMargin'] == 0:
  121. SetEditorOption("Marker Margin Width", self["Marker Margin Width"])
  122. else:
  123. SetEditorOption("Marker Margin Width", 0)
  124. if self.edgeColor != self.initialEdgeColor:
  125. SetEditorOption("Right Edge Color", self.edgeColor)
  126. if self['bVSS']:
  127. SetEditorOption("Source Control Module", "pywin.framework.editor.vss")
  128. else:
  129. if GetEditorOption("Source Control Module", "")=='pywin.framework.editor.vss':
  130. SetEditorOption("Source Control Module", "")
  131. # Keyboard config
  132. configname = self.GetDlgItem(win32ui.IDC_KEYBOARD_CONFIG).GetWindowText()
  133. if configname:
  134. if configname == "default":
  135. DeleteEditorOption("Keyboard Config")
  136. else:
  137. SetEditorOption("Keyboard Config", configname)
  138. import pywin.scintilla.view
  139. pywin.scintilla.view.LoadConfiguration()
  140. # Now tell all views we have changed.
  141. ## for doc in editorTemplate.GetDocumentList():
  142. ## for view in doc.GetAllViews():
  143. ## try:
  144. ## fn = view.OnConfigChange
  145. ## except AttributeError:
  146. ## continue
  147. ## fn()
  148. return 1
  149. class EditorWhitespacePropertyPage(dialog.PropertyPage):
  150. def __init__(self):
  151. dialog.PropertyPage.__init__(self, win32ui.IDD_PP_TABS)
  152. self.autooptions = []
  153. self._AddEditorOption(win32ui.IDC_TAB_SIZE, "i", "Tab Size", 4)
  154. self._AddEditorOption(win32ui.IDC_INDENT_SIZE, "i", "Indent Size", 4)
  155. self._AddEditorOption(win32ui.IDC_USE_SMART_TABS, "i", "Smart Tabs", 1)
  156. self._AddEditorOption(win32ui.IDC_VIEW_WHITESPACE, "i", "View Whitespace", 0)
  157. self._AddEditorOption(win32ui.IDC_VIEW_EOL, "i", "View EOL", 0)
  158. self._AddEditorOption(win32ui.IDC_VIEW_INDENTATIONGUIDES, "i", "View Indentation Guides", 0)
  159. def _AddEditorOption(self, idd, typ, optionName, defaultVal):
  160. self.AddDDX(idd, optionName, typ)
  161. self[optionName] = GetEditorOption(optionName, defaultVal)
  162. self.autooptions.append((optionName, defaultVal))
  163. def OnInitDialog(self):
  164. for name, val in self.autooptions:
  165. self[name] = GetEditorOption(name, val)
  166. rc = dialog.PropertyPage.OnInitDialog(self)
  167. idc = win32ui.IDC_TABTIMMY_NONE
  168. if GetEditorOption("Use Tab Timmy", 1):
  169. idc = win32ui.IDC_TABTIMMY_IND
  170. self.GetDlgItem(idc).SetCheck(1)
  171. idc = win32ui.IDC_RADIO1
  172. if GetEditorOption("Use Tabs", 0):
  173. idc = win32ui.IDC_USE_TABS
  174. self.GetDlgItem(idc).SetCheck(1)
  175. tt_color = GetEditorOption("Tab Timmy Color", win32api.RGB(0xff, 0, 0))
  176. self.cbo = self.GetDlgItem(win32ui.IDC_COMBO1)
  177. for c in paletteVGA:
  178. self.cbo.AddString(c[0])
  179. sel = 0
  180. for c in paletteVGA:
  181. if tt_color == win32api.RGB(c[1], c[2], c[3]):
  182. break
  183. sel = sel + 1
  184. else:
  185. sel = -1
  186. self.cbo.SetCurSel(sel)
  187. self.HookCommand(self.OnButSimple, win32ui.IDC_TABTIMMY_NONE)
  188. self.HookCommand(self.OnButSimple, win32ui.IDC_TABTIMMY_IND)
  189. self.HookCommand(self.OnButSimple, win32ui.IDC_TABTIMMY_BG)
  190. # Set ranges for the spinners.
  191. for spinner_id in [win32ui.IDC_SPIN1, win32ui.IDC_SPIN2]:
  192. spinner = self.GetDlgItem(spinner_id)
  193. spinner.SetRange(1, 16)
  194. return rc
  195. def OnButSimple(self, id, code):
  196. if code == win32con.BN_CLICKED:
  197. self.UpdateUIForState()
  198. def UpdateUIForState(self):
  199. timmy = self.GetDlgItem(win32ui.IDC_TABTIMMY_NONE).GetCheck()
  200. self.GetDlgItem(win32ui.IDC_COMBO1).EnableWindow(not timmy)
  201. def OnOK(self):
  202. for name, defVal in self.autooptions:
  203. SetEditorOption(name, self[name])
  204. SetEditorOption("Use Tabs", self.GetDlgItem(win32ui.IDC_USE_TABS).GetCheck())
  205. SetEditorOption("Use Tab Timmy", self.GetDlgItem(win32ui.IDC_TABTIMMY_IND).GetCheck())
  206. c = paletteVGA[self.cbo.GetCurSel()]
  207. SetEditorOption("Tab Timmy Color", win32api.RGB(c[1], c[2], c[3]))
  208. return 1
  209. def testpp():
  210. ps = dialog.PropertySheet("Editor Options")
  211. ps.AddPage(EditorWhitespacePropertyPage())
  212. ps.DoModal()
  213. if __name__=='__main__':
  214. testpp()