configui.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. from pywin.mfc import dialog
  2. import win32api
  3. import win32con
  4. import win32ui
  5. import copy
  6. import string
  7. from . import scintillacon
  8. # Used to indicate that style should use default color
  9. from win32con import CLR_INVALID
  10. ######################################################
  11. # Property Page for syntax formatting options
  12. # The standard 16 color VGA palette should always be possible
  13. paletteVGA = (
  14. ("Black", win32api.RGB(0,0,0)),
  15. ("Navy", win32api.RGB(0,0,128)),
  16. ("Green", win32api.RGB(0,128,0)),
  17. ("Cyan", win32api.RGB(0,128,128)),
  18. ("Maroon", win32api.RGB(128,0,0)),
  19. ("Purple", win32api.RGB(128,0,128)),
  20. ("Olive", win32api.RGB(128,128,0)),
  21. ("Gray", win32api.RGB(128,128,128)),
  22. ("Silver", win32api.RGB(192,192,192)),
  23. ("Blue", win32api.RGB(0,0,255)),
  24. ("Lime", win32api.RGB(0,255,0)),
  25. ("Aqua", win32api.RGB(0,255,255)),
  26. ("Red", win32api.RGB(255,0,0)),
  27. ("Fuchsia", win32api.RGB(255,0,255)),
  28. ("Yellow", win32api.RGB(255,255,0)),
  29. ("White", win32api.RGB(255,255,255)),
  30. # and a few others will generally be possible.
  31. ("DarkGrey", win32api.RGB(64,64,64)),
  32. ("PurpleBlue", win32api.RGB(64,64,192)),
  33. ("DarkGreen", win32api.RGB(0,96,0)),
  34. ("DarkOlive", win32api.RGB(128,128,64)),
  35. ("MediumBlue", win32api.RGB(0,0,192)),
  36. ("DarkNavy", win32api.RGB(0,0,96)),
  37. ("Magenta", win32api.RGB(96,0,96)),
  38. ("OffWhite", win32api.RGB(255,255,220)),
  39. ("LightPurple", win32api.RGB(220,220,255)),
  40. ("<Default>", win32con.CLR_INVALID)
  41. )
  42. class ScintillaFormatPropertyPage(dialog.PropertyPage):
  43. def __init__(self, scintillaClass = None, caption = 0):
  44. self.scintillaClass = scintillaClass
  45. dialog.PropertyPage.__init__(self, win32ui.IDD_PP_FORMAT, caption=caption)
  46. def OnInitDialog(self):
  47. try:
  48. if self.scintillaClass is None:
  49. from . import control
  50. sc = control.CScintillaEdit
  51. else:
  52. sc = self.scintillaClass
  53. self.scintilla = sc()
  54. style = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.ES_MULTILINE
  55. # Convert the rect size
  56. rect = self.MapDialogRect( (5, 5, 120, 75))
  57. self.scintilla.CreateWindow(style, rect, self, 111)
  58. self.HookNotify(self.OnBraceMatch, scintillacon.SCN_CHECKBRACE)
  59. self.scintilla.HookKeyStroke(self.OnEsc, 27)
  60. self.scintilla.SCISetViewWS(1)
  61. self.pos_bstart = self.pos_bend = self.pos_bbad = 0
  62. colorizer = self.scintilla._GetColorizer()
  63. text = colorizer.GetSampleText()
  64. items = text.split('|', 2)
  65. pos = len(items[0])
  66. self.scintilla.SCIAddText(''.join(items))
  67. self.scintilla.SetSel(pos, pos)
  68. self.scintilla.ApplyFormattingStyles()
  69. self.styles = self.scintilla._GetColorizer().styles
  70. self.cbo = self.GetDlgItem(win32ui.IDC_COMBO1)
  71. for c in paletteVGA:
  72. self.cbo.AddString(c[0])
  73. self.cboBoldItalic = self.GetDlgItem(win32ui.IDC_COMBO2)
  74. for item in ["Bold Italic", "Bold", "Italic", "Regular"]:
  75. self.cboBoldItalic.InsertString(0, item)
  76. self.butIsDefault = self.GetDlgItem(win32ui.IDC_CHECK1)
  77. self.butIsDefaultBackground = self.GetDlgItem(win32ui.IDC_CHECK2)
  78. self.listbox = self.GetDlgItem(win32ui.IDC_LIST1)
  79. self.HookCommand(self.OnListCommand, win32ui.IDC_LIST1)
  80. names = list(self.styles.keys())
  81. names.sort()
  82. for name in names:
  83. if self.styles[name].aliased is None:
  84. self.listbox.AddString(name)
  85. self.listbox.SetCurSel(0)
  86. idc = win32ui.IDC_RADIO1
  87. if not self.scintilla._GetColorizer().bUseFixed: idc = win32ui.IDC_RADIO2
  88. self.GetDlgItem(idc).SetCheck(1)
  89. self.UpdateUIForStyle(self.styles[names[0]])
  90. self.scintilla.HookFormatter(self)
  91. self.HookCommand(self.OnButDefaultFixedFont, win32ui.IDC_BUTTON1)
  92. self.HookCommand(self.OnButDefaultPropFont, win32ui.IDC_BUTTON2)
  93. self.HookCommand(self.OnButThisFont, win32ui.IDC_BUTTON3)
  94. self.HookCommand(self.OnButUseDefaultFont, win32ui.IDC_CHECK1)
  95. self.HookCommand(self.OnButThisBackground, win32ui.IDC_BUTTON4)
  96. self.HookCommand(self.OnButUseDefaultBackground, win32ui.IDC_CHECK2)
  97. self.HookCommand(self.OnStyleUIChanged, win32ui.IDC_COMBO1)
  98. self.HookCommand(self.OnStyleUIChanged, win32ui.IDC_COMBO2)
  99. self.HookCommand(self.OnButFixedOrDefault, win32ui.IDC_RADIO1)
  100. self.HookCommand(self.OnButFixedOrDefault, win32ui.IDC_RADIO2)
  101. except:
  102. import traceback
  103. traceback.print_exc()
  104. def OnEsc(self, ch):
  105. self.GetParent().EndDialog(win32con.IDCANCEL)
  106. def OnBraceMatch(self, std, extra):
  107. import pywin.scintilla.view
  108. pywin.scintilla.view.DoBraceMatch(self.scintilla)
  109. def GetSelectedStyle(self):
  110. return self.styles[self.listbox.GetText(self.listbox.GetCurSel())]
  111. def _DoButDefaultFont(self, extra_flags, attr):
  112. baseFormat = getattr(self.scintilla._GetColorizer(), attr)
  113. flags = extra_flags | win32con.CF_SCREENFONTS | win32con.CF_EFFECTS | win32con.CF_FORCEFONTEXIST
  114. d=win32ui.CreateFontDialog(baseFormat, flags, None, self)
  115. if d.DoModal()==win32con.IDOK:
  116. setattr(self.scintilla._GetColorizer(), attr, d.GetCharFormat())
  117. self.OnStyleUIChanged(0, win32con.BN_CLICKED)
  118. def OnButDefaultFixedFont(self, id, code):
  119. if code==win32con.BN_CLICKED:
  120. self._DoButDefaultFont(win32con.CF_FIXEDPITCHONLY, "baseFormatFixed")
  121. return 1
  122. def OnButDefaultPropFont(self, id, code):
  123. if code==win32con.BN_CLICKED:
  124. self._DoButDefaultFont(win32con.CF_SCALABLEONLY, "baseFormatProp")
  125. return 1
  126. def OnButFixedOrDefault(self, id, code):
  127. if code==win32con.BN_CLICKED:
  128. bUseFixed = id == win32ui.IDC_RADIO1
  129. self.GetDlgItem(win32ui.IDC_RADIO1).GetCheck() != 0
  130. self.scintilla._GetColorizer().bUseFixed = bUseFixed
  131. self.scintilla.ApplyFormattingStyles(0)
  132. return 1
  133. def OnButThisFont(self, id, code):
  134. if code==win32con.BN_CLICKED:
  135. flags = win32con.CF_SCREENFONTS | win32con.CF_EFFECTS | win32con.CF_FORCEFONTEXIST
  136. style = self.GetSelectedStyle()
  137. # If the selected style is based on the default, we need to apply
  138. # the default to it.
  139. def_format = self.scintilla._GetColorizer().GetDefaultFormat()
  140. format = style.GetCompleteFormat(def_format)
  141. d=win32ui.CreateFontDialog(format, flags, None, self)
  142. if d.DoModal()==win32con.IDOK:
  143. style.format = d.GetCharFormat()
  144. self.scintilla.ApplyFormattingStyles(0)
  145. return 1
  146. def OnButUseDefaultFont(self, id, code):
  147. if code == win32con.BN_CLICKED:
  148. isDef = self.butIsDefault.GetCheck()
  149. self.GetDlgItem(win32ui.IDC_BUTTON3).EnableWindow(not isDef)
  150. if isDef: # Being reset to the default font.
  151. style = self.GetSelectedStyle()
  152. style.ForceAgainstDefault()
  153. self.UpdateUIForStyle(style)
  154. self.scintilla.ApplyFormattingStyles(0)
  155. else:
  156. # User wants to override default -
  157. # do nothing!
  158. pass
  159. def OnButThisBackground(self, id, code):
  160. if code==win32con.BN_CLICKED:
  161. style = self.GetSelectedStyle()
  162. bg = win32api.RGB(0xff, 0xff, 0xff)
  163. if style.background != CLR_INVALID:
  164. bg = style.background
  165. d=win32ui.CreateColorDialog(bg, 0, self)
  166. if d.DoModal()==win32con.IDOK:
  167. style.background = d.GetColor()
  168. self.scintilla.ApplyFormattingStyles(0)
  169. return 1
  170. def OnButUseDefaultBackground(self, id, code):
  171. if code == win32con.BN_CLICKED:
  172. isDef = self.butIsDefaultBackground.GetCheck()
  173. self.GetDlgItem(win32ui.IDC_BUTTON4).EnableWindow(not isDef)
  174. if isDef: # Being reset to the default color
  175. style = self.GetSelectedStyle()
  176. style.background = style.default_background
  177. self.UpdateUIForStyle(style)
  178. self.scintilla.ApplyFormattingStyles(0)
  179. else:
  180. # User wants to override default -
  181. # do nothing!
  182. pass
  183. def OnListCommand(self, id, code):
  184. if code==win32con.LBN_SELCHANGE:
  185. style = self.GetSelectedStyle()
  186. self.UpdateUIForStyle(style)
  187. return 1
  188. def UpdateUIForStyle(self, style ):
  189. format = style.format
  190. sel = 0
  191. for c in paletteVGA:
  192. if format[4] == c[1]:
  193. # print "Style", style.name, "is", c[0]
  194. break
  195. sel = sel + 1
  196. else:
  197. sel = -1
  198. self.cbo.SetCurSel(sel)
  199. self.butIsDefault.SetCheck(style.IsBasedOnDefault())
  200. self.GetDlgItem(win32ui.IDC_BUTTON3).EnableWindow(not style.IsBasedOnDefault())
  201. self.butIsDefaultBackground.SetCheck(style.background == style.default_background)
  202. self.GetDlgItem(win32ui.IDC_BUTTON4).EnableWindow(style.background != style.default_background)
  203. bold = format[1] & win32con.CFE_BOLD != 0; italic = format[1] & win32con.CFE_ITALIC != 0
  204. self.cboBoldItalic.SetCurSel( bold*2 + italic )
  205. def OnStyleUIChanged(self, id, code):
  206. if code in [win32con.BN_CLICKED, win32con.CBN_SELCHANGE]:
  207. style = self.GetSelectedStyle()
  208. self.ApplyUIFormatToStyle(style)
  209. self.scintilla.ApplyFormattingStyles(0)
  210. return 0
  211. return 1
  212. def ApplyUIFormatToStyle(self, style):
  213. format = style.format
  214. color = paletteVGA[self.cbo.GetCurSel()]
  215. effect = 0
  216. sel = self.cboBoldItalic.GetCurSel()
  217. if sel==0:
  218. effect = 0
  219. elif sel==1:
  220. effect = win32con.CFE_ITALIC
  221. elif sel==2:
  222. effect = win32con.CFE_BOLD
  223. else:
  224. effect = win32con.CFE_BOLD | win32con.CFE_ITALIC
  225. maskFlags=format[0]|win32con.CFM_COLOR|win32con.CFM_BOLD|win32con.CFM_ITALIC
  226. style.format = (maskFlags, effect, style.format[2], style.format[3], color[1]) + style.format[5:]
  227. def OnOK(self):
  228. self.scintilla._GetColorizer().SavePreferences()
  229. return 1
  230. def test():
  231. page = ColorEditorPropertyPage()
  232. sheet = pywin.mfc.dialog.PropertySheet("Test")
  233. sheet.AddPage(page)
  234. sheet.CreateWindow()