/lib/pwiki/WikiTxtCtrl.py
Python | 7961 lines | 7593 code | 196 blank | 172 comment | 14 complexity | f4e308862a3cff5d0fbdfcda1e526217 MD5 | raw file
Possible License(s): LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- from __future__ import with_statement
- ## import hotshot
- ## _prof = hotshot.Profile("hotshot.prf")
-
- import pdb
-
- import traceback, codecs
- from cStringIO import StringIO
- import string, itertools, contextlib
- import re # import pwiki.srePersistent as re
- import threading
-
- import subprocess
- import textwrap
-
- from os.path import exists, dirname, isfile, isdir, join, basename
- from os import rename, unlink, listdir
-
- from time import time, sleep
-
- import wx, wx.stc
-
- from Consts import FormatTypes
-
- from .Utilities import DUMBTHREADSTOP, callInMainThread, ThreadHolder, \
- calcResizeArIntoBoundingBox, DictFromFields
-
- from .wxHelper import GUI_ID, getTextFromClipboard, copyTextToClipboard, \
- wxKeyFunctionSink, getAccelPairFromKeyDown, appendToMenuByMenuDesc
- from . import wxHelper
-
- from . import OsAbstract
-
- from .WikiExceptions import *
-
- from .SystemInfo import isUnicode, isOSX, isLinux, isWindows
-
- from .ParseUtilities import getFootnoteAnchorDict
-
- from .EnhancedScintillaControl import StyleCollector
-
- from .SearchableScintillaControl import SearchableScintillaControl
-
-
-
- from . import Configuration
- from . import AdditionalDialogs
- from . import WikiTxtDialogs
-
- # image stuff
- import imghdr
-
-
- # import WikiFormatting
- from . import DocPages
- from . import UserActionCoord, WindowLayout
-
- from .SearchAndReplace import SearchReplaceOperation
- from . import StringOps
- from . import SpellChecker
-
- # from StringOps import * # TODO Remove this
- # mbcsDec, uniToGui, guiToUni, \
- # wikiWordToLabel, revStr, lineendToInternal, lineendToOs
-
- # NOTE: TEMPORY
- import inspect
-
-
- from ViHelper import ViHintDialog, ViHelper
- from collections import defaultdict
-
- try:
- import WindowsHacks
- except:
- if isWindows():
- traceback.print_exc()
- WindowsHacks = None
-
-
- # Python compiler flag for float division
- CO_FUTURE_DIVISION = 0x2000
-
-
-
-
- class WikiTxtCtrl(SearchableScintillaControl):
- NUMBER_MARGIN = 0
- FOLD_MARGIN = 2
- SELECT_MARGIN = 1
-
- # Not the best of all possible solutions
- SUGGESTION_CMD_IDS = [GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_0,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_1,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_2,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_3,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_4,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_5,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_6,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_7,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_8,
- GUI_ID.CMD_REPLACE_THIS_SPELLING_WITH_SUGGESTION_9]
-
- def __init__(self, presenter, parent, ID):
- SearchableScintillaControl.__init__(self, presenter,
- presenter.getMainControl(), parent, ID)
- self.evalScope = None
- self.stylingThreadHolder = ThreadHolder()
- self.calltipThreadHolder = ThreadHolder()
- self.contextMenuThreadHolder = ThreadHolder()
- self.clearStylingCache()
- self.pageType = "normal" # The pagetype controls some special editor behaviour
- # self.idleCounter = 0 # Used to reduce idle load
- # self.loadedDocPage = None
- self.lastFont = None
- self.ignoreOnChange = False
- self.dwellLockCounter = 0 # Don't process dwell start messages if >0
- self.wikiLanguageHelper = None
- self.templateIdRecycler = wxHelper.IdRecycler()
- self.vi = None # Contains ViHandler instance if vi key handling enabled
-
- # If autocompletion word was choosen, how many bytes to delete backward
- # before inserting word
- self.autoCompBackBytesMap = {} # Maps selected word to number of backbytes
-
- # Inline image
- self.tooltip_image = None
-
- # configurable editor settings
- config = self.presenter.getConfig()
-
- # TODO: set wrap indent mode (for wx >= 2.9)
- self.setWrapMode(config.getboolean("main", "wrap_mode"))
- self.SetIndentationGuides(config.getboolean("main", "indentation_guides"))
- self.autoIndent = config.getboolean("main", "auto_indent")
- self.autoBullets = config.getboolean("main", "auto_bullets")
- self.setShowLineNumbers(config.getboolean("main", "show_lineNumbers"))
- self.foldingActive = config.getboolean("main", "editor_useFolding")
- self.tabsToSpaces = config.getboolean("main", "editor_tabsToSpaces")
-
- # editor settings
- self.applyBasicSciSettings()
-
- self.defaultFont = config.get("main", "font",
- self.presenter.getDefaultFontFaces()["mono"])
-
- self.CallTipSetForeground(wx.Colour(0, 0, 0))
-
- shorthintDelay = self.presenter.getConfig().getint("main",
- "editor_shortHint_delay", 500)
- self.SetMouseDwellTime(shorthintDelay)
-
- # Popup menu must be created by Python code to replace clipboard functions
- # for unicode build on Win 98/ME
- self.UsePopUp(0)
-
- self.SetMarginMask(self.FOLD_MARGIN, wx.stc.STC_MASK_FOLDERS)
- self.SetMarginMask(self.NUMBER_MARGIN, 0)
- self.SetMarginMask(self.SELECT_MARGIN, 0)
-
- if self.foldingActive:
- self.SetMarginWidth(self.FOLD_MARGIN, 16)
- else:
- self.SetMarginWidth(self.FOLD_MARGIN, 0)
- self.SetMarginWidth(self.SELECT_MARGIN, 16)
- self.SetMarginWidth(self.NUMBER_MARGIN, 0)
-
- self.SetMarginType(self.FOLD_MARGIN, wx.stc.STC_MARGIN_SYMBOL)
- self.SetMarginType(self.SELECT_MARGIN, wx.stc.STC_MARGIN_SYMBOL)
- self.SetMarginType(self.NUMBER_MARGIN, wx.stc.STC_MARGIN_NUMBER)
-
- # Optical details
- self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER, wx.stc.STC_MARK_PLUS)
- self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN, wx.stc.STC_MARK_MINUS)
- self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND, wx.stc.STC_MARK_EMPTY)
- self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_EMPTY)
- self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_EMPTY)
- self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERSUB, wx.stc.STC_MARK_EMPTY)
- self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERTAIL, wx.stc.STC_MARK_EMPTY)
- self.SetFoldFlags(16)
-
- self.SetMarginSensitive(self.FOLD_MARGIN, True)
- self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" %
- self.presenter.getDefaultFontFaces())
-
- # self.setFoldingActive(self.foldingActive)
-
- for i in xrange(32):
- self.StyleSetEOLFilled(i, True)
-
- # i plan on lexing myself
- self.SetLexer(wx.stc.STC_LEX_CONTAINER)
-
-
- # make the text control a drop target for files and text
- self.SetDropTarget(WikiTxtCtrlDropTarget(self))
-
- # self.CmdKeyClearAll()
- #
- # # register some keyboard commands
- # self.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN)
- # self.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
- # self.CmdKeyAssign(wx.stc.STC_KEY_HOME, 0, wx.stc.STC_CMD_HOMEWRAP)
- # self.CmdKeyAssign(wx.stc.STC_KEY_END, 0, wx.stc.STC_CMD_LINEENDWRAP)
- # self.CmdKeyAssign(wx.stc.STC_KEY_HOME, wx.stc.STC_SCMOD_SHIFT,
- # wx.stc.STC_CMD_HOMEWRAPEXTEND)
- # self.CmdKeyAssign(wx.stc.STC_KEY_END, wx.stc.STC_SCMOD_SHIFT,
- # wx.stc.STC_CMD_LINEENDWRAPEXTEND)
- #
- #
- # # Clear all key mappings for clipboard operations
- # # PersonalWikiFrame handles them and calls the special clipboard functions
- # # instead of the normal ones
- # self.CmdKeyClear(wx.stc.STC_KEY_INSERT, wx.stc.STC_SCMOD_CTRL)
- # self.CmdKeyClear(wx.stc.STC_KEY_INSERT, wx.stc.STC_SCMOD_SHIFT)
- # self.CmdKeyClear(wx.stc.STC_KEY_DELETE, wx.stc.STC_SCMOD_SHIFT)
- #
- # self.CmdKeyClear(ord('X'), wx.stc.STC_SCMOD_CTRL)
- # self.CmdKeyClear(ord('C'), wx.stc.STC_SCMOD_CTRL)
- # self.CmdKeyClear(ord('V'), wx.stc.STC_SCMOD_CTRL)
-
- self.SetModEventMask(
- wx.stc.STC_MOD_INSERTTEXT | wx.stc.STC_MOD_DELETETEXT)
-
- # set the autocomplete separator
- self.AutoCompSetSeparator(1) # ord('~')
- self.AutoCompSetTypeSeparator(2) # ord('?')
-
- # register some event handlers
- self.presenterListener = wxKeyFunctionSink((
- ("saving all pages", self.onSavingAllPages),
- ("closing current wiki", self.onClosingCurrentWiki),
- ("dropping current wiki", self.onDroppingCurrentWiki),
- ("reloaded current doc page", self.onReloadedCurrentPage)
- ), self.presenter.getMiscEvent())
-
- self.__sinkApp = wxKeyFunctionSink((
- ("options changed", self.onOptionsChanged),
- ), wx.GetApp().getMiscEvent(), self)
-
- self.__sinkGlobalConfig = wxKeyFunctionSink((
- ("changed configuration", self.onChangedConfiguration),
- ), wx.GetApp().getGlobalConfig().getMiscEvent(), self)
-
- # if not self.presenter.getMainControl().isMainWindowConstructed():
- # # Install event handler to wait for construction
- # self.__sinkMainFrame = wxKeyFunctionSink((
- # ("constructed main window", self.onConstructedMainWindow),
- # ), self.presenter.getMainControl().getMiscEvent(), self)
- # else:
- # self.onConstructedMainWindow(None)
-
- self.__sinkMainFrame = wxKeyFunctionSink((
- ("idle visible", self.onIdleVisible),
- ), self.presenter.getMainControl().getMiscEvent(), self)
-
-
- # self.presenter.getMiscEvent().addListener(self.presenterListener)
-
-
- self.wikiPageSink = wxKeyFunctionSink((
- ("updated wiki page", self.onWikiPageUpdated), # fired by a WikiPage
- ("modified spell checker session", self.OnStyleNeeded), # ???
- ("changed read only flag", self.onPageChangedReadOnlyFlag)
- ))
-
-
- wx.stc.EVT_STC_STYLENEEDED(self, ID, self.OnStyleNeeded)
- wx.stc.EVT_STC_CHARADDED(self, ID, self.OnCharAdded)
- wx.stc.EVT_STC_MODIFIED(self, ID, self.OnModified)
- wx.stc.EVT_STC_USERLISTSELECTION(self, ID, self.OnUserListSelection)
- wx.stc.EVT_STC_MARGINCLICK(self, ID, self.OnMarginClick)
- wx.stc.EVT_STC_DWELLSTART(self, ID, self.OnDwellStart)
- wx.stc.EVT_STC_DWELLEND(self, ID, self.OnDwellEnd)
-
- # wx.EVT_LEFT_DOWN(self, self.OnClick)
- wx.EVT_MIDDLE_DOWN(self, self.OnMiddleDown)
- wx.EVT_LEFT_DCLICK(self, self.OnDoubleClick)
-
- # if config.getboolean("main", "editor_useImeWorkaround", False):
- # wx.EVT_CHAR(self, self.OnChar_ImeWorkaround)
-
- wx.EVT_SET_FOCUS(self, self.OnSetFocus)
-
- wx.EVT_CONTEXT_MENU(self, self.OnContextMenu)
-
- # self.incSearchCharStartPos = 0
- self.incSearchPreviousHiddenLines = None
- self.incSearchPreviousHiddenStartLine = -1
-
- self.onlineSpellCheckerActive = SpellChecker.isSpellCheckSupported() and \
- self.presenter.getConfig().getboolean(
- "main", "editor_onlineSpellChecker_active", False)
-
- self.optionColorizeSearchFragments = self.presenter.getConfig()\
- .getboolean("main", "editor_colorizeSearchFragments", False)
-
- self.onOptionsChanged(None)
-
- # when was a key pressed last. used to check idle time.
- self.lastKeyPressed = time()
- self.eolMode = self.GetEOLMode()
-
- # Check if modifiers where pressed since last extended logical line move
- # See self.moveSelectedLinesOneUp() for the reason of this
- self.modifiersPressedSinceExtLogLineMove = False
-
- self.contextMenuTokens = None
- self.contextMenuSpellCheckSuggestions = None
-
- # Connect context menu events to functions
- wx.EVT_MENU(self, GUI_ID.CMD_UNDO, lambda evt: self.Undo())
- wx.EVT_MENU(self, GUI_ID.CMD_REDO, lambda evt: self.Redo())
-
- wx.EVT_MENU(self, GUI_ID.CMD_CLIPBOARD_CUT, lambda evt: self.Cut())
- wx.EVT_MENU(self, GUI_ID.CMD_CLIPBOARD_COPY, lambda evt: self.Copy())
- wx.EVT_MENU(self, GUI_ID.CMD_CLIPBOARD_PASTE, lambda evt: self.Paste())
- wx.EVT_MENU(self, GUI_ID.CMD_CLIPBOARD_PASTE_RAW_HTML,
- lambda evt: self.pasteRawHtml())
- wx.EVT_MENU(self, GUI_ID.CMD_SELECT_ALL, lambda evt: self.SelectAll())
-
- wx.EVT_MENU(self, GUI_ID.CMD_TEXT_DELETE, lambda evt: self.ReplaceSelection(""))
- wx.EVT_MENU(self, GUI_ID.CMD_ZOOM_IN,
- lambda evt: self.CmdKeyExecute(wx.stc.STC_CMD_ZOOMIN))
- wx.EVT_MENU(self, GUI_ID.CMD_ZOOM_OUT,
- lambda evt: self.CmdKeyExecute(wx.stc.STC_CMD_ZOOMOUT))
-
-
- for sps in self.SUGGESTION_CMD_IDS:
- wx.EVT_MENU(self, sps, self.OnReplaceThisSpellingWithSuggestion)
-
- wx.EVT_MENU(self, GUI_ID.CMD_ADD_THIS_SPELLING_SESSION,
- self.OnAddThisSpellingToIgnoreSession)
- wx.EVT_MENU(self, GUI_ID.CMD_ADD_THIS_SPELLING_GLOBAL,
- self.OnAddThisSpellingToIgnoreGlobal)
- wx.EVT_MENU(self, GUI_ID.CMD_ADD_THIS_SPELLING_LOCAL,
- self.OnAddThisSpellingToIgnoreLocal)
-
- wx.EVT_MENU(self, GUI_ID.CMD_LOGICAL_LINE_UP,
- self.OnLogicalLineMove)
- wx.EVT_MENU(self, GUI_ID.CMD_LOGICAL_LINE_UP_WITH_INDENT,
- self.OnLogicalLineMove)
- wx.EVT_MENU(self, GUI_ID.CMD_LOGICAL_LINE_DOWN,
- self.OnLogicalLineMove)
- wx.EVT_MENU(self, GUI_ID.CMD_LOGICAL_LINE_DOWN_WITH_INDENT,
- self.OnLogicalLineMove)
-
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_THIS, self.OnActivateThis)
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_THIS,
- self.OnActivateNewTabThis)
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_BACKGROUND_THIS,
- self.OnActivateNewTabBackgroundThis)
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_WINDOW_THIS,
- self.OnActivateNewWindowThis)
-
- # Passing the evt here is not strictly necessary, but it may be
- # used in the future
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_THIS_LEFT,
- lambda evt: self.OnActivateThis(evt, u"left"))
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_THIS_LEFT,
- lambda evt: self.OnActivateNewTabThis(evt, u"left"))
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_BACKGROUND_THIS_LEFT,
- lambda evt: self.OnActivateNewTabBackgroundThis(evt, u"left"))
-
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_THIS_RIGHT,
- lambda evt: self.OnActivateThis(evt, u"right"))
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_THIS_RIGHT,
- lambda evt: self.OnActivateNewTabThis(evt, u"right"))
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_BACKGROUND_THIS_RIGHT,
- lambda evt: self.OnActivateNewTabBackgroundThis(evt, u"right"))
-
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_THIS_ABOVE,
- lambda evt: self.OnActivateThis(evt, u"above"))
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_THIS_ABOVE,
- lambda evt: self.OnActivateNewTabThis(evt, u"above"))
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_BACKGROUND_THIS_ABOVE,
- lambda evt: self.OnActivateNewTabBackgroundThis(evt, u"above"))
-
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_THIS_BELOW,
- lambda evt: self.OnActivateThis(evt, u"below"))
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_THIS_BELOW,
- lambda evt: self.OnActivateNewTabThis(evt, u"below"))
- wx.EVT_MENU(self, GUI_ID.CMD_ACTIVATE_NEW_TAB_BACKGROUND_THIS_BELOW,
- lambda evt: self.OnActivateNewTabBackgroundThis(evt, u"below"))
-
-
- wx.EVT_MENU(self, GUI_ID.CMD_CONVERT_URL_ABSOLUTE_RELATIVE_THIS,
- self.OnConvertUrlAbsoluteRelativeThis)
-
- wx.EVT_MENU(self, GUI_ID.CMD_OPEN_CONTAINING_FOLDER_THIS,
- self.OnOpenContainingFolderThis)
-
- wx.EVT_MENU(self, GUI_ID.CMD_DELETE_FILE,
- self.OnDeleteFile)
-
- wx.EVT_MENU(self, GUI_ID.CMD_RENAME_FILE,
- self.OnRenameFile)
-
- wx.EVT_MENU(self, GUI_ID.CMD_CLIPBOARD_COPY_URL_TO_THIS_ANCHOR,
- self.OnClipboardCopyUrlToThisAnchor)
-
- wx.EVT_MENU(self, GUI_ID.CMD_SELECT_TEMPLATE, self.OnSelectTemplate)
-
- # 2.8 does not support SetEditable - Define a dummy function for now
- if wx.version().startswith("2.8"):
- def SetEditable(self, state):
- pass
-
- # def __getattr__(self, attr):
- # return getattr(self.cnt, attr)
-
- def getLoadedDocPage(self):
- return self.presenter.getDocPage()
-
- def close(self):
- """
- Close the editor (=prepare for destruction)
- """
- self.stylingThreadHolder.setThread(None)
- self.calltipThreadHolder.setThread(None)
- self.contextMenuThreadHolder.setThread(None)
-
- self.unloadCurrentDocPage({}) # ?
- self.presenterListener.disconnect()
- # self.presenter.getMiscEvent().removeListener(self.presenterListener)
-
-
- # def onConstructedMainWindow(self, evt):
- # """
- # Now we can register idle handler.
- # """
- # wx.EVT_IDLE(self, self.OnIdle)
-
-
- def Copy(self, text=None):
- if text is None:
- text = self.GetSelectedText()
-
- if len(text) == 0:
- return
-
- cbIcept = self.presenter.getMainControl().getClipboardInterceptor()
- if cbIcept is not None:
- cbIcept.informCopyInWikidPadStart(text=text)
- try:
- copyTextToClipboard(text)
- finally:
- cbIcept.informCopyInWikidPadStop()
- else:
- copyTextToClipboard(text)
-
- def Paste(self):
- # Text pasted?
- text = getTextFromClipboard()
- if text:
- self.ReplaceSelection(text)
- return True
-
- # File(name)s pasted?
- filenames = wxHelper.getFilesFromClipboard()
- if filenames is not None:
- mc = self.presenter.getMainControl()
-
- paramDict = {"editor": self, "filenames": filenames,
- "x": -1, "y": -1, "main control": mc,
- "processDirectly": True}
-
- # mc.getUserActionCoord().runAction(
- # u"action/editor/this/paste/files/insert/url/ask", paramDict)
-
- mc.getUserActionCoord().reactOnUserEvent(
- u"event/paste/editor/files", paramDict)
-
- return True
-
- fs = self.presenter.getWikiDocument().getFileStorage()
- imgsav = WikiTxtDialogs.ImagePasteSaver()
- imgsav.readOptionsFromConfig(self.presenter.getConfig())
-
- # Bitmap pasted?
- bmp = wxHelper.getBitmapFromClipboard()
- if bmp is not None:
- img = bmp.ConvertToImage()
- del bmp
-
- if self.presenter.getConfig().getboolean("main",
- "editor_imagePaste_askOnEachPaste", True):
- # Options say to present dialog on an image paste operation
- # Send image so it can be used for preview
- dlg = WikiTxtDialogs.ImagePasteDialog(
- self.presenter.getMainControl(), -1, imgsav, img)
- try:
- dlg.ShowModal()
- imgsav = dlg.getImagePasteSaver()
- finally:
- dlg.Destroy()
-
- destPath = imgsav.saveFile(fs, img)
- if destPath is None:
- # Couldn't find unused filename or saving denied
- return True
-
- url = self.presenter.getWikiDocument().makeAbsPathRelUrl(destPath)
-
- if url is None:
- url = u"file:" + StringOps.urlFromPathname(destPath)
-
- self.ReplaceSelection(url)
- return True
-
- if not WindowsHacks:
- return False
-
- # Windows Meta File pasted?
- destPath = imgsav.saveWmfFromClipboardToFileStorage(fs)
- if destPath is not None:
- url = self.presenter.getWikiDocument().makeAbsPathRelUrl(destPath)
-
- # Windows Meta File pasted?
- destPath = imgsav.saveWmfFromClipboardToFileStorage(fs)
- if destPath is not None:
- url = self.presenter.getWikiDocument().makeAbsPathRelUrl(destPath)
-
- if url is None:
- url = u"file:" + StringOps.urlFromPathname(destPath)
-
- self.ReplaceSelection(url)
- return True
-
- # Text pasted?
- text = getTextFromClipboard()
- if text:
- self.ReplaceSelection(text)
- return True
-
- return False
-
-
- def pasteRawHtml(self):
- rawHtml, url = wxHelper.getHtmlFromClipboard()
- if rawHtml:
- return self.wikiLanguageHelper.handlePasteRawHtml(self, rawHtml, {})
-
- return False
-
-
- def onCmdCopy(self, miscevt):
- if wx.Window.FindFocus() != self:
- return
- self.Copy()
-
-
-
- def setLayerVisible(self, vis, scName=""):
- """
- Informs the widget if it is really visible on the screen or not
- """
- # if vis:
- # self.Enable(True)
- self.Enable(vis)
-
-
- def isCharWrap(self):
- docPage = self.getLoadedDocPage()
- if docPage is not None:
- return docPage.getAttributeOrGlobal(u"wrap_type", u"word").lower()\
- .startswith(u"char")
- else:
- return False
-
- def setWrapMode(self, onOrOff, charWrap=None):
- if charWrap is None:
- charWrap = self.isCharWrap()
-
- if onOrOff:
- if charWrap:
- self.SetWrapMode(wx.stc.STC_WRAP_CHAR)
- else:
- self.SetWrapMode(wx.stc.STC_WRAP_WORD)
- else:
- self.SetWrapMode(wx.stc.STC_WRAP_NONE)
-
- def getWrapMode(self):
- return self.GetWrapMode() != wx.stc.STC_WRAP_NONE
-
- def setAutoIndent(self, onOff):
- self.autoIndent = onOff
-
- def getAutoIndent(self):
- return self.autoIndent
-
- def setAutoBullets(self, onOff):
- self.autoBullets = onOff
-
- def getAutoBullets(self):
- return self.autoBullets
-
- def setTabsToSpaces(self, onOff):
- self.tabsToSpaces = onOff
- self.SetUseTabs(not onOff)
-
- def getTabsToSpaces(self):
- return self.tabsToSpaces
-
- def setShowLineNumbers(self, onOrOff):
- if onOrOff:
- self.SetMarginWidth(self.NUMBER_MARGIN,
- self.TextWidth(wx.stc.STC_STYLE_LINENUMBER, "_99999"))
- self.SetMarginWidth(self.SELECT_MARGIN, 0)
- else:
- self.SetMarginWidth(self.NUMBER_MARGIN, 0)
- self.SetMarginWidth(self.SELECT_MARGIN, 16)
-
- def getShowLineNumbers(self):
- return self.GetMarginWidth(self.NUMBER_MARGIN) != 0
-
-
- def setFoldingActive(self, onOrOff, forceSync=False):
- """
- forceSync -- when setting folding on, the folding is completed
- before function returns iff forceSync is True
- """
- if onOrOff:
- self.SetMarginWidth(self.FOLD_MARGIN, 16)
- self.foldingActive = True
- if forceSync:
- try:
- self.applyFolding(self.processFolding(
- self.getPageAst(), DUMBTHREADSTOP))
- except NoPageAstException:
- return
- else:
- self.OnStyleNeeded(None)
- else:
- self.SetMarginWidth(self.FOLD_MARGIN, 0)
- self.unfoldAll()
- self.foldingActive = False
-
- def getFoldingActive(self):
- return self.foldingActive
-
-
- def SetStyles(self, styleFaces = None):
- self.SetStyleBits(5)
-
- # create the styles
- if styleFaces is None:
- styleFaces = self.presenter.getDefaultFontFaces()
-
- config = self.presenter.getConfig()
- styles = self.presenter.getMainControl().getPresentationExt()\
- .getStyles(styleFaces, config)
-
- for type, style in styles:
- self.StyleSetSpec(type, style)
-
- if type == wx.stc.STC_STYLE_CALLTIP:
- self.CallTipUseStyle(10)
-
- self.IndicatorSetStyle(2, wx.stc.STC_INDIC_SQUIGGLE)
- self.IndicatorSetForeground(2, wx.Colour(255, 0, 0))
-
-
- def SetText(self, text, emptyUndo=True):
- """
- Overrides the wxStyledTextCtrl method.
- text -- Unicode text content to set
- """
- self.incSearchCharStartPos = 0
- self.clearStylingCache()
- self.pageType = "normal"
-
- self.SetSelection(-1, -1)
- self.ignoreOnChange = True
- if isUnicode():
- wx.stc.StyledTextCtrl.SetText(self, text)
- else:
- wx.stc.StyledTextCtrl.SetText(self,
- StringOps.mbcsEnc(text, "replace")[0])
- self.ignoreOnChange = False
-
- if emptyUndo:
- self.EmptyUndoBuffer()
- # self.applyBasicSciSettings()
-
-
- def replaceText(self, text):
- if isUnicode():
- wx.stc.StyledTextCtrl.SetText(self, text)
- else:
- wx.stc.StyledTextCtrl.SetText(self,
- StringOps.mbcsEnc(text, "replace")[0])
-
-
- def replaceTextAreaByCharPos(self, newText, start, end):
- text = self.GetText()
- bs = self.bytelenSct(text[:start])
- be = bs + self.bytelenSct(text[start:end])
- self.SetTargetStart(bs)
- self.SetTargetEnd(be)
-
- if isUnicode():
- self.ReplaceTarget(newText)
- else:
- self.ReplaceTarget(StringOps.mbcsEnc(newText, "replace")[0])
-
- # text = self.GetText()
- # text = text[:pos] + newText + text[(pos + len):]
- #
- # self.replaceText(text)
-
-
- def showSelectionByCharPos(self, start, end):
- """
- Same as SetSelectionByCharPos(), but scrolls to position correctly
- """
- text = self.GetText()
- bs = self.bytelenSct(text[:start])
- be = bs + self.bytelenSct(text[start:end])
-
- self.ensureTextRangeByBytePosExpanded(bs, be)
- super(WikiTxtCtrl, self).showSelectionByCharPos(start, end)
-
-
- def applyBasicSciSettings(self):
- """
- Apply the basic Scintilla settings which are resetted to wrong
- default values by some operations
- """
- if isUnicode():
- self.SetCodePage(wx.stc.STC_CP_UTF8)
- self.SetTabIndents(True)
- self.SetBackSpaceUnIndents(True)
- self.SetUseTabs(not self.tabsToSpaces)
- self.SetEOLMode(wx.stc.STC_EOL_LF)
-
- tabWidth = self.presenter.getConfig().getint("main",
- "editor_tabWidth", 4)
-
- self.SetIndent(tabWidth)
- self.SetTabWidth(tabWidth)
-
- self.AutoCompSetFillUps(u":=") # TODO Add '.'?
- # self.SetYCaretPolicy(wxSTC_CARET_SLOP, 2)
- # self.SetYCaretPolicy(wxSTC_CARET_JUMPS | wxSTC_CARET_EVEN, 4)
- self.SetYCaretPolicy(wx.stc.STC_CARET_SLOP | wx.stc.STC_CARET_EVEN, 4)
-
-
-
- def saveLoadedDocPage(self):
- """
- Save loaded wiki page into database. Does not check if dirty
- """
- if self.getLoadedDocPage() is None:
- return
-
- page = self.getLoadedDocPage()
-
- # if not self.loadedDocPage.getDirty()[0]:
- # return
-
- # text = self.GetText()
- # page.replaceLiveText(text)
- if self.presenter.getMainControl().saveDocPage(page):
- self.SetSavePoint()
-
-
- def unloadCurrentDocPage(self, evtprops=None):
- ## _prof.start()
- # Stop threads
- self.stylingThreadHolder.setThread(None)
- self.calltipThreadHolder.setThread(None)
-
- docPage = self.getLoadedDocPage()
- if docPage is not None:
- wikiWord = docPage.getWikiWord()
- if wikiWord is not None:
- docPage.setPresentation((self.GetCurrentPos(),
- self.GetScrollPos(wx.HORIZONTAL),
- self.GetScrollPos(wx.VERTICAL)), 0)
- docPage.setPresentation((self.getFoldInfo(),), 5)
-
- if docPage.getDirty()[0]:
- self.saveLoadedDocPage()
-
- docPage.removeTxtEditor(self)
-
- self.SetDocPointer(None)
- self.applyBasicSciSettings()
-
- self.wikiPageSink.disconnect()
-
- self.presenter.setDocPage(None)
-
- self.clearStylingCache()
- # self.stylebytes = None
- # self.foldingseq = None
- # self.pageAst = None
- self.pageType = "normal"
-
- ## _prof.stop()
-
-
- def loadFuncPage(self, funcPage, evtprops=None):
- self.unloadCurrentDocPage(evtprops)
- # set the editor text
- content = None
- wikiDataManager = self.presenter.getWikiDocument()
-
- self.presenter.setDocPage(funcPage)
-
- if self.getLoadedDocPage() is None:
- return # TODO How to handle?
-
- globalAttrs = wikiDataManager.getWikiData().getGlobalAttributes()
- # get the font that should be used in the editor
- font = globalAttrs.get("global.font", self.defaultFont)
-
- # set the styles in the editor to the font
- if self.lastFont != font:
- faces = self.presenter.getDefaultFontFaces().copy()
- faces["mono"] = font
- self.SetStyles(faces)
- self.lastEditorFont = font
-
- # this updates depending on attribute "wrap_type" (word or character)
- self.setWrapMode(self.getWrapMode())
-
- # p2 = evtprops.copy()
- # p2.update({"loading current page": True})
- # self.pWiki.fireMiscEventProps(p2) # TODO Remove this hack
-
- self.wikiPageSink.setEventSource(self.getLoadedDocPage().getMiscEvent())
-
- otherEditor = self.getLoadedDocPage().getTxtEditor()
- if otherEditor is not None:
- # Another editor contains already this page, so share its
- # Scintilla document object for synchronized editing
- self.SetDocPointer(otherEditor.GetDocPointer())
- self.applyBasicSciSettings()
- else:
- # Load content
- try:
- content = self.getLoadedDocPage().getLiveText()
- except WikiFileNotFoundException, e:
- assert 0 # TODO
-
- # now fill the text into the editor
- self.SetReadOnly(False)
- self.SetText(content)
-
- if self.wikiLanguageHelper is None or \
- self.wikiLanguageHelper.getWikiLanguageName() != \
- self.getLoadedDocPage().getWikiLanguageName():
-
- wx.GetApp().freeWikiLanguageHelper(self.wikiLanguageHelper)
- self.wikiLanguageHelper = self.getLoadedDocPage().createWikiLanguageHelper()
-
- self.getLoadedDocPage().addTxtEditor(self)
- self._checkForReadOnly()
- self.presenter.setTitle(self.getLoadedDocPage().getTitle())
-
-
- def loadWikiPage(self, wikiPage, evtprops=None):
- """
- Save loaded page, if necessary, then load wikiPage into editor
- """
- self.unloadCurrentDocPage(evtprops)
- # set the editor text
- wikiDataManager = self.presenter.getWikiDocument()
-
- self.presenter.setDocPage(wikiPage)
-
- docPage = self.getLoadedDocPage()
-
- if docPage is None:
- return # TODO How to handle?
-
- self.wikiPageSink.setEventSource(docPage.getMiscEvent())
-
- otherEditor = docPage.getTxtEditor()
- if otherEditor is not None:
- # Another editor contains already this page, so share its
- # Scintilla document object for synchronized editing
- self.SetDocPointer(otherEditor.GetDocPointer())
- self.applyBasicSciSettings()
- else:
- # Load content
- try:
- content = docPage.getLiveText()
- except WikiFileNotFoundException, e:
- assert 0 # TODO
-
- # now fill the text into the editor
- self.SetReadOnly(False)
- self.setTextAgaUpdated(content)
-
- if self.wikiLanguageHelper is None or \
- self.wikiLanguageHelper.getWikiLanguageName() != \
- docPage.getWikiLanguageName():
-
- wx.GetApp().freeWikiLanguageHelper(self.wikiLanguageHelper)
- self.wikiLanguageHelper = docPage.createWikiLanguageHelper()
-
- docPage.addTxtEditor(self)
- self._checkForReadOnly()
-
- if evtprops is None:
- evtprops = {}
- p2 = evtprops.copy()
- p2.update({"loading wiki page": True, "wikiPage": docPage})
- self.presenter.fireMiscEventProps(p2) # TODO Remove this hack
-
- # get the font that should be used in the editor
- font = docPage.getAttributeOrGlobal("font", self.defaultFont)
-
- # set the styles in the editor to the font
- if self.lastFont != font:
- faces = self.presenter.getDefaultFontFaces().copy()
- faces["mono"] = font
- self.SetStyles(faces)
- self.lastEditorFont = font
-
- # this updates depending on attribute "wrap_type" (word or character)
- self.setWrapMode(self.getWrapMode())
-
- self.pageType = docPage.getAttributes().get(u"pagetype",
- [u"normal"])[-1]
-
- if self.pageType == u"normal":
- if not docPage.isDefined():
- # This is a new, not yet defined page, so go to the end of page
- self.GotoPos(self.GetLength())
- else:
- anchor = evtprops.get("anchor")
- if anchor:
- # Scroll page according to the anchor
- pageAst = self.getPageAst()
-
- anchorNodes = pageAst.iterDeepByName("anchorDef")
- for node in anchorNodes:
- if node.anchorLink == anchor:
- self.gotoCharPos(node.pos + node.strLength)
- break
- else:
- anchor = None # Not found
-
- if not anchor:
- # Is there a position given in the eventprops?
- firstcharpos = evtprops.get("firstcharpos", -1)
- if firstcharpos != -1:
- charlength = max(0, evtprops.get("charlength", 0))
- self.showSelectionByCharPos(firstcharpos,
- firstcharpos + charlength)
- anchor = True
-
- if not anchor:
- # see if there is a saved position for this page
- prst = docPage.getPresentation()
- lastPos, scrollPosX, scrollPosY = prst[0:3]
- foldInfo = prst[5]
- self.setFoldInfo(foldInfo)
- self.GotoPos(lastPos)
-
- self.scrollXY(scrollPosX, scrollPosY)
- else:
- self.handleSpecialPageType()
-
- self.presenter.setTitle(docPage.getTitle())
-
-
- def handleSpecialPageType(self):
- # self.allowRectExtend(self.pageType != u"texttree")
-
- if self.pageType == u"form":
- self.GotoPos(0)
- self._goToNextFormField()
- return True
-
- return False
-
-
- def onReloadedCurrentPage(self, miscevt):
- """
- Called when already loaded page should be loaded again, mainly
- interesting if a link with anchor is activated
- """
- if not self.presenter.isCurrent():
- return
-
- anchor = miscevt.get("anchor")
- if not anchor:
- if self.pageType == u"normal":
- # Is there a position given in the eventprops?
- firstcharpos = miscevt.get("firstcharpos", -1)
- if firstcharpos != -1:
- charlength = max(0, miscevt.get("charlength", 0))
- self.showSelectionByCharPos(firstcharpos,
- firstcharpos + charlength)
-
- return
-
-
- # if not anchor:
- # return
-
- docPage = self.getLoadedDocPage()
-
- if not docPage.isDefined():
- return
-
- if self.wikiLanguageHelper is None or \
- self.wikiLanguageHelper.getWikiLanguageName() != \
- docPage.getWikiLanguageName():
-
- wx.GetApp().freeWikiLanguageHelper(self.wikiLanguageHelper)
- self.wikiLanguageHelper = docPage.createWikiLanguageHelper()
-
- if self.pageType == u"normal":
- # Scroll page according to the anchor
- try:
- anchorNodes = self.getPageAst().iterDeepByName("anchorDef")
- anchorNodes = self.getPageAst().iterDeepByName("anchorDef")
- for node in anchorNodes:
- if node.anchorLink == anchor:
- self.gotoCharPos(node.pos + node.strLength)
- break
- # else:
- # anchor = None # Not found
-
- except NoPageAstException:
- return
-
-
- def _checkForReadOnly(self):
- """
- Set/unset read-only mode of editor according to read-only state of page.
- """
- docPage = self.getLoadedDocPage()
- if docPage is None:
- self.SetReadOnly(True)
- else:
- self.SetReadOnly(docPage.isReadOnlyEffect())
-
-
- def _getColorFromOption(self, option, defColTuple):
- """
- Helper for onOptionsChanged() to read a color from an option
- and create a wx.Colour object from it.
- """
- coltuple = StringOps.colorDescToRgbTuple(self.presenter.getConfig().get(
- "main", option))
-
- if coltuple is None:
- coltuple = defColTuple
-
- return wx.Colour(*coltuple)
-
-
- def onPageChangedReadOnlyFlag(self, miscevt):
- self._checkForReadOnly()
-
-
- def onOptionsChanged(self, miscevt):
- faces = self.presenter.getDefaultFontFaces().copy()
-
- if isinstance(self.getLoadedDocPage(),
- (DocPages.WikiPage, DocPages.AliasWikiPage)):
-
- font = self.getLoadedDocPage().getAttributeOrGlobal("font",
- self.defaultFont)
- faces["mono"] = font
- self.lastEditorFont = font # ???
-
- self._checkForReadOnly()
-
- self.SetStyles(faces)
-
- color = self._getColorFromOption("editor_bg_color", (255, 255, 255))
-
- for i in xrange(32):
- self.StyleSetBackground(i, color)
- self.StyleSetBackground(wx.stc.STC_STYLE_DEFAULT, color)
-
- self.SetSelForeground(True, self._getColorFromOption(
- "editor_selection_fg_color", (0, 0, 0)))
- self.SetSelBackground(True, self._getColorFromOption(
- "editor_selection_bg_color", (192, 192, 192)))
- self.SetCaretForeground(self._getColorFromOption(
- "editor_caret_color", (0, 0, 0)))
- # Set default color (especially for folding lines)
- self.StyleSetForeground(wx.stc.STC_STYLE_DEFAULT, self._getColorFromOption(
- "editor_plaintext_color", (0, 0, 0)))
- self.StyleSetBackground(wx.stc.STC_STYLE_LINENUMBER, self._getColorFromOption(
- "editor_margin_bg_color", (212, 208, 200)))
-
- shorthintDelay = self.presenter.getConfig().getint("main",
- "editor_shortHint_delay", 500)
- self.SetMouseDwellTime(shorthintDelay)
-
- tabWidth = self.presenter.getConfig().getint("main",
- "editor_tabWidth", 4)
-
- self.SetIndent(tabWidth)
- self.SetTabWidth(tabWidth)
- # this updates depending on attribute "wrap_type" (word or character)
- self.setWrapMode(self.getWrapMode())
-
- # To allow switching vi keys on and off without restart
- use_vi_navigation = self.presenter.getConfig().getboolean("main",
- "editor_compatibility_ViKeys", False)
-
- self.Unbind(wx.EVT_CHAR)
- self.Unbind(wx.EVT_KEY_DOWN)
- self.Unbind(wx.EVT_KEY_UP)
- self.Unbind(wx.EVT_LEFT_UP)
- #self.Unbind(wx.EVT_SCROLLWIN)
- self.Unbind(wx.EVT_MOUSEWHEEL)
-
- if use_vi_navigation:
- if self.vi is None:
- self.vi = ViHandler(self)
-
-
- if not isLinux():
- # Need to merge with OnChar_ImeWorkaround
- self.Bind(wx.EVT_CHAR, self.vi.OnChar)
- self.Bind(wx.EVT_KEY_DOWN, self.vi.OnViKeyDown)
- self.Bind(wx.EVT_LEFT_DOWN, self.vi.OnMouseClick)
- self.Bind(wx.EVT_LEFT_UP, self.vi.OnLeftMouseUp)
- # TODO: Replace with seperate scroll events
- #self.Bind(wx.EVT_SCROLLWIN, self.vi.OnScroll)
-
- if self.vi.settings["caret_scroll"]:
- self.Bind(wx.EVT_MOUSEWHEEL, self.vi.OnMouseScroll)
-
- # Should probably store shortcut state in a global
- # variable otherwise this will be run each time
- # a new tab is opened
- wx.CallAfter(self.vi._enableMenuShortcuts, False)
-
- else:
- if self.vi is not None:
- self.vi.TurnOff()
- self.vi = None
-
- if self.presenter.getConfig().getboolean("main",
- "editor_useImeWorkaround", False):
- wx.EVT_CHAR(self, self.OnChar_ImeWorkaround)
- self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
- self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
- self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
- self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
- if not isLinux():
- self.Bind(wx.EVT_CHAR, None)
-
-
- def onChangedConfiguration(self, miscevt):
- """
- Called when global configuration was changed. Most things are processed
- by onOptionsChanged so only the online spell checker switch must be
- handled here.
- """
- restyle = False
-
- newSetting = SpellChecker.isSpellCheckSupported() and \
- self.presenter.getConfig().getboolean(
- "main", "editor_onlineSpellChecker_active", False)
-
- if newSetting != self.onlineSpellCheckerActive:
- self.onlineSpellCheckerActive = newSetting
- restyle = True
-
- newSetting = self.presenter.getConfig()\
- .getboolean("main", "editor_colorizeSearchFragments", False)
-
- if newSetting != self.optionColorizeSearchFragments:
- self.optionColorizeSearchFragments = newSetting
- restyle = True
-
- if restyle:
- self.OnStyleNeeded(None)
-
-
-
- def onWikiPageUpdated(self, miscevt):
- if self.getLoadedDocPage() is None or \
- not isinstance(self.getLoadedDocPage(),
- (DocPages.WikiPage, DocPages.AliasWikiPage)):
- return
-
- # get the font that should be used in the editor
- font = self.getLoadedDocPage().getAttributeOrGlobal("font",
- self.defaultFont)
-
- # set the styles in the editor to the font
- if self.lastFont != font:
- faces = self.presenter.getDefaultFontFaces().copy()
- faces["mono"] = font
- self.SetStyles(faces)
- self.lastEditorFont = font
-
- # this updates depending on attribute "wrap_type" (word or character)
- self.setWrapMode(self.getWrapMode())
-
- self.pageType = self.getLoadedDocPage().getAttributes().get(u"pagetype",
- [u"normal"])[-1]
-
-
- def handleInvalidFileSignature(self, docPage):
- """
- Called directly from a doc page to repair the editor state if an
- invalid file signature was detected.
-
- docPage -- calling docpage
- """
- if docPage is not self.getLoadedDocPage() or \
- not isinstance(docPage,
- (DocPages.DataCarryingPage, DocPages.AliasWikiPage)):
- return
-
- sd, ud = docPage.getDirty()
- if sd:
- return # TODO What to do on conflict?
-
- content = docPage.getContent()
- docPage.setEditorText(content, dirty=False)
- self.ignoreOnChange = True
- # TODO: Store/restore selection & scroll pos.
- self.setTextAgaUpdated(content)
- self.ignoreOnChange = False
-
-
- def onSavingAllPages(self, miscevt):
- if self.getLoadedDocPage() is not None and (
- self.getLoadedDocPage().getDirty()[0] or miscevt.get("force",
- False)):
- self.saveLoadedDocPage()
-
- def onClosingCurrentWiki(self, miscevt):
- self.unloadCurrentDocPage()
-
- def onDroppingCurrentWiki(self, miscevt):
- """
- An access error occurred. Get rid of any data without trying to save
- it.
- """
- if self.getLoadedDocPage() is not None:
- self.wikiPageSink.disconnect()
-
- self.SetDocPointer(None)
- self.applyBasicSciSettings()
-
- self.getLoadedDocPage().removeTxtEditor(self)
- self.presenter.setDocPage(None)
- # self.loadedDocPage = None
- self.pageType = "normal"
-
-
- def OnStyleNeeded(self, evt):
- "Styles the text of the editor"
- docPage = self.getLoadedDocPage()
- if docPage is None:
- # This avoids further request from STC:
- self.stopStcStyler()
- return
-
- # get the text to regex against (use doc pages getLiveText because
- # it's cached
- text = docPage.getLiveText() # self.GetText()
- textlen = len(text)
-
- t = self.stylingThreadHolder.getThread()
- if t is not None:
- self.stylingThreadHolder.setThread(None)
- self.clearStylingCache()
-
-
- if textlen < self.presenter.getConfig().getint(
- "main", "sync_highlight_byte_limit"):
- # if True:
- # Synchronous styling
- self.stylingThreadHolder.setThread(None)
- self.buildStyling(text, 0, threadstop=DUMBTHREADSTOP)
-
- self.applyStyling(self.stylebytes) # TODO Necessary?
- # We can't call applyFolding directly because this in turn
- # calls repairFoldingVisibility which can't work while in
- # EVT_STC_STYLENEEDED event (at least for wxPython 2.6.2)
- # storeStylingAndAst() sends a StyleDoneEvent instead
- if self.getFoldingActive():
- self.storeStylingAndAst(None, self.foldingseq)
- else:
- # Asynchronous styling
- # This avoids further request from STC:
- self.stopStcStyler()
-
- sth = self.stylingThreadHolder
-
- delay = self.presenter.getConfig().getfloat(
- "main", "async_highlight_delay")
- t = threading.Thread(None, self.buildStyling, args = (text, delay, sth))
- sth.setThread(t)
- t.setDaemon(True)
- t.start()
-
-
- def _fillTemplateMenu(self, menu):
- idRecycler = self.templateIdRecycler
- idRecycler.clearAssoc()
-
- config = self.presenter.getConfig()
-
- templateRePat = config.get(u"main", u"template_pageNamesRE",
- u"^template/")
-
- try:
- templateRe = re.compile(templateRePat, re.DOTALL | re.UNICODE)
- except re.error:
- templateRe = re.compile(u"^template/", re.DOTALL | re.UNICODE)
-
- wikiDocument = self.presenter.getWikiDocument()
- templateNames = [n for n in wikiDocument.getAllDefinedWikiPageNames()
- if templateRe.search(n)]
-
- wikiDocument.getCollator().sort(templateNames)
-
- for tn in templateNames:
- menuID, reused = idRecycler.assocGetIdAndReused(tn)
-
- if not reused:
- # For a new id, an event must be set
- wx.EVT_MENU(self, menuID, self.OnTemplateUsed)
-
- menu.Append(menuID, StringOps.uniToGui(tn))
-
-
- def OnTemplateUsed(self, evt):
- docPage = self.getLoadedDocPage()
- if docPage is None:
- return
- templateName = self.templateIdRecycler.get(evt.GetId())
-
- if templateName is None:
- return
-
- wikiDocument = self.presenter.getWikiDocument()
- templatePage = wikiDocument.getWikiPage(templateName)
-
- content = self.getLoadedDocPage().getContentOfTemplate(templatePage,
- templatePage)
- docPage.setMetaDataFromTemplate(templatePage)
-
- self.SetText(content, emptyUndo=False)
- self.pageType = docPage.getAttributes().get(u"pagetype",
- [u"normal"])[-1]
- self.handleSpecialPageType()
- # TODO Handle form mode
- self.presenter.informEditorTextChanged(self)
-
-
- def…
Large files files are truncated, but you can click here to view the full file