eric7/QScintilla/MiniEditor.py

Fri, 31 Dec 2021 17:22:45 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Fri, 31 Dec 2021 17:22:45 +0100
branch
eric7
changeset 8885
b0bbe8bda1f2
parent 8881
54e42bc2437a
child 9152
8a68afaf1ba2
permissions
-rw-r--r--

Extended the mini editor to have capability to change editor configuration.

# -*- coding: utf-8 -*-

# Copyright (c) 2007 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing an editor for simple editing tasks.
"""

import os
import re
import contextlib

import editorconfig

from PyQt6.QtCore import (
    pyqtSignal, pyqtSlot, Qt, QSignalMapper, QPoint, QTimer, QFileInfo, QSize,
    QCoreApplication
)
from PyQt6.QtGui import (
    QKeySequence, QPalette, QFont, QPixmap, QActionGroup, QAction
)
from PyQt6.QtWidgets import (
    QWidget, QWhatsThis, QDialog, QInputDialog, QApplication,
    QMenu, QVBoxLayout, QHBoxLayout, QLabel
)
from PyQt6.QtPrintSupport import QPrinter, QPrintDialog, QAbstractPrintDialog
from PyQt6.Qsci import QsciScintilla

from EricGui.EricAction import EricAction, createActionGroup
from EricWidgets import EricMessageBox, EricFileDialog
from EricWidgets.EricMainWindow import EricMainWindow
from EricWidgets.EricClickableLabel import EricClickableLabel
from EricWidgets.EricZoomWidget import EricZoomWidget
from EricGui.EricOverrideCursor import EricOverrideCursor

from .QsciScintillaCompat import QsciScintillaCompat

import UI.PixmapCache
import UI.Config

from Globals import isMacPlatform

import Utilities
import Preferences


class MiniScintilla(QsciScintillaCompat):
    """
    Class implementing a QsciScintillaCompat subclass for handling focus
    events.
    """
    EncloseChars = {
        '"': '"',
        "'": "'",
        "(": "()",
        ")": "()",
        "{": "{}",          # __IGNORE_WARNING_M613__
        "}": "{}",          # __IGNORE_WARNING_M613__
        "[": "[]",
        "]": "[]",
        "<": "<>",
        ">": "<>",
    }
    
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent parent widget
        @type QWidget
        """
        super().__init__(parent)
        
        self.enableMultiCursorSupport()
        
        self.mw = parent
    
    def getFileName(self):
        """
        Public method to return the name of the file being displayed.
        
        @return filename of the displayed file
        @rtype str
        """
        return self.mw.getFileName()
    
    def editorCommand(self, cmd):
        """
        Public method to perform a simple editor command.
        
        @param cmd the scintilla command to be performed (integer)
        """
        if cmd == QsciScintilla.SCI_DELETEBACK:
            line, index = self.getCursorPosition()
            text = self.text(line)[index - 1:index + 1]
            matchingPairs = ['()', '[]', '{}', '<>', "''", '""']
            # __IGNORE_WARNING_M613__
            if text in matchingPairs:
                self.delete()
        
        super().editorCommand(cmd)
    
    def keyPressEvent(self, ev):
        """
        Protected method to handle the user input a key at a time.
        
        @param ev key event
        @type QKeyEvent
        """
        def encloseSelectedText(encString):
            """
            Local function to enclose the current selection with some
            characters.
            
            @param encString string to use to enclose the selection
                (one or two characters)
            @type str
            """
            startChar = encString[0]
            endChar = encString[1] if len(encString) == 2 else startChar
            
            sline, sindex, eline, eindex = self.getSelection()
            replaceText = startChar + self.selectedText() + endChar
            self.beginUndoAction()
            self.replaceSelectedText(replaceText)
            self.endUndoAction()
            self.setSelection(sline, sindex + 1, eline, eindex + 1)
        
        txt = ev.text()
        
        # See it is text to insert.
        if len(txt) and txt >= " ":
            if (
                self.hasSelectedText() and
                txt in MiniScintilla.EncloseChars
            ):
                encloseSelectedText(MiniScintilla.EncloseChars[txt])
                ev.accept()
                return
            
            super().keyPressEvent(ev)
        else:
            ev.ignore()
    
    def mousePressEvent(self, event):
        """
        Protected method to handle the mouse press event.
        
        @param event the mouse press event
        @type QMouseEvent
        """
        if event.button() == Qt.MouseButton.XButton1:
            self.undo()
            event.accept()
        elif event.button() == Qt.MouseButton.XButton2:
            self.redo()
            event.accept()
        elif (
            event.button() == Qt.MouseButton.LeftButton and
            bool(event.modifiers() & (
                Qt.KeyboardModifier.MetaModifier |
                Qt.KeyboardModifier.AltModifier
            ))
        ):
            line, index = self.lineIndexFromPoint(event.position().toPoint())
            self.addCursor(line, index)
            event.accept()
        else:
            super().mousePressEvent(event)
    
    def focusInEvent(self, event):
        """
        Protected method called when the editor receives focus.
        
        This method checks for modifications of the current file and
        rereads it upon request. The cursor is placed at the current position
        assuming, that it is in the vicinity of the old position after the
        reread.
        
        @param event the event object
        @type QFocusEvent
        """
        self.mw.editorActGrp.setEnabled(True)
        with contextlib.suppress(AttributeError):
            self.setCaretWidth(self.mw.caretWidth)
        
        self.setCursorFlashTime(QApplication.cursorFlashTime())
        
        super().focusInEvent(event)
    
    def focusOutEvent(self, event):
        """
        Protected method called when the editor loses focus.
        
        @param event the event object
        @type QFocusEvent
        """
        self.mw.editorActGrp.setEnabled(False)
        self.setCaretWidth(0)
        
        super().focusOutEvent(event)
        
    def removeTrailingWhitespace(self):
        """
        Public method to remove trailing whitespace.
        """
        searchRE = r"[ \t]+$"    # whitespace at the end of a line
        
        ok = self.findFirstTarget(searchRE, True, False, False, 0, 0)
        self.beginUndoAction()
        while ok:
            self.replaceTarget("")
            ok = self.findNextTarget()
        self.endUndoAction()


class MiniEditor(EricMainWindow):
    """
    Class implementing an editor for simple editing tasks.
    
    @signal editorSaved() emitted after the file has been saved
    @signal languageChanged(str) emitted when the editors language was set. The
        language is passed as a parameter.
    @signal editorRenamed(str) emitted after the editor got a new name
        (i.e. after a 'Save As')
    @signal cursorLineChanged(int) emitted when the cursor line was changed
    
    @signal refreshed() dummy signal to emulate the Editor interface
    """
    editorSaved = pyqtSignal()
    languageChanged = pyqtSignal(str)
    editorRenamed = pyqtSignal(str)
    cursorLineChanged = pyqtSignal(int)
    
    refreshed = pyqtSignal()
    
    def __init__(self, filename="", filetype="", parent=None, name=None):
        """
        Constructor
        
        @param filename name of the file to open (string)
        @param filetype type of the source file (string)
        @param parent reference to the parent widget (QWidget)
        @param name object name of the window (string)
        """
        super().__init__(parent)
        if name is not None:
            self.setObjectName(name)
        self.setWindowIcon(UI.PixmapCache.getIcon("editor"))
        
        self.setStyle(Preferences.getUI("Style"),
                      Preferences.getUI("StyleSheet"))
        
        self.__textEdit = MiniScintilla(self)
        self.__textEdit.clearSearchIndicators = self.clearSearchIndicators
        self.__textEdit.setSearchIndicator = self.setSearchIndicator
        self.__textEdit.setUtf8(True)
        
        self.getCursorPosition = self.__textEdit.getCursorPosition
        self.text = self.__textEdit.text
        self.getZoom = self.__textEdit.getZoom
        self.zoomTo = self.__textEdit.zoomTo
        self.zoomIn = self.__textEdit.zoomIn
        self.zoomOut = self.__textEdit.zoomOut
        
        self.__curFile = filename
        self.__lastLine = 0
        
        self.srHistory = {
            "search": [],
            "replace": []
        }
        from .SearchReplaceWidget import SearchReplaceWidget
        self.__searchWidget = SearchReplaceWidget(False, self, self)
        self.__replaceWidget = SearchReplaceWidget(True, self, self)
        
        from .EditorOutline import EditorOutlineView
        self.__sourceOutline = EditorOutlineView(self, populate=False)
        self.__sourceOutline.setMaximumWidth(
            Preferences.getEditor("SourceOutlineWidth"))
        
        hlayout = QHBoxLayout()
        hlayout.setContentsMargins(0, 0, 0, 0)
        hlayout.setSpacing(1)
        hlayout.addWidget(self.__textEdit)
        hlayout.addWidget(self.__sourceOutline)
        
        centralWidget = QWidget()
        layout = QVBoxLayout()
        layout.setContentsMargins(1, 1, 1, 1)
        layout.addLayout(hlayout)
        layout.addWidget(self.__searchWidget)
        layout.addWidget(self.__replaceWidget)
        centralWidget.setLayout(layout)
        self.setCentralWidget(centralWidget)
        self.__searchWidget.hide()
        self.__replaceWidget.hide()
        
        self.lexer_ = None
        self.apiLanguage = ""
        self.filetype = ""
        
        self.__loadEditorConfig(filename)
        
        self.__createActions()
        self.__createMenus()
        self.__createToolBars()
        self.__createStatusBar()
        
        self.__loadConfiguration()
        self.__readSettings()
        
        # clear QScintilla defined keyboard commands
        # we do our own handling through the view manager
        self.__textEdit.clearAlternateKeys()
        self.__textEdit.clearKeys()
        
        # initialise the mark occurrences timer
        self.__markOccurrencesTimer = QTimer(self)
        self.__markOccurrencesTimer.setSingleShot(True)
        self.__markOccurrencesTimer.setInterval(
            Preferences.getEditor("MarkOccurrencesTimeout"))
        self.__markOccurrencesTimer.timeout.connect(self.__markOccurrences)
        self.__markedText = ""
        
        self.__changeTimer = QTimer(self)
        self.__changeTimer.setSingleShot(True)
        self.__changeTimer.setInterval(5 * 1000)
        self.__textEdit.textChanged.connect(self.__resetChangeTimer)
        
        self.__textEdit.textChanged.connect(self.__documentWasModified)
        self.__textEdit.modificationChanged.connect(self.__modificationChanged)
        self.__textEdit.cursorPositionChanged.connect(
            self.__cursorPositionChanged)
        self.__textEdit.linesChanged.connect(self.__resizeLinenoMargin)
        
        self.__textEdit.setContextMenuPolicy(
            Qt.ContextMenuPolicy.CustomContextMenu)
        self.__textEdit.customContextMenuRequested.connect(
            self.__contextMenuRequested)
        
        self.__textEdit.selectionChanged.connect(
            lambda: self.__searchWidget.selectionChanged(self.__textEdit))
        self.__textEdit.selectionChanged.connect(
            lambda: self.__replaceWidget.selectionChanged(self.__textEdit))
        
        if filename:
            self.__loadFile(filename, filetype)
        else:
            self.__setCurrentFile("")
            self.encoding = self.__getEditorConfig("DefaultEncoding")
        
        self.__checkActions()
        
        self.__sourceOutline.setActive(True)
        self.__sourceOutline.setVisible(
            self.__sourceOutline.isSupportedLanguage(
                self.getLanguage()
            )
        )
        self.__changeTimer.timeout.connect(self.__sourceOutline.repopulate)
        self.languageChanged.connect(self.__editorChanged)
        self.editorRenamed.connect(self.__editorChanged)

    def closeEvent(self, event):
        """
        Protected method to handle the close event.
        
        @param event close event (QCloseEvent)
        """
        if self.__maybeSave():
            self.__writeSettings()
            event.accept()
        else:
            event.ignore()
    
    def __newFile(self):
        """
        Private slot to create a new file.
        """
        if self.__maybeSave():
            self.__textEdit.clear()
            self.__setCurrentFile("")
        
        self.__checkActions()
    
    def __open(self):
        """
        Private slot to open a file.
        """
        if self.__maybeSave():
            fileName = EricFileDialog.getOpenFileName(self)
            if fileName:
                self.__loadFile(fileName)
        self.__checkActions()
    
    def __save(self):
        """
        Private slot to save a file.
        
        @return flag indicating success (boolean)
        """
        if not self.__curFile:
            return self.__saveAs()
        else:
            return self.__saveFile(self.__curFile)
    
    def __saveAs(self):
        """
        Private slot to save a file with a new name.
        
        @return flag indicating success (boolean)
        """
        fileName = EricFileDialog.getSaveFileName(self)
        if not fileName:
            return False
        
        result = self.__saveFile(fileName)
        
        self.editorRenamed.emit(fileName)
        
        return result
    
    def __saveCopy(self):
        """
        Private slot to save a copy of the file with a new name.
        """
        fileName = EricFileDialog.getSaveFileName(self)
        if not fileName:
            return
        
        self.__writeFile(fileName)
    
    def __about(self):
        """
        Private slot to show a little About message.
        """
        EricMessageBox.about(
            self,
            self.tr("About eric Mini Editor"),
            self.tr(
                "The eric Mini Editor is an editor component"
                " based on QScintilla. It may be used for simple"
                " editing tasks, that don't need the power of"
                " a full blown editor."))
    
    def __aboutQt(self):
        """
        Private slot to handle the About Qt dialog.
        """
        EricMessageBox.aboutQt(self, "eric Mini Editor")
    
    def __whatsThis(self):
        """
        Private slot called in to enter Whats This mode.
        """
        QWhatsThis.enterWhatsThisMode()
    
    def __documentWasModified(self):
        """
        Private slot to handle a change in the documents modification status.
        """
        self.setWindowModified(self.__textEdit.isModified())
    
    def __checkActions(self, setSb=True):
        """
        Private slot to check some actions for their enable/disable status
        and set the statusbar info.
        
        @param setSb flag indicating an update of the status bar is wanted
            (boolean)
        """
        self.saveAct.setEnabled(self.__textEdit.isModified())
        
        self.undoAct.setEnabled(self.__textEdit.isUndoAvailable())
        self.redoAct.setEnabled(self.__textEdit.isRedoAvailable())
        
        if setSb:
            line, pos = self.getCursorPosition()
            lang = self.getLanguage()
            self.__setSbFile(line + 1, pos, lang)
    
    def __setSbFile(self, line=None, pos=None, language=None, zoom=None):
        """
        Private method to set the file info in the status bar.
        
        @param line line number to display
        @type int
        @param pos character position to display
        @type int
        @param language language to display
        @type str
        @param zoom zoom value
        @type int
        """
        if not self.__curFile:
            writ = '   '
        else:
            if QFileInfo(self.__curFile).isWritable():
                writ = ' rw'
            else:
                writ = ' ro'
        
        self.sbWritable.setText(writ)
        
        if line is None:
            line = ''
        self.sbLine.setText(self.tr('Line: {0:5}').format(line))
        
        if pos is None:
            pos = ''
        self.sbPos.setText(self.tr('Pos: {0:5}').format(pos))
        
        if language is None:
            pixmap = QPixmap()
        elif language == "":
            pixmap = UI.PixmapCache.getPixmap("fileText")
        else:
            import QScintilla.Lexers
            pixmap = QScintilla.Lexers.getLanguageIcon(language, True)
        self.sbLanguage.setPixmap(pixmap)
        if pixmap.isNull():
            self.sbLanguage.setText(language)
            self.sbLanguage.setToolTip("")
        else:
            self.sbLanguage.setText("")
            self.sbLanguage.setToolTip(
                self.tr('Language: {0}').format(language))
        
        if zoom is None:
            self.sbZoom.setValue(self.getZoom())
        else:
            self.sbZoom.setValue(zoom)
    
    def __readShortcut(self, act, category):
        """
        Private function to read a single keyboard shortcut from the settings.
        
        @param act reference to the action object (EricAction)
        @param category category the action belongs to (string)
        """
        if act.objectName():
            accel = Preferences.getSettings().value(
                "Shortcuts/{0}/{1}/Accel".format(category, act.objectName()))
            if accel is not None:
                act.setShortcut(QKeySequence(accel))
            accel = Preferences.getSettings().value(
                "Shortcuts/{0}/{1}/AltAccel".format(
                    category, act.objectName()))
            if accel is not None:
                act.setAlternateShortcut(QKeySequence(accel), removeEmpty=True)
    
    def __createActions(self):
        """
        Private method to create the actions.
        """
        self.fileActions = []
        self.editActions = []
        self.helpActions = []
        self.searchActions = []
        self.viewActions = []
        self.configActions = []
        
        self.__createFileActions()
        self.__createEditActions()
        self.__createHelpActions()
        self.__createSearchActions()
        self.__createViewActions()
        self.__createConfigActions()
        
        # read the keyboard shortcuts and make them identical to the main
        # eric shortcuts
        for act in self.helpActions + self.configActions:
            self.__readShortcut(act, "General")
        for act in self.editActions:
            self.__readShortcut(act, "Edit")
        for act in self.fileActions:
            self.__readShortcut(act, "File")
        for act in self.searchActions:
            self.__readShortcut(act, "Search")
        for act in self.viewActions:
            self.__readShortcut(act, "View")
    
    def __createFileActions(self):
        """
        Private method to create the File actions.
        """
        self.newAct = EricAction(
            self.tr('New'),
            UI.PixmapCache.getIcon("new"),
            self.tr('&New'),
            QKeySequence(self.tr("Ctrl+N", "File|New")),
            0, self, 'vm_file_new')
        self.newAct.setStatusTip(self.tr('Open an empty editor window'))
        self.newAct.setWhatsThis(self.tr(
            """<b>New</b>"""
            """<p>An empty editor window will be created.</p>"""
        ))
        self.newAct.triggered.connect(self.__newFile)
        self.fileActions.append(self.newAct)
        
        self.openAct = EricAction(
            self.tr('Open'),
            UI.PixmapCache.getIcon("open"),
            self.tr('&Open...'),
            QKeySequence(self.tr("Ctrl+O", "File|Open")),
            0, self, 'vm_file_open')
        self.openAct.setStatusTip(self.tr('Open a file'))
        self.openAct.setWhatsThis(self.tr(
            """<b>Open a file</b>"""
            """<p>You will be asked for the name of a file to be opened.</p>"""
        ))
        self.openAct.triggered.connect(self.__open)
        self.fileActions.append(self.openAct)
        
        self.saveAct = EricAction(
            self.tr('Save'),
            UI.PixmapCache.getIcon("fileSave"),
            self.tr('&Save'),
            QKeySequence(self.tr("Ctrl+S", "File|Save")),
            0, self, 'vm_file_save')
        self.saveAct.setStatusTip(self.tr('Save the current file'))
        self.saveAct.setWhatsThis(self.tr(
            """<b>Save File</b>"""
            """<p>Save the contents of current editor window.</p>"""
        ))
        self.saveAct.triggered.connect(self.__save)
        self.fileActions.append(self.saveAct)
        
        self.saveAsAct = EricAction(
            self.tr('Save as'),
            UI.PixmapCache.getIcon("fileSaveAs"),
            self.tr('Save &as...'),
            QKeySequence(self.tr("Shift+Ctrl+S", "File|Save As")),
            0, self, 'vm_file_save_as')
        self.saveAsAct.setStatusTip(self.tr(
            'Save the current file to a new one'))
        self.saveAsAct.setWhatsThis(self.tr(
            """<b>Save File as</b>"""
            """<p>Save the contents of current editor window to a new file."""
            """ The file can be entered in a file selection dialog.</p>"""
        ))
        self.saveAsAct.triggered.connect(self.__saveAs)
        self.fileActions.append(self.saveAsAct)
        
        self.saveCopyAct = EricAction(
            self.tr('Save Copy'),
            UI.PixmapCache.getIcon("fileSaveCopy"),
            self.tr('Save &Copy...'),
            0, 0, self, 'vm_file_save_copy')
        self.saveCopyAct.setStatusTip(self.tr(
            'Save a copy of the current file'))
        self.saveCopyAct.setWhatsThis(self.tr(
            """<b>Save Copy</b>"""
            """<p>Save a copy of the contents of current editor window."""
            """ The file can be entered in a file selection dialog.</p>"""
        ))
        self.saveCopyAct.triggered.connect(self.__saveCopy)
        self.fileActions.append(self.saveCopyAct)
        
        self.closeAct = EricAction(
            self.tr('Close'),
            UI.PixmapCache.getIcon("close"),
            self.tr('&Close'),
            QKeySequence(self.tr("Ctrl+W", "File|Close")),
            0, self, 'vm_file_close')
        self.closeAct.setStatusTip(self.tr('Close the editor window'))
        self.closeAct.setWhatsThis(self.tr(
            """<b>Close Window</b>"""
            """<p>Close the current window.</p>"""
        ))
        self.closeAct.triggered.connect(self.close)
        self.fileActions.append(self.closeAct)
        
        self.printAct = EricAction(
            self.tr('Print'),
            UI.PixmapCache.getIcon("print"),
            self.tr('&Print'),
            QKeySequence(self.tr("Ctrl+P", "File|Print")),
            0, self, 'vm_file_print')
        self.printAct.setStatusTip(self.tr('Print the current file'))
        self.printAct.setWhatsThis(self.tr(
            """<b>Print File</b>"""
            """<p>Print the contents of the current file.</p>"""
        ))
        self.printAct.triggered.connect(self.__printFile)
        self.fileActions.append(self.printAct)
        
        self.printPreviewAct = EricAction(
            self.tr('Print Preview'),
            UI.PixmapCache.getIcon("printPreview"),
            QCoreApplication.translate('ViewManager', 'Print Preview'),
            0, 0, self, 'vm_file_print_preview')
        self.printPreviewAct.setStatusTip(self.tr(
            'Print preview of the current file'))
        self.printPreviewAct.setWhatsThis(self.tr(
            """<b>Print Preview</b>"""
            """<p>Print preview of the current file.</p>"""
        ))
        self.printPreviewAct.triggered.connect(self.__printPreviewFile)
        self.fileActions.append(self.printPreviewAct)
    
    def __createEditActions(self):
        """
        Private method to create the Edit actions.
        """
        self.undoAct = EricAction(
            self.tr('Undo'),
            UI.PixmapCache.getIcon("editUndo"),
            self.tr('&Undo'),
            QKeySequence(self.tr("Ctrl+Z", "Edit|Undo")),
            QKeySequence(self.tr("Alt+Backspace", "Edit|Undo")),
            self, 'vm_edit_undo')
        self.undoAct.setStatusTip(self.tr('Undo the last change'))
        self.undoAct.setWhatsThis(self.tr(
            """<b>Undo</b>"""
            """<p>Undo the last change done in the current editor.</p>"""
        ))
        self.undoAct.triggered.connect(self.__undo)
        self.editActions.append(self.undoAct)
        
        self.redoAct = EricAction(
            self.tr('Redo'),
            UI.PixmapCache.getIcon("editRedo"),
            self.tr('&Redo'),
            QKeySequence(self.tr("Ctrl+Shift+Z", "Edit|Redo")),
            0, self, 'vm_edit_redo')
        self.redoAct.setStatusTip(self.tr('Redo the last change'))
        self.redoAct.setWhatsThis(self.tr(
            """<b>Redo</b>"""
            """<p>Redo the last change done in the current editor.</p>"""
        ))
        self.redoAct.triggered.connect(self.__redo)
        self.editActions.append(self.redoAct)
        
        self.cutAct = EricAction(
            self.tr('Cut'),
            UI.PixmapCache.getIcon("editCut"),
            self.tr('Cu&t'),
            QKeySequence(self.tr("Ctrl+X", "Edit|Cut")),
            QKeySequence(self.tr("Shift+Del", "Edit|Cut")),
            self, 'vm_edit_cut')
        self.cutAct.setStatusTip(self.tr('Cut the selection'))
        self.cutAct.setWhatsThis(self.tr(
            """<b>Cut</b>"""
            """<p>Cut the selected text of the current editor to the"""
            """ clipboard.</p>"""
        ))
        self.cutAct.triggered.connect(self.__textEdit.cut)
        self.editActions.append(self.cutAct)
        
        self.copyAct = EricAction(
            self.tr('Copy'),
            UI.PixmapCache.getIcon("editCopy"),
            self.tr('&Copy'),
            QKeySequence(self.tr("Ctrl+C", "Edit|Copy")),
            QKeySequence(self.tr("Ctrl+Ins", "Edit|Copy")),
            self, 'vm_edit_copy')
        self.copyAct.setStatusTip(self.tr('Copy the selection'))
        self.copyAct.setWhatsThis(self.tr(
            """<b>Copy</b>"""
            """<p>Copy the selected text of the current editor to the"""
            """ clipboard.</p>"""
        ))
        self.copyAct.triggered.connect(self.__textEdit.copy)
        self.editActions.append(self.copyAct)
        
        self.pasteAct = EricAction(
            self.tr('Paste'),
            UI.PixmapCache.getIcon("editPaste"),
            self.tr('&Paste'),
            QKeySequence(self.tr("Ctrl+V", "Edit|Paste")),
            QKeySequence(self.tr("Shift+Ins", "Edit|Paste")),
            self, 'vm_edit_paste')
        self.pasteAct.setStatusTip(self.tr(
            'Paste the last cut/copied text'))
        self.pasteAct.setWhatsThis(self.tr(
            """<b>Paste</b>"""
            """<p>Paste the last cut/copied text from the clipboard to"""
            """ the current editor.</p>"""
        ))
        self.pasteAct.triggered.connect(self.__textEdit.paste)
        self.editActions.append(self.pasteAct)
        
        self.deleteAct = EricAction(
            self.tr('Clear'),
            UI.PixmapCache.getIcon("editDelete"),
            self.tr('Cl&ear'),
            QKeySequence(self.tr("Alt+Shift+C", "Edit|Clear")),
            0,
            self, 'vm_edit_clear')
        self.deleteAct.setStatusTip(self.tr('Clear all text'))
        self.deleteAct.setWhatsThis(self.tr(
            """<b>Clear</b>"""
            """<p>Delete all text of the current editor.</p>"""
        ))
        self.deleteAct.triggered.connect(self.__textEdit.clear)
        self.editActions.append(self.deleteAct)
        
        self.cutAct.setEnabled(False)
        self.copyAct.setEnabled(False)
        self.__textEdit.copyAvailable.connect(self.cutAct.setEnabled)
        self.__textEdit.copyAvailable.connect(self.copyAct.setEnabled)
        
        ####################################################################
        ## Below follow the actions for QScintilla standard commands.
        ####################################################################
        
        self.esm = QSignalMapper(self)
        try:
            self.esm.mappedInt.connect(self.__textEdit.editorCommand)
        except AttributeError:
            # pre Qt 5.15
            self.esm.mapped[int].connect(self.__textEdit.editorCommand)
        
        self.editorActGrp = createActionGroup(self)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Move left one character'),
            QCoreApplication.translate('ViewManager',
                                       'Move left one character'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Left')), 0,
            self.editorActGrp, 'vm_edit_move_left_char')
        self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFT)
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+B')))
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Move right one character'),
            QCoreApplication.translate('ViewManager',
                                       'Move right one character'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Right')),
            0, self.editorActGrp, 'vm_edit_move_right_char')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+F')))
        self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Move up one line'),
            QCoreApplication.translate('ViewManager', 'Move up one line'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Up')), 0,
            self.editorActGrp, 'vm_edit_move_up_line')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+P')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEUP)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Move down one line'),
            QCoreApplication.translate('ViewManager', 'Move down one line'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Down')), 0,
            self.editorActGrp, 'vm_edit_move_down_line')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+N')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEDOWN)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Move left one word part'),
            QCoreApplication.translate('ViewManager',
                                       'Move left one word part'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_left_word_part')
        if not isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Left')))
        self.esm.setMapping(act, QsciScintilla.SCI_WORDPARTLEFT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Move right one word part'),
            QCoreApplication.translate('ViewManager',
                                       'Move right one word part'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_right_word_part')
        if not isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Right')))
        self.esm.setMapping(act, QsciScintilla.SCI_WORDPARTRIGHT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Move left one word'),
            QCoreApplication.translate('ViewManager', 'Move left one word'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_left_word')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Left')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Left')))
        self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Move right one word'),
            QCoreApplication.translate('ViewManager', 'Move right one word'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_right_word')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Right')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Right')))
        self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Move to first visible character in document line'),
            QCoreApplication.translate(
                'ViewManager',
                'Move to first visible character in document line'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_first_visible_char')
        if not isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Home')))
        self.esm.setMapping(act, QsciScintilla.SCI_VCHOME)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Move to start of display line'),
            QCoreApplication.translate(
                'ViewManager',
                'Move to start of display line'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_start_line')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Left')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Home')))
        self.esm.setMapping(act, QsciScintilla.SCI_HOMEDISPLAY)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Move to end of document line'),
            QCoreApplication.translate(
                'ViewManager',
                'Move to end of document line'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_end_line')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+E')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'End')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Scroll view down one line'),
            QCoreApplication.translate('ViewManager',
                                       'Scroll view down one line'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Down')),
            0, self.editorActGrp, 'vm_edit_scroll_down_line')
        self.esm.setMapping(act, QsciScintilla.SCI_LINESCROLLDOWN)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Scroll view up one line'),
            QCoreApplication.translate('ViewManager',
                                       'Scroll view up one line'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+Up')),
            0, self.editorActGrp, 'vm_edit_scroll_up_line')
        self.esm.setMapping(act, QsciScintilla.SCI_LINESCROLLUP)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Move up one paragraph'),
            QCoreApplication.translate('ViewManager', 'Move up one paragraph'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Alt+Up')),
            0, self.editorActGrp, 'vm_edit_move_up_para')
        self.esm.setMapping(act, QsciScintilla.SCI_PARAUP)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Move down one paragraph'),
            QCoreApplication.translate('ViewManager',
                                       'Move down one paragraph'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Down')),
            0, self.editorActGrp, 'vm_edit_move_down_para')
        self.esm.setMapping(act, QsciScintilla.SCI_PARADOWN)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Move up one page'),
            QCoreApplication.translate('ViewManager', 'Move up one page'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'PgUp')), 0,
            self.editorActGrp, 'vm_edit_move_up_page')
        self.esm.setMapping(act, QsciScintilla.SCI_PAGEUP)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Move down one page'),
            QCoreApplication.translate('ViewManager', 'Move down one page'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'PgDown')),
            0, self.editorActGrp, 'vm_edit_move_down_page')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+V')))
        self.esm.setMapping(act, QsciScintilla.SCI_PAGEDOWN)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Move to start of document'),
            QCoreApplication.translate('ViewManager',
                                       'Move to start of document'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_start_text')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Up')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Home')))
        self.esm.setMapping(act, QsciScintilla.SCI_DOCUMENTSTART)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Move to end of document'),
            QCoreApplication.translate('ViewManager',
                                       'Move to end of document'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_end_text')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Down')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+End')))
        self.esm.setMapping(act, QsciScintilla.SCI_DOCUMENTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Indent one level'),
            QCoreApplication.translate('ViewManager', 'Indent one level'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Tab')), 0,
            self.editorActGrp, 'vm_edit_indent_one_level')
        self.esm.setMapping(act, QsciScintilla.SCI_TAB)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Unindent one level'),
            QCoreApplication.translate('ViewManager', 'Unindent one level'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Shift+Tab')),
            0, self.editorActGrp, 'vm_edit_unindent_one_level')
        self.esm.setMapping(act, QsciScintilla.SCI_BACKTAB)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Extend selection left one character'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection left one character'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Shift+Left')),
            0, self.editorActGrp, 'vm_edit_extend_selection_left_char')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Shift+B')))
        self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection right one character'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection right one character'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Shift+Right')),
            0, self.editorActGrp, 'vm_edit_extend_selection_right_char')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Shift+F')))
        self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection up one line'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection up one line'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Shift+Up')),
            0, self.editorActGrp, 'vm_edit_extend_selection_up_line')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Shift+P')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEUPEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection down one line'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection down one line'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Shift+Down')),
            0, self.editorActGrp, 'vm_edit_extend_selection_down_line')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Shift+N')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEDOWNEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection left one word part'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection left one word part'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_left_word_part')
        if not isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Shift+Left')))
        self.esm.setMapping(act, QsciScintilla.SCI_WORDPARTLEFTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection right one word part'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection right one word part'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_right_word_part')
        if not isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Shift+Right')))
        self.esm.setMapping(act, QsciScintilla.SCI_WORDPARTRIGHTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Extend selection left one word'),
            QCoreApplication.translate(
                'ViewManager', 'Extend selection left one word'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_left_word')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Shift+Left')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Left')))
        self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Extend selection right one word'),
            QCoreApplication.translate(
                'ViewManager', 'Extend selection right one word'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_right_word')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Shift+Right')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Right')))
        self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection to first visible character in document'
                ' line'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection to first visible character in document'
                ' line'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_first_visible_char')
        if not isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Shift+Home')))
        self.esm.setMapping(act, QsciScintilla.SCI_VCHOMEEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Extend selection to end of document line'),
            QCoreApplication.translate(
                'ViewManager', 'Extend selection to end of document line'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_end_line')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Shift+E')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Shift+End')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEENDEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection up one paragraph'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection up one paragraph'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Shift+Up')),
            0, self.editorActGrp, 'vm_edit_extend_selection_up_para')
        self.esm.setMapping(act, QsciScintilla.SCI_PARAUPEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Extend selection down one paragraph'),
            QCoreApplication.translate(
                'ViewManager', 'Extend selection down one paragraph'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Shift+Down')),
            0,
            self.editorActGrp, 'vm_edit_extend_selection_down_para')
        self.esm.setMapping(act, QsciScintilla.SCI_PARADOWNEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection up one page'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection up one page'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Shift+PgUp')),
            0, self.editorActGrp, 'vm_edit_extend_selection_up_page')
        self.esm.setMapping(act, QsciScintilla.SCI_PAGEUPEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection down one page'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection down one page'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Shift+PgDown')),
            0, self.editorActGrp, 'vm_edit_extend_selection_down_page')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Shift+V')))
        self.esm.setMapping(act, QsciScintilla.SCI_PAGEDOWNEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Extend selection to start of document'),
            QCoreApplication.translate(
                'ViewManager', 'Extend selection to start of document'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_start_text')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Up')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Home')))
        self.esm.setMapping(act, QsciScintilla.SCI_DOCUMENTSTARTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Extend selection to end of document'),
            QCoreApplication.translate(
                'ViewManager', 'Extend selection to end of document'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_end_text')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Down')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+End')))
        self.esm.setMapping(act, QsciScintilla.SCI_DOCUMENTENDEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Delete previous character'),
            QCoreApplication.translate('ViewManager',
                                       'Delete previous character'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Backspace')),
            0, self.editorActGrp, 'vm_edit_delete_previous_char')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+H')))
        else:
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Shift+Backspace')))
        self.esm.setMapping(act, QsciScintilla.SCI_DELETEBACK)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Delete previous character if not at start of line'),
            QCoreApplication.translate(
                'ViewManager',
                'Delete previous character if not at start of line'),
            0, 0,
            self.editorActGrp, 'vm_edit_delet_previous_char_not_line_start')
        self.esm.setMapping(act, QsciScintilla.SCI_DELETEBACKNOTLINE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Delete current character'),
            QCoreApplication.translate('ViewManager',
                                       'Delete current character'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Del')), 0,
            self.editorActGrp, 'vm_edit_delete_current_char')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+D')))
        self.esm.setMapping(act, QsciScintilla.SCI_CLEAR)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Delete word to left'),
            QCoreApplication.translate('ViewManager', 'Delete word to left'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Backspace')),
            0, self.editorActGrp, 'vm_edit_delete_word_left')
        self.esm.setMapping(act, QsciScintilla.SCI_DELWORDLEFT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Delete word to right'),
            QCoreApplication.translate('ViewManager', 'Delete word to right'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Del')),
            0, self.editorActGrp, 'vm_edit_delete_word_right')
        self.esm.setMapping(act, QsciScintilla.SCI_DELWORDRIGHT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Delete line to left'),
            QCoreApplication.translate('ViewManager', 'Delete line to left'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Shift+Backspace')),
            0, self.editorActGrp, 'vm_edit_delete_line_left')
        self.esm.setMapping(act, QsciScintilla.SCI_DELLINELEFT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Delete line to right'),
            QCoreApplication.translate('ViewManager', 'Delete line to right'),
            0, 0,
            self.editorActGrp, 'vm_edit_delete_line_right')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+K')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Del')))
        self.esm.setMapping(act, QsciScintilla.SCI_DELLINERIGHT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Insert new line'),
            QCoreApplication.translate('ViewManager', 'Insert new line'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Return')),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Enter')),
            self.editorActGrp, 'vm_edit_insert_line')
        self.esm.setMapping(act, QsciScintilla.SCI_NEWLINE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Delete current line'),
            QCoreApplication.translate('ViewManager', 'Delete current line'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Shift+L')),
            0, self.editorActGrp, 'vm_edit_delete_current_line')
        self.esm.setMapping(act, QsciScintilla.SCI_LINEDELETE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Duplicate current line'),
            QCoreApplication.translate('ViewManager',
                                       'Duplicate current line'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+D')),
            0, self.editorActGrp, 'vm_edit_duplicate_current_line')
        self.esm.setMapping(act, QsciScintilla.SCI_LINEDUPLICATE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Swap current and previous lines'),
            QCoreApplication.translate(
                'ViewManager',
                'Swap current and previous lines'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+T')),
            0, self.editorActGrp, 'vm_edit_swap_current_previous_line')
        self.esm.setMapping(act, QsciScintilla.SCI_LINETRANSPOSE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Reverse selected lines'),
            QCoreApplication.translate('ViewManager',
                                       'Reverse selected lines'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Meta+Alt+R')),
            0, self.editorActGrp, 'vm_edit_reverse selected_lines')
        self.esm.setMapping(act, QsciScintilla.SCI_LINEREVERSE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Cut current line'),
            QCoreApplication.translate('ViewManager', 'Cut current line'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Shift+L')),
            0, self.editorActGrp, 'vm_edit_cut_current_line')
        self.esm.setMapping(act, QsciScintilla.SCI_LINECUT)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Copy current line'),
            QCoreApplication.translate('ViewManager', 'Copy current line'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Shift+T')),
            0, self.editorActGrp, 'vm_edit_copy_current_line')
        self.esm.setMapping(act, QsciScintilla.SCI_LINECOPY)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Toggle insert/overtype'),
            QCoreApplication.translate('ViewManager',
                                       'Toggle insert/overtype'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Ins')), 0,
            self.editorActGrp, 'vm_edit_toggle_insert_overtype')
        self.esm.setMapping(act, QsciScintilla.SCI_EDITTOGGLEOVERTYPE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Convert selection to lower case'),
            QCoreApplication.translate(
                'ViewManager',
                'Convert selection to lower case'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Shift+U')),
            0, self.editorActGrp, 'vm_edit_convert_selection_lower')
        self.esm.setMapping(act, QsciScintilla.SCI_LOWERCASE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Convert selection to upper case'),
            QCoreApplication.translate(
                'ViewManager',
                'Convert selection to upper case'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Shift+U')),
            0, self.editorActGrp, 'vm_edit_convert_selection_upper')
        self.esm.setMapping(act, QsciScintilla.SCI_UPPERCASE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Move to end of display line'),
            QCoreApplication.translate(
                'ViewManager', 'Move to end of display line'),
            0, 0,
            self.editorActGrp, 'vm_edit_move_end_displayed_line')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Right')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+End')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEENDDISPLAY)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection to end of display line'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend selection to end of display line'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_selection_end_displayed_line')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Right')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEENDDISPLAYEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Formfeed'),
            QCoreApplication.translate('ViewManager', 'Formfeed'),
            0, 0,
            self.editorActGrp, 'vm_edit_formfeed')
        self.esm.setMapping(act, QsciScintilla.SCI_FORMFEED)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate('ViewManager', 'Escape'),
            QCoreApplication.translate('ViewManager', 'Escape'),
            QKeySequence(QCoreApplication.translate('ViewManager', 'Esc')), 0,
            self.editorActGrp, 'vm_edit_escape')
        self.esm.setMapping(act, QsciScintilla.SCI_CANCEL)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection down one line'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection down one line'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Ctrl+Down')),
            0, self.editorActGrp, 'vm_edit_extend_rect_selection_down_line')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+N')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEDOWNRECTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection up one line'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection up one line'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Ctrl+Up')),
            0, self.editorActGrp, 'vm_edit_extend_rect_selection_up_line')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+P')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEUPRECTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection left one character'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection left one character'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Ctrl+Left')),
            0, self.editorActGrp, 'vm_edit_extend_rect_selection_left_char')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+B')))
        self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFTRECTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection right one character'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection right one character'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Ctrl+Right')),
            0, self.editorActGrp, 'vm_edit_extend_rect_selection_right_char')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+F')))
        self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHTRECTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection to first'
                ' visible character in document line'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection to first'
                ' visible character in document line'),
            0, 0,
            self.editorActGrp,
            'vm_edit_extend_rect_selection_first_visible_char')
        if not isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Shift+Home')))
        self.esm.setMapping(act, QsciScintilla.SCI_VCHOMERECTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection to end of document line'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection to end of document line'),
            0, 0,
            self.editorActGrp, 'vm_edit_extend_rect_selection_end_line')
        if isMacPlatform():
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+E')))
        else:
            act.setShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Alt+Shift+End')))
        self.esm.setMapping(act, QsciScintilla.SCI_LINEENDRECTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection up one page'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection up one page'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Shift+PgUp')),
            0, self.editorActGrp, 'vm_edit_extend_rect_selection_up_page')
        self.esm.setMapping(act, QsciScintilla.SCI_PAGEUPRECTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection down one page'),
            QCoreApplication.translate(
                'ViewManager',
                'Extend rectangular selection down one page'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Alt+Shift+PgDown')),
            0, self.editorActGrp, 'vm_edit_extend_rect_selection_down_page')
        if isMacPlatform():
            act.setAlternateShortcut(QKeySequence(
                QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+V')))
        self.esm.setMapping(act, QsciScintilla.SCI_PAGEDOWNRECTEXTEND)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Duplicate current selection'),
            QCoreApplication.translate(
                'ViewManager',
                'Duplicate current selection'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Shift+D')),
            0, self.editorActGrp, 'vm_edit_duplicate_current_selection')
        self.esm.setMapping(act, QsciScintilla.SCI_SELECTIONDUPLICATE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_SCROLLTOSTART"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Scroll to start of document'),
                QCoreApplication.translate(
                    'ViewManager', 'Scroll to start of document'),
                0, 0,
                self.editorActGrp, 'vm_edit_scroll_start_text')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager', 'Home')))
            self.esm.setMapping(act, QsciScintilla.SCI_SCROLLTOSTART)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_SCROLLTOEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Scroll to end of document'),
                QCoreApplication.translate(
                    'ViewManager', 'Scroll to end of document'),
                0, 0,
                self.editorActGrp, 'vm_edit_scroll_end_text')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager', 'End')))
            self.esm.setMapping(act, QsciScintilla.SCI_SCROLLTOEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_VERTICALCENTRECARET"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Scroll vertically to center current line'),
                QCoreApplication.translate(
                    'ViewManager', 'Scroll vertically to center current line'),
                0, 0,
                self.editorActGrp, 'vm_edit_scroll_vertically_center')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager', 'Meta+L')))
            self.esm.setMapping(act, QsciScintilla.SCI_VERTICALCENTRECARET)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_WORDRIGHTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Move to end of next word'),
                QCoreApplication.translate(
                    'ViewManager', 'Move to end of next word'),
                0, 0,
                self.editorActGrp, 'vm_edit_move_end_next_word')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager', 'Alt+Right')))
            self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_WORDRIGHTENDEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Extend selection to end of next word'),
                QCoreApplication.translate(
                    'ViewManager', 'Extend selection to end of next word'),
                0, 0,
                self.editorActGrp, 'vm_edit_select_end_next_word')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager',
                                               'Alt+Shift+Right')))
            self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHTENDEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_WORDLEFTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Move to end of previous word'),
                QCoreApplication.translate(
                    'ViewManager', 'Move to end of previous word'),
                0, 0,
                self.editorActGrp, 'vm_edit_move_end_previous_word')
            self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_WORDLEFTENDEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Extend selection to end of previous word'),
                QCoreApplication.translate(
                    'ViewManager', 'Extend selection to end of previous word'),
                0, 0,
                self.editorActGrp, 'vm_edit_select_end_previous_word')
            self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFTENDEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_HOME"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Move to start of document line'),
                QCoreApplication.translate(
                    'ViewManager', 'Move to start of document line'),
                0, 0,
                self.editorActGrp, 'vm_edit_move_start_document_line')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager', 'Meta+A')))
            self.esm.setMapping(act, QsciScintilla.SCI_HOME)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_HOMEEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to start of document line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to start of document line'),
                0, 0,
                self.editorActGrp,
                'vm_edit_extend_selection_start_document_line')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager', 'Meta+Shift+A')))
            self.esm.setMapping(act, QsciScintilla.SCI_HOME)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_HOMERECTEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend rectangular selection to start of document line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend rectangular selection to start of document line'),
                0, 0,
                self.editorActGrp, 'vm_edit_select_rect_start_line')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager',
                                               'Meta+Alt+Shift+A')))
            self.esm.setMapping(act, QsciScintilla.SCI_HOMERECTEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_HOMEDISPLAYEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to start of display line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to start of display line'),
                0, 0,
                self.editorActGrp,
                'vm_edit_extend_selection_start_display_line')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager',
                                               'Ctrl+Shift+Left')))
            self.esm.setMapping(act, QsciScintilla.SCI_HOMEDISPLAYEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_HOMEWRAP"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Move to start of display or document line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Move to start of display or document line'),
                0, 0,
                self.editorActGrp, 'vm_edit_move_start_display_document_line')
            self.esm.setMapping(act, QsciScintilla.SCI_HOMEWRAP)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_HOMEWRAPEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to start of display or document line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to start of display or document line'),
                0, 0,
                self.editorActGrp,
                'vm_edit_extend_selection_start_display_document_line')
            self.esm.setMapping(act, QsciScintilla.SCI_HOMEWRAPEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_VCHOMEWRAP"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Move to first visible character in display'
                    ' or document line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Move to first visible character in display'
                    ' or document line'),
                0, 0,
                self.editorActGrp,
                'vm_edit_move_first_visible_char_document_line')
            self.esm.setMapping(act, QsciScintilla.SCI_VCHOMEWRAP)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_VCHOMEWRAPEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to first visible character in'
                    ' display or document line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to first visible character in'
                    ' display or document line'),
                0, 0,
                self.editorActGrp,
                'vm_edit_extend_selection_first_visible_char_document_line')
            self.esm.setMapping(act, QsciScintilla.SCI_VCHOMEWRAPEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_LINEENDWRAP"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Move to end of display or document line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Move to end of display or document line'),
                0, 0,
                self.editorActGrp, 'vm_edit_end_start_display_document_line')
            self.esm.setMapping(act, QsciScintilla.SCI_LINEENDWRAP)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_LINEENDWRAPEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to end of display or document line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Extend selection to end of display or document line'),
                0, 0,
                self.editorActGrp,
                'vm_edit_extend_selection_end_display_document_line')
            self.esm.setMapping(act, QsciScintilla.SCI_LINEENDWRAPEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_STUTTEREDPAGEUP"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Stuttered move up one page'),
                QCoreApplication.translate(
                    'ViewManager', 'Stuttered move up one page'),
                0, 0,
                self.editorActGrp, 'vm_edit_stuttered_move_up_page')
            self.esm.setMapping(act, QsciScintilla.SCI_STUTTEREDPAGEUP)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_STUTTEREDPAGEUPEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Stuttered extend selection up one page'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Stuttered extend selection up one page'),
                0, 0,
                self.editorActGrp,
                'vm_edit_stuttered_extend_selection_up_page')
            self.esm.setMapping(act, QsciScintilla.SCI_STUTTEREDPAGEUPEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_STUTTEREDPAGEDOWN"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager', 'Stuttered move down one page'),
                QCoreApplication.translate(
                    'ViewManager', 'Stuttered move down one page'),
                0, 0,
                self.editorActGrp, 'vm_edit_stuttered_move_down_page')
            self.esm.setMapping(act, QsciScintilla.SCI_STUTTEREDPAGEDOWN)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_STUTTEREDPAGEDOWNEXTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Stuttered extend selection down one page'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Stuttered extend selection down one page'),
                0, 0,
                self.editorActGrp,
                'vm_edit_stuttered_extend_selection_down_page')
            self.esm.setMapping(act, QsciScintilla.SCI_STUTTEREDPAGEDOWNEXTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_DELWORDRIGHTEND"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Delete right to end of next word'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Delete right to end of next word'),
                0, 0,
                self.editorActGrp, 'vm_edit_delete_right_end_next_word')
            if isMacPlatform():
                act.setShortcut(QKeySequence(
                    QCoreApplication.translate('ViewManager', 'Alt+Del')))
            self.esm.setMapping(act, QsciScintilla.SCI_DELWORDRIGHTEND)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_MOVESELECTEDLINESUP"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Move selected lines up one line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Move selected lines up one line'),
                0, 0,
                self.editorActGrp, 'vm_edit_move_selection_up_one_line')
            self.esm.setMapping(act, QsciScintilla.SCI_MOVESELECTEDLINESUP)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        if hasattr(QsciScintilla, "SCI_MOVESELECTEDLINESDOWN"):
            act = EricAction(
                QCoreApplication.translate(
                    'ViewManager',
                    'Move selected lines down one line'),
                QCoreApplication.translate(
                    'ViewManager',
                    'Move selected lines down one line'),
                0, 0,
                self.editorActGrp, 'vm_edit_move_selection_down_one_line')
            self.esm.setMapping(act, QsciScintilla.SCI_MOVESELECTEDLINESDOWN)
            act.triggered.connect(self.esm.map)
            self.editActions.append(act)
        
        act = EricAction(
            QCoreApplication.translate(
                'ViewManager',
                'Duplicate current selection'),
            QCoreApplication.translate(
                'ViewManager',
                'Duplicate current selection'),
            QKeySequence(QCoreApplication.translate('ViewManager',
                                                    'Ctrl+Shift+D')),
            0, self.editorActGrp, 'vm_edit_duplicate_current_selection')
        self.esm.setMapping(act, QsciScintilla.SCI_SELECTIONDUPLICATE)
        act.triggered.connect(self.esm.map)
        self.editActions.append(act)
        
        self.__textEdit.addActions(self.editorActGrp.actions())
    
    def __createSearchActions(self):
        """
        Private method defining the user interface actions for the search
            commands.
        """
        self.searchAct = EricAction(
            QCoreApplication.translate('ViewManager', 'Search'),
            UI.PixmapCache.getIcon("find"),
            QCoreApplication.translate('ViewManager', '&Search...'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Ctrl+F", "Search|Search")),
            0,
            self, 'vm_search')
        self.searchAct.setStatusTip(
            QCoreApplication.translate('ViewManager', 'Search for a text'))
        self.searchAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Search</b>"""
            """<p>Search for some text in the current editor. A"""
            """ dialog is shown to enter the searchtext and options"""
            """ for the search.</p>"""
        ))
        self.searchAct.triggered.connect(self.showSearchWidget)
        self.searchActions.append(self.searchAct)
        
        self.searchNextAct = EricAction(
            QCoreApplication.translate('ViewManager', 'Search next'),
            UI.PixmapCache.getIcon("findNext"),
            QCoreApplication.translate('ViewManager', 'Search &next'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "F3", "Search|Search next")),
            0,
            self, 'vm_search_next')
        self.searchNextAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Search next occurrence of text'))
        self.searchNextAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Search next</b>"""
            """<p>Search the next occurrence of some text in the current"""
            """ editor. The previously entered searchtext and options are"""
            """ reused.</p>"""
        ))
        self.searchNextAct.triggered.connect(self.__searchNext)
        self.searchActions.append(self.searchNextAct)
        
        self.searchPrevAct = EricAction(
            QCoreApplication.translate('ViewManager', 'Search previous'),
            UI.PixmapCache.getIcon("findPrev"),
            QCoreApplication.translate('ViewManager', 'Search &previous'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Shift+F3", "Search|Search previous")),
            0,
            self, 'vm_search_previous')
        self.searchPrevAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Search previous occurrence of text'))
        self.searchPrevAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Search previous</b>"""
            """<p>Search the previous occurrence of some text in the"""
            """ current editor. The previously entered searchtext and"""
            """ options are reused.</p>"""
        ))
        self.searchPrevAct.triggered.connect(self.__searchPrev)
        self.searchActions.append(self.searchPrevAct)
        
        self.searchClearMarkersAct = EricAction(
            QCoreApplication.translate('ViewManager',
                                       'Clear search markers'),
            UI.PixmapCache.getIcon("findClear"),
            QCoreApplication.translate('ViewManager', 'Clear search markers'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Ctrl+3", "Search|Clear search markers")),
            0,
            self, 'vm_clear_search_markers')
        self.searchClearMarkersAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Clear all displayed search markers'))
        self.searchClearMarkersAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Clear search markers</b>"""
            """<p>Clear all displayed search markers.</p>"""
        ))
        self.searchClearMarkersAct.triggered.connect(
            self.__searchClearMarkers)
        self.searchActions.append(self.searchClearMarkersAct)
        
        self.replaceAct = EricAction(
            QCoreApplication.translate('ViewManager', 'Replace'),
            QCoreApplication.translate('ViewManager', '&Replace...'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Ctrl+R", "Search|Replace")),
            0,
            self, 'vm_search_replace')
        self.replaceAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Replace some text'))
        self.replaceAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Replace</b>"""
            """<p>Search for some text in the current editor and replace"""
            """ it. A dialog is shown to enter the searchtext, the"""
            """ replacement text and options for the search and replace.</p>"""
        ))
        self.replaceAct.triggered.connect(self.showReplaceWidget)
        self.searchActions.append(self.replaceAct)
        
        self.replaceAndSearchAct = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Replace and Search'),
            UI.PixmapCache.getIcon("editReplaceSearch"),
            QCoreApplication.translate(
                'ViewManager', 'Replace and Search'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Meta+R", "Search|Replace and Search")),
            0,
            self, 'vm_replace_search')
        self.replaceAndSearchAct.setStatusTip(QCoreApplication.translate(
            'ViewManager',
            'Replace the found text and search the next occurrence'))
        self.replaceAndSearchAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Replace and Search</b>"""
            """<p>Replace the found occurrence of text in the current"""
            """ editor and search for the next one. The previously entered"""
            """ search text and options are reused.</p>"""
        ))
        self.replaceAndSearchAct.triggered.connect(
            self.__replaceWidget.replaceSearch)
        self.searchActions.append(self.replaceAndSearchAct)
        
        self.replaceSelectionAct = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Replace Occurrence'),
            UI.PixmapCache.getIcon("editReplace"),
            QCoreApplication.translate(
                'ViewManager', 'Replace Occurrence'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Ctrl+Meta+R", "Search|Replace Occurrence")),
            0,
            self, 'vm_replace_occurrence')
        self.replaceSelectionAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Replace the found text'))
        self.replaceSelectionAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Replace Occurrence</b>"""
            """<p>Replace the found occurrence of the search text in the"""
            """ current editor.</p>"""
        ))
        self.replaceSelectionAct.triggered.connect(
            self.__replaceWidget.replace)
        self.searchActions.append(self.replaceSelectionAct)
        
        self.replaceAllAct = EricAction(
            QCoreApplication.translate(
                'ViewManager', 'Replace All'),
            UI.PixmapCache.getIcon("editReplaceAll"),
            QCoreApplication.translate(
                'ViewManager', 'Replace All'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Shift+Meta+R", "Search|Replace All")),
            0,
            self, 'vm_replace_all')
        self.replaceAllAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Replace search text occurrences'))
        self.replaceAllAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Replace All</b>"""
            """<p>Replace all occurrences of the search text in the current"""
            """ editor.</p>"""
        ))
        self.replaceAllAct.triggered.connect(
            self.__replaceWidget.replaceAll)
        self.searchActions.append(self.replaceAllAct)
    
    def __createViewActions(self):
        """
        Private method to create the View actions.
        """
        self.zoomInAct = EricAction(
            QCoreApplication.translate('ViewManager', 'Zoom in'),
            UI.PixmapCache.getIcon("zoomIn"),
            QCoreApplication.translate('ViewManager', 'Zoom &in'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Ctrl++", "View|Zoom in")),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Zoom In", "View|Zoom in")),
            self, 'vm_view_zoom_in')
        self.zoomInAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Zoom in on the text'))
        self.zoomInAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Zoom in</b>"""
            """<p>Zoom in on the text. This makes the text bigger.</p>"""
        ))
        self.zoomInAct.triggered.connect(self.__zoomIn)
        self.viewActions.append(self.zoomInAct)
        
        self.zoomOutAct = EricAction(
            QCoreApplication.translate('ViewManager', 'Zoom out'),
            UI.PixmapCache.getIcon("zoomOut"),
            QCoreApplication.translate('ViewManager', 'Zoom &out'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Ctrl+-", "View|Zoom out")),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Zoom Out", "View|Zoom out")),
            self, 'vm_view_zoom_out')
        self.zoomOutAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Zoom out on the text'))
        self.zoomOutAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Zoom out</b>"""
            """<p>Zoom out on the text. This makes the text smaller.</p>"""
        ))
        self.zoomOutAct.triggered.connect(self.__zoomOut)
        self.viewActions.append(self.zoomOutAct)
        
        self.zoomResetAct = EricAction(
            QCoreApplication.translate('ViewManager', 'Zoom reset'),
            UI.PixmapCache.getIcon("zoomReset"),
            QCoreApplication.translate('ViewManager', 'Zoom &reset'),
            QKeySequence(QCoreApplication.translate(
                'ViewManager', "Ctrl+0", "View|Zoom reset")),
            0,
            self, 'vm_view_zoom_reset')
        self.zoomResetAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Reset the zoom of the text'))
        self.zoomResetAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Zoom reset</b>"""
            """<p>Reset the zoom of the text. """
            """This sets the zoom factor to 100%.</p>"""
        ))
        self.zoomResetAct.triggered.connect(self.__zoomReset)
        self.viewActions.append(self.zoomResetAct)
        
        self.zoomToAct = EricAction(
            QCoreApplication.translate('ViewManager', 'Zoom'),
            UI.PixmapCache.getIcon("zoomTo"),
            QCoreApplication.translate('ViewManager', '&Zoom'),
            0, 0,
            self, 'vm_view_zoom')
        self.zoomToAct.setStatusTip(QCoreApplication.translate(
            'ViewManager', 'Zoom the text'))
        self.zoomToAct.setWhatsThis(QCoreApplication.translate(
            'ViewManager',
            """<b>Zoom</b>"""
            """<p>Zoom the text. This opens a dialog where the"""
            """ desired size can be entered.</p>"""
        ))
        self.zoomToAct.triggered.connect(self.__zoom)
        self.viewActions.append(self.zoomToAct)
    
    def __createHelpActions(self):
        """
        Private method to create the Help actions.
        """
        self.aboutAct = EricAction(
            self.tr('About'),
            self.tr('&About'),
            0, 0, self, 'about_eric')
        self.aboutAct.setStatusTip(self.tr(
            'Display information about this software'))
        self.aboutAct.setWhatsThis(self.tr(
            """<b>About</b>"""
            """<p>Display some information about this software.</p>"""))
        self.aboutAct.triggered.connect(self.__about)
        self.helpActions.append(self.aboutAct)
        
        self.aboutQtAct = EricAction(
            self.tr('About Qt'),
            self.tr('About &Qt'),
            0, 0, self, 'about_qt')
        self.aboutQtAct.setStatusTip(
            self.tr('Display information about the Qt toolkit'))
        self.aboutQtAct.setWhatsThis(self.tr(
            """<b>About Qt</b>"""
            """<p>Display some information about the Qt toolkit.</p>"""
        ))
        self.aboutQtAct.triggered.connect(self.__aboutQt)
        self.helpActions.append(self.aboutQtAct)
        
        self.whatsThisAct = EricAction(
            self.tr('What\'s This?'),
            UI.PixmapCache.getIcon("whatsThis"),
            self.tr('&What\'s This?'),
            QKeySequence(self.tr("Shift+F1", "Help|What's This?'")),
            0, self, 'help_help_whats_this')
        self.whatsThisAct.setStatusTip(self.tr('Context sensitive help'))
        self.whatsThisAct.setWhatsThis(self.tr(
            """<b>Display context sensitive help</b>"""
            """<p>In What's This? mode, the mouse cursor shows an arrow"""
            """ with a question mark, and you can click on the interface"""
            """ elements to get a short description of what they do and"""
            """ how to use them. In dialogs, this feature can be"""
            """ accessed using the context help button in the titlebar."""
            """</p>"""
        ))
        self.whatsThisAct.triggered.connect(self.__whatsThis)
        self.helpActions.append(self.whatsThisAct)
    
    def __createConfigActions(self):
        """
        Private method to create the Settings actions.
        """
        self.prefAct = EricAction(
            self.tr('Preferences'),
            UI.PixmapCache.getIcon("configure"),
            self.tr('&Preferences...'),
            0, 0, self, 'hexEditor_settings_preferences')
        self.prefAct.setStatusTip(self.tr(
            'Set the prefered configuration'))
        self.prefAct.setWhatsThis(self.tr(
            """<b>Preferences</b>"""
            """<p>Set the configuration items of the application"""
            """ with your prefered values.</p>"""
        ))
        self.prefAct.triggered.connect(self.__showPreferences)
        self.prefAct.setMenuRole(QAction.MenuRole.PreferencesRole)
        self.configActions.append(self.prefAct)
    
    def __createMenus(self):
        """
        Private method to create the menus of the menu bar.
        """
        self.fileMenu = self.menuBar().addMenu(self.tr("&File"))
        self.fileMenu.addAction(self.newAct)
        self.fileMenu.addAction(self.openAct)
        self.fileMenu.addAction(self.saveAct)
        self.fileMenu.addAction(self.saveAsAct)
        self.fileMenu.addAction(self.saveCopyAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.printPreviewAct)
        self.fileMenu.addAction(self.printAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.closeAct)
        
        self.editMenu = self.menuBar().addMenu(self.tr("&Edit"))
        self.editMenu.addAction(self.undoAct)
        self.editMenu.addAction(self.redoAct)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.cutAct)
        self.editMenu.addAction(self.copyAct)
        self.editMenu.addAction(self.pasteAct)
        self.editMenu.addAction(self.deleteAct)
        self.editMenu.addSeparator()
        
        self.searchMenu = self.menuBar().addMenu(self.tr("&Search"))
        self.searchMenu.addAction(self.searchAct)
        self.searchMenu.addAction(self.searchNextAct)
        self.searchMenu.addAction(self.searchPrevAct)
        self.searchMenu.addAction(self.searchClearMarkersAct)
        self.searchMenu.addAction(self.replaceAct)
        self.searchMenu.addAction(self.replaceAndSearchAct)
        self.searchMenu.addAction(self.replaceSelectionAct)
        self.searchMenu.addAction(self.replaceAllAct)
        
        self.viewMenu = self.menuBar().addMenu(self.tr("&View"))
        self.viewMenu.addAction(self.zoomInAct)
        self.viewMenu.addAction(self.zoomOutAct)
        self.viewMenu.addAction(self.zoomResetAct)
        self.viewMenu.addAction(self.zoomToAct)
        
        self.settingsMenu = self.menuBar().addMenu(self.tr("Se&ttings"))
        self.settingsMenu.addAction(self.prefAct)
       
        self.menuBar().addSeparator()
        
        self.helpMenu = self.menuBar().addMenu(self.tr("&Help"))
        self.helpMenu.addAction(self.aboutAct)
        self.helpMenu.addAction(self.aboutQtAct)
        self.helpMenu.addSeparator()
        self.helpMenu.addAction(self.whatsThisAct)
        
        self.__initContextMenu()
    
    def __createToolBars(self):
        """
        Private method to create the various toolbars.
        """
        filetb = self.addToolBar(self.tr("File"))
        filetb.setIconSize(UI.Config.ToolBarIconSize)
        filetb.addAction(self.newAct)
        filetb.addAction(self.openAct)
        filetb.addAction(self.saveAct)
        filetb.addAction(self.saveAsAct)
        filetb.addAction(self.saveCopyAct)
        filetb.addSeparator()
        filetb.addAction(self.printPreviewAct)
        filetb.addAction(self.printAct)
        filetb.addSeparator()
        filetb.addAction(self.closeAct)
        
        edittb = self.addToolBar(self.tr("Edit"))
        edittb.setIconSize(UI.Config.ToolBarIconSize)
        edittb.addAction(self.undoAct)
        edittb.addAction(self.redoAct)
        edittb.addSeparator()
        edittb.addAction(self.cutAct)
        edittb.addAction(self.copyAct)
        edittb.addAction(self.pasteAct)
        edittb.addAction(self.deleteAct)
        
        findtb = self.addToolBar(self.tr("Search"))
        findtb.setIconSize(UI.Config.ToolBarIconSize)
        findtb.addAction(self.searchAct)
        findtb.addAction(self.searchNextAct)
        findtb.addAction(self.searchPrevAct)
        findtb.addAction(self.searchClearMarkersAct)
        
        viewtb = self.addToolBar(self.tr("View"))
        viewtb.setIconSize(UI.Config.ToolBarIconSize)
        viewtb.addAction(self.zoomInAct)
        viewtb.addAction(self.zoomOutAct)
        viewtb.addAction(self.zoomResetAct)
        viewtb.addAction(self.zoomToAct)
        
        settingstb = self.addToolBar(self.tr("Settings"))
        settingstb.setIconSize(UI.Config.ToolBarIconSize)
        settingstb.addAction(self.prefAct)
        
        helptb = self.addToolBar(self.tr("Help"))
        helptb.setIconSize(UI.Config.ToolBarIconSize)
        helptb.addAction(self.whatsThisAct)
    
    def __createStatusBar(self):
        """
        Private method to initialize the status bar.
        """
        self.__statusBar = self.statusBar()
        self.__statusBar.setSizeGripEnabled(True)

        self.sbLanguage = EricClickableLabel(self.__statusBar)
        self.__statusBar.addPermanentWidget(self.sbLanguage)
        self.sbLanguage.setWhatsThis(self.tr(
            """<p>This part of the status bar displays the"""
            """ editor language.</p>"""
        ))
        self.sbLanguage.clicked.connect(self.__showLanguagesMenu)

        self.sbWritable = QLabel(self.__statusBar)
        self.__statusBar.addPermanentWidget(self.sbWritable)
        self.sbWritable.setWhatsThis(self.tr(
            """<p>This part of the status bar displays an indication of the"""
            """ editors files writability.</p>"""
        ))

        self.sbLine = QLabel(self.__statusBar)
        self.__statusBar.addPermanentWidget(self.sbLine)
        self.sbLine.setWhatsThis(self.tr(
            """<p>This part of the status bar displays the line number of"""
            """ the editor.</p>"""
        ))

        self.sbPos = QLabel(self.__statusBar)
        self.__statusBar.addPermanentWidget(self.sbPos)
        self.sbPos.setWhatsThis(self.tr(
            """<p>This part of the status bar displays the cursor position"""
            """ of the editor.</p>"""
        ))
        
        self.sbZoom = EricZoomWidget(
            UI.PixmapCache.getPixmap("zoomOut"),
            UI.PixmapCache.getPixmap("zoomIn"),
            UI.PixmapCache.getPixmap("zoomReset"),
            self.__statusBar)
        self.__statusBar.addPermanentWidget(self.sbZoom)
        self.sbZoom.setWhatsThis(self.tr(
            """<p>This part of the status bar allows zooming the editor."""
            """</p>"""
        ))
        self.sbZoom.valueChanged.connect(self.__zoomTo)
        
        self.__statusBar.showMessage(self.tr("Ready"))
    
    def __showPreferences(self):
        """
        Private slot to set the preferences.
        """
        from Preferences.ConfigurationDialog import (
            ConfigurationDialog, ConfigurationMode
        )
        dlg = ConfigurationDialog(
            None, 'Configuration', True, fromEric=True,
            displayMode=ConfigurationMode.EDITORMODE)
        dlg.preferencesChanged.connect(self.__preferencesChanged)
        dlg.show()
        dlg.showConfigurationPageByName("interfacePage")
        dlg.exec()
        QCoreApplication.processEvents()
        if dlg.result() == QDialog.DialogCode.Accepted:
            dlg.setPreferences()
            Preferences.syncPreferences()
            self.__preferencesChanged()
    
    @pyqtSlot()
    def __preferencesChanged(self):
        """
        Private slot to handle a configuration change.
        """
        self.__loadConfiguration()
        
        self.__markOccurrencesTimer.setInterval(
            Preferences.getEditor("MarkOccurrencesTimeout"))
    
    @pyqtSlot()
    def __loadConfiguration(self):
        """
        Private slot to load the configuration.
        """
        self.__setTextDisplay()
        self.__setMargins()
        self.__setEolMode()
    
    def __readSettings(self):
        """
        Private method to read the settings remembered last time.
        """
        settings = Preferences.getSettings()
        pos = settings.value("MiniEditor/Position", QPoint(0, 0))
        size = settings.value("MiniEditor/Size", QSize(800, 600))
        self.resize(size)
        self.move(pos)
    
    def __writeSettings(self):
        """
        Private method to write the settings for reuse.
        """
        settings = Preferences.getSettings()
        settings.setValue("MiniEditor/Position", self.pos())
        settings.setValue("MiniEditor/Size", self.size())
    
    def __maybeSave(self):
        """
        Private method to ask the user to save the file, if it was modified.
        
        @return flag indicating, if it is ok to continue (boolean)
        """
        if self.__textEdit.isModified():
            ret = EricMessageBox.okToClearData(
                self,
                self.tr("eric Mini Editor"),
                self.tr("The document has unsaved changes."),
                self.__save)
            return ret
        return True
    
    def __loadFile(self, fileName, filetype=None):
        """
        Private method to load the given file.
        
        @param fileName name of the file to load (string)
        @param filetype type of the source file (string)
        """
        self.__loadEditorConfig(fileName=fileName)
        
        try:
            with EricOverrideCursor():
                encoding = self.__getEditorConfig("DefaultEncoding",
                                                  nodefault=True)
                if encoding:
                    txt, self.encoding = Utilities.readEncodedFileWithEncoding(
                        fileName, encoding)
                else:
                    txt, self.encoding = Utilities.readEncodedFile(fileName)
        except (UnicodeDecodeError, OSError) as why:
            EricMessageBox.critical(
                self, self.tr('Open File'),
                self.tr('<p>The file <b>{0}</b> could not be opened.</p>'
                        '<p>Reason: {1}</p>')
                .format(fileName, str(why)))
            return
        
        with EricOverrideCursor():
            self.__textEdit.setText(txt)
            
            if filetype is None:
                self.filetype = ""
            else:
                self.filetype = filetype
            self.__setCurrentFile(fileName)
            
            self.__textEdit.setModified(False)
            self.setWindowModified(False)
            
            self.__convertTabs()
            
            eolMode = self.__getEditorConfig("EOLMode", nodefault=True)
            if eolMode is None:
                fileEol = self.__textEdit.detectEolString(txt)
                self.__textEdit.setEolModeByEolString(fileEol)
            else:
                self.__textEdit.convertEols(eolMode)
        
        self.__statusBar.showMessage(self.tr("File loaded"), 2000)
    
    def __convertTabs(self):
        """
        Private slot to convert tabulators to spaces.
        """
        if (
            (not self.__getEditorConfig("TabForIndentation")) and
            Preferences.getEditor("ConvertTabsOnLoad") and
            not (self.lexer_ and
                 self.lexer_.alwaysKeepTabs())
        ):
            txt = self.__textEdit.text()
            txtExpanded = txt.expandtabs(self.__getEditorConfig("TabWidth"))
            if txtExpanded != txt:
                self.__textEdit.beginUndoAction()
                self.__textEdit.setText(txt)
                self.__textEdit.endUndoAction()
                
                self.__textEdit.setModified(True)
                self.setWindowModified(True)

    def __saveFile(self, fileName):
        """
        Private method to save to the given file.
        
        @param fileName name of the file to save to
        @type str
        @return flag indicating success
        @rtype bool
        """
        res = self.__writeFile(fileName)
        
        if res:
            self.editorSaved.emit()
            self.__setCurrentFile(fileName)
        
        self.__checkActions()
        
        return res
    
    def __writeFile(self, fileName):
        """
        Private method to write the current editor text to a file.
        
        @param fileName name of the file to be written to
        @type str
        @return flag indicating success
        @rtype bool
        """
        config = self.__loadEditorConfigObject(fileName)
        
        eol = self.__getEditorConfig("EOLMode", nodefault=True, config=config)
        if eol is not None:
            self.__textEdit.convertEols(eol)
        
        if self.__getEditorConfig("StripTrailingWhitespace", config=config):
            self.__textEdit.removeTrailingWhitespace()
        
        txt = self.__textEdit.text()
        
        if self.__getEditorConfig("InsertFinalNewline", config=config):
            eol = self.__textEdit.getLineSeparator()
            if eol:
                if len(txt) >= len(eol):
                    if txt[-len(eol):] != eol:
                        txt += eol
                else:
                    txt += eol
        
        # now write text to the file
        try:
            with EricOverrideCursor():
                editorConfigEncoding = self.__getEditorConfig(
                    "DefaultEncoding", nodefault=True, config=config)
                self.encoding = Utilities.writeEncodedFile(
                    fileName, txt, self.encoding,
                    forcedEncoding=editorConfigEncoding)
        except (OSError, Utilities.CodingError, UnicodeError) as why:
            EricMessageBox.critical(
                self, self.tr('Save File'),
                self.tr('<p>The file <b>{0}</b> could not be saved.<br/>'
                        'Reason: {1}</p>')
                .format(fileName, str(why)))
            return False
        
        self.__statusBar.showMessage(self.tr("File saved"), 2000)
        
        return True
    
    def setWindowModified(self, modified):
        """
        Public method to set the window modification status.
        
        @param modified flag indicating the modification status
        @type bool
        """
        if "[*]" not in self.windowTitle():
            self.setWindowTitle(self.tr("[*] - {0}")
                                .format(self.tr("Mini Editor")))
        super().setWindowModified(modified)
        
    def __setCurrentFile(self, fileName):
        """
        Private method to register the file name of the current file.
        
        @param fileName name of the file to register (string)
        """
        self.__curFile = fileName
        
        shownName = (
            self.tr("Untitled")
            if not self.__curFile else
            self.__strippedName(self.__curFile)
        )
        
        self.setWindowTitle(self.tr("{0}[*] - {1}")
                            .format(shownName, self.tr("Mini Editor")))
        
        self.__textEdit.setModified(False)
        self.setWindowModified(False)
        
        self.setLanguage(self.__bindName(self.__textEdit.text(0)))
        
        self.__loadEditorConfig()

    def getFileName(self):
        """
        Public method to return the name of the file being displayed.
        
        @return filename of the displayed file (string)
        """
        return self.__curFile
    
    def __strippedName(self, fullFileName):
        """
        Private method to return the filename part of the given path.
        
        @param fullFileName full pathname of the given file (string)
        @return filename part (string)
        """
        return QFileInfo(fullFileName).fileName()

    def __modificationChanged(self, m):
        """
        Private slot to handle the modificationChanged signal.
        
        @param m modification status
        """
        self.setWindowModified(m)
        self.__checkActions()
    
    def __cursorPositionChanged(self, line, pos):
        """
        Private slot to handle the cursorPositionChanged signal.
        
        @param line line number of the cursor
        @param pos position in line of the cursor
        """
        lang = self.getLanguage()
        self.__setSbFile(line + 1, pos, lang)
        
        if Preferences.getEditor("MarkOccurrencesEnabled"):
            self.__markOccurrencesTimer.stop()
            self.__markOccurrencesTimer.start()
        
        if self.__lastLine != line:
            self.cursorLineChanged.emit(line)
            self.__lastLine = line
    
    def __undo(self):
        """
        Private method to undo the last recorded change.
        """
        self.__textEdit.undo()
        self.__checkActions()
    
    def __redo(self):
        """
        Private method to redo the last recorded change.
        """
        self.__textEdit.redo()
        self.__checkActions()
    
    def __selectAll(self):
        """
        Private slot handling the select all context menu action.
        """
        self.__textEdit.selectAll(True)
    
    def __deselectAll(self):
        """
        Private slot handling the deselect all context menu action.
        """
        self.__textEdit.selectAll(False)
    
    def __setMargins(self):
        """
        Private method to configure the margins.
        """
        # set the settings for all margins
        self.__textEdit.setMarginsFont(
            Preferences.getEditorOtherFonts("MarginsFont"))
        self.__textEdit.setMarginsForegroundColor(
            Preferences.getEditorColour("MarginsForeground"))
        self.__textEdit.setMarginsBackgroundColor(
            Preferences.getEditorColour("MarginsBackground"))
        
        # set margin 0 settings
        linenoMargin = Preferences.getEditor("LinenoMargin")
        self.__textEdit.setMarginLineNumbers(0, linenoMargin)
        if linenoMargin:
            self.__resizeLinenoMargin()
        else:
            self.__textEdit.setMarginWidth(0, 16)
        
        # set margin 1 settings
        self.__textEdit.setMarginWidth(1, 0)
        
        # set margin 2 settings
        self.__textEdit.setMarginWidth(2, 16)
        if Preferences.getEditor("FoldingMargin"):
            folding = Preferences.getEditor("FoldingStyle")
            self.__textEdit.setFolding(folding)
            self.__textEdit.setFoldMarginColors(
                Preferences.getEditorColour("FoldmarginBackground"),
                Preferences.getEditorColour("FoldmarginBackground"))
            self.__textEdit.setFoldMarkersColors(
                Preferences.getEditorColour("FoldMarkersForeground"),
                Preferences.getEditorColour("FoldMarkersBackground"))
        else:
            self.__textEdit.setFolding(
                QsciScintilla.FoldStyle.NoFoldStyle.value)
    
    def __resizeLinenoMargin(self):
        """
        Private slot to resize the line numbers margin.
        """
        linenoMargin = Preferences.getEditor("LinenoMargin")
        if linenoMargin:
            self.__textEdit.setMarginWidth(
                0, '8' * (len(str(self.__textEdit.lines())) + 1))
    
    def __setTabAndIndent(self):
        """
        Private method to set indentation size and style and tab width.
        """
        self.__textEdit.setTabWidth(self.__getEditorConfig("TabWidth"))
        self.__textEdit.setIndentationWidth(
            self.__getEditorConfig("IndentWidth"))
        if self.lexer_ and self.lexer_.alwaysKeepTabs():
            self.__textEdit.setIndentationsUseTabs(True)
        else:
            self.__textEdit.setIndentationsUseTabs(
                self.__getEditorConfig("TabForIndentation"))
    
    def __setTextDisplay(self):
        """
        Private method to configure the text display.
        """
        self.__setTabAndIndent()
        
        self.__textEdit.setTabIndents(Preferences.getEditor("TabIndents"))
        self.__textEdit.setBackspaceUnindents(
            Preferences.getEditor("TabIndents"))
        self.__textEdit.setIndentationGuides(
            Preferences.getEditor("IndentationGuides"))
        self.__textEdit.setIndentationGuidesBackgroundColor(
            Preferences.getEditorColour("IndentationGuidesBackground"))
        self.__textEdit.setIndentationGuidesForegroundColor(
            Preferences.getEditorColour("IndentationGuidesForeground"))
        if Preferences.getEditor("ShowWhitespace"):
            self.__textEdit.setWhitespaceVisibility(
                QsciScintilla.WhitespaceVisibility.WsVisible)
            self.__textEdit.setWhitespaceForegroundColor(
                Preferences.getEditorColour("WhitespaceForeground"))
            self.__textEdit.setWhitespaceBackgroundColor(
                Preferences.getEditorColour("WhitespaceBackground"))
            self.__textEdit.setWhitespaceSize(
                Preferences.getEditor("WhitespaceSize"))
        else:
            self.__textEdit.setWhitespaceVisibility(
                QsciScintilla.WhitespaceVisibility.WsInvisible)
        self.__textEdit.setEolVisibility(Preferences.getEditor("ShowEOL"))
        self.__textEdit.setAutoIndent(Preferences.getEditor("AutoIndentation"))
        if Preferences.getEditor("BraceHighlighting"):
            self.__textEdit.setBraceMatching(
                QsciScintilla.BraceMatch.SloppyBraceMatch)
        else:
            self.__textEdit.setBraceMatching(
                QsciScintilla.BraceMatch.NoBraceMatch)
        self.__textEdit.setMatchedBraceForegroundColor(
            Preferences.getEditorColour("MatchingBrace"))
        self.__textEdit.setMatchedBraceBackgroundColor(
            Preferences.getEditorColour("MatchingBraceBack"))
        self.__textEdit.setUnmatchedBraceForegroundColor(
            Preferences.getEditorColour("NonmatchingBrace"))
        self.__textEdit.setUnmatchedBraceBackgroundColor(
            Preferences.getEditorColour("NonmatchingBraceBack"))
        if Preferences.getEditor("CustomSelectionColours"):
            self.__textEdit.setSelectionBackgroundColor(
                Preferences.getEditorColour("SelectionBackground"))
        else:
            self.__textEdit.setSelectionBackgroundColor(
                QApplication.palette().color(QPalette.ColorRole.Highlight))
        if Preferences.getEditor("ColourizeSelText"):
            self.__textEdit.resetSelectionForegroundColor()
        elif Preferences.getEditor("CustomSelectionColours"):
            self.__textEdit.setSelectionForegroundColor(
                Preferences.getEditorColour("SelectionForeground"))
        else:
            self.__textEdit.setSelectionForegroundColor(
                QApplication.palette().color(
                    QPalette.ColorRole.HighlightedText))
        self.__textEdit.setSelectionToEol(
            Preferences.getEditor("ExtendSelectionToEol"))
        self.__textEdit.setCaretForegroundColor(
            Preferences.getEditorColour("CaretForeground"))
        self.__textEdit.setCaretLineBackgroundColor(
            Preferences.getEditorColour("CaretLineBackground"))
        self.__textEdit.setCaretLineVisible(
            Preferences.getEditor("CaretLineVisible"))
        self.__textEdit.setCaretLineAlwaysVisible(
            Preferences.getEditor("CaretLineAlwaysVisible"))
        self.caretWidth = Preferences.getEditor("CaretWidth")
        self.__textEdit.setCaretWidth(self.caretWidth)
        self.caretLineFrameWidth = Preferences.getEditor("CaretLineFrameWidth")
        self.__textEdit.setCaretLineFrameWidth(self.caretLineFrameWidth)
        self.useMonospaced = Preferences.getEditor("UseMonospacedFont")
        self.__setMonospaced(self.useMonospaced)
        edgeMode = Preferences.getEditor("EdgeMode")
        edge = QsciScintilla.EdgeMode(edgeMode)
        self.__textEdit.setEdgeMode(edge)
        if edgeMode:
            self.__textEdit.setEdgeColumn(Preferences.getEditor("EdgeColumn"))
            self.__textEdit.setEdgeColor(Preferences.getEditorColour("Edge"))
        
        wrapVisualFlag = Preferences.getEditor("WrapVisualFlag")
        self.__textEdit.setWrapMode(Preferences.getEditor("WrapLongLinesMode"))
        self.__textEdit.setWrapVisualFlags(wrapVisualFlag, wrapVisualFlag)
        self.__textEdit.setWrapIndentMode(
            Preferences.getEditor("WrapIndentMode"))
        self.__textEdit.setWrapStartIndent(
            Preferences.getEditor("WrapStartIndent"))
        
        self.searchIndicator = QsciScintilla.INDIC_CONTAINER
        self.__textEdit.indicatorDefine(
            self.searchIndicator, QsciScintilla.INDIC_BOX,
            Preferences.getEditorColour("SearchMarkers"))
        
        self.__textEdit.setCursorFlashTime(QApplication.cursorFlashTime())
        
        if Preferences.getEditor("OverrideEditAreaColours"):
            self.__textEdit.setColor(
                Preferences.getEditorColour("EditAreaForeground"))
            self.__textEdit.setPaper(
                Preferences.getEditorColour("EditAreaBackground"))
        
        self.__textEdit.setVirtualSpaceOptions(
            Preferences.getEditor("VirtualSpaceOptions"))
        
        # to avoid errors due to line endings by pasting
        self.__textEdit.SendScintilla(
            QsciScintilla.SCI_SETPASTECONVERTENDINGS, True)
    
    def __setEolMode(self):
        """
        Private method to configure the eol mode of the editor.
        """
        eolMode = self.__getEditorConfig("EOLMode")
        self.__textEdit.setEolMode(eolMode)
        
    def __setMonospaced(self, on):
        """
        Private method to set/reset a monospaced font.
        
        @param on flag to indicate usage of a monospace font (boolean)
        """
        if on:
            if not self.lexer_:
                f = Preferences.getEditorOtherFonts("MonospacedFont")
                self.__textEdit.monospacedStyles(f)
        else:
            if not self.lexer_:
                self.__textEdit.clearStyles()
                self.__setMargins()
            self.__textEdit.setFont(
                Preferences.getEditorOtherFonts("DefaultFont"))
        
        self.useMonospaced = on
    
    def __printFile(self):
        """
        Private slot to print the text.
        """
        from .Printer import Printer
        printer = Printer(mode=QPrinter.PrinterMode.HighResolution)
        sb = self.statusBar()
        printDialog = QPrintDialog(printer, self)
        if self.__textEdit.hasSelectedText():
            printDialog.setOption(
                QAbstractPrintDialog.PrintDialogOption.PrintSelection,
                True)
        if printDialog.exec() == QDialog.DialogCode.Accepted:
            sb.showMessage(self.tr('Printing...'))
            QApplication.processEvents()
            if self.__curFile:
                printer.setDocName(QFileInfo(self.__curFile).fileName())
            else:
                printer.setDocName(self.tr("Untitled"))
            if (
                printDialog.printRange() ==
                QAbstractPrintDialog.PrintRange.Selection
            ):
                # get the selection
                fromLine, fromIndex, toLine, toIndex = (
                    self.__textEdit.getSelection()
                )
                if toIndex == 0:
                    toLine -= 1
                # QScintilla seems to print one line more than told
                res = printer.printRange(self.__textEdit, fromLine, toLine - 1)
            else:
                res = printer.printRange(self.__textEdit)
            if res:
                sb.showMessage(self.tr('Printing completed'), 2000)
            else:
                sb.showMessage(self.tr('Error while printing'), 2000)
            QApplication.processEvents()
        else:
            sb.showMessage(self.tr('Printing aborted'), 2000)
            QApplication.processEvents()
    
    def __printPreviewFile(self):
        """
        Private slot to show a print preview of the text.
        """
        from PyQt6.QtPrintSupport import QPrintPreviewDialog
        from .Printer import Printer
        
        printer = Printer(mode=QPrinter.PrinterMode.HighResolution)
        if self.__curFile:
            printer.setDocName(QFileInfo(self.__curFile).fileName())
        else:
            printer.setDocName(self.tr("Untitled"))
        preview = QPrintPreviewDialog(printer, self)
        preview.paintRequested.connect(self.__printPreview)
        preview.exec()
    
    def __printPreview(self, printer):
        """
        Private slot to generate a print preview.
        
        @param printer reference to the printer object
            (QScintilla.Printer.Printer)
        """
        printer.printRange(self.__textEdit)
    
    #########################################################
    ## Methods needed by the context menu
    #########################################################
    
    def __contextMenuRequested(self, coord):
        """
        Private slot to show the context menu.
        
        @param coord the position of the mouse pointer (QPoint)
        """
        self.contextMenu.popup(self.mapToGlobal(coord))
    
    def __initContextMenu(self):
        """
        Private method used to setup the context menu.
        """
        self.contextMenu = QMenu()
        
        self.languagesMenu = self.__initContextMenuLanguages()
        
        self.contextMenu.addAction(self.undoAct)
        self.contextMenu.addAction(self.redoAct)
        self.contextMenu.addSeparator()
        self.contextMenu.addAction(self.cutAct)
        self.contextMenu.addAction(self.copyAct)
        self.contextMenu.addAction(self.pasteAct)
        self.contextMenu.addSeparator()
        self.contextMenu.addAction(self.tr('Select all'), self.__selectAll)
        self.contextMenu.addAction(
            self.tr('Deselect all'), self.__deselectAll)
        self.contextMenu.addSeparator()
        self.languagesMenuAct = self.contextMenu.addMenu(self.languagesMenu)
        self.contextMenu.addSeparator()
        self.contextMenu.addAction(self.printPreviewAct)
        self.contextMenu.addAction(self.printAct)
    
    def __initContextMenuLanguages(self):
        """
        Private method used to setup the Languages context sub menu.
        
        @return reference to the generated menu (QMenu)
        """
        menu = QMenu(self.tr("Languages"))
        
        self.languagesActGrp = QActionGroup(self)
        self.noLanguageAct = menu.addAction(self.tr("No Language"))
        self.noLanguageAct.setCheckable(True)
        self.noLanguageAct.setData("None")
        self.languagesActGrp.addAction(self.noLanguageAct)
        menu.addSeparator()
        
        from . import Lexers
        self.supportedLanguages = {}
        supportedLanguages = Lexers.getSupportedLanguages()
        languages = sorted(supportedLanguages.keys())
        for language in languages:
            if language != "Guessed":
                self.supportedLanguages[language] = (
                    supportedLanguages[language][:2]
                )
                act = menu.addAction(
                    UI.PixmapCache.getIcon(supportedLanguages[language][2]),
                    self.supportedLanguages[language][0])
                act.setCheckable(True)
                act.setData(language)
                self.supportedLanguages[language].append(act)
                self.languagesActGrp.addAction(act)
        
        menu.addSeparator()
        self.pygmentsAct = menu.addAction(self.tr("Guessed"))
        self.pygmentsAct.setCheckable(True)
        self.pygmentsAct.setData("Guessed")
        self.languagesActGrp.addAction(self.pygmentsAct)
        self.pygmentsSelAct = menu.addAction(self.tr("Alternatives"))
        self.pygmentsSelAct.setData("Alternatives")
        
        menu.triggered.connect(self.__languageMenuTriggered)
        menu.aboutToShow.connect(self.__showContextMenuLanguages)
        
        return menu
    
    def __showContextMenuLanguages(self):
        """
        Private slot handling the aboutToShow signal of the languages context
        menu.
        """
        if self.apiLanguage.startswith("Pygments|"):
            self.pygmentsSelAct.setText(
                self.tr("Alternatives ({0})").format(
                    self.getLanguage(normalized=False)))
        else:
            self.pygmentsSelAct.setText(self.tr("Alternatives"))
    
    def __showLanguagesMenu(self, pos):
        """
        Private slot to show the Languages menu of the status bar.
        
        @param pos position the menu should be shown at (QPoint)
        """
        self.languagesMenu.exec(pos)
    
    def __selectPygmentsLexer(self):
        """
        Private method to select a specific pygments lexer.
        
        @return name of the selected pygments lexer
        @rtype str
        """
        from pygments.lexers import get_all_lexers
        lexerList = sorted(lex[0] for lex in get_all_lexers())
        try:
            lexerSel = lexerList.index(
                self.getLanguage(normalized=False, forPygments=True))
        except ValueError:
            lexerSel = 0
        lexerName, ok = QInputDialog.getItem(
            self,
            self.tr("Pygments Lexer"),
            self.tr("Select the Pygments lexer to apply."),
            lexerList,
            lexerSel,
            False)
        if ok and lexerName:
            return lexerName
        else:
            return ""
    
    def __languageMenuTriggered(self, act):
        """
        Private method to handle the selection of a lexer language.
        
        @param act reference to the action that was triggered (QAction)
        """
        if act == self.noLanguageAct:
            self.__resetLanguage()
        elif act == self.pygmentsAct:
            self.setLanguage("dummy.pygments")
        elif act == self.pygmentsSelAct:
            language = self.__selectPygmentsLexer()
            if language:
                self.setLanguage("dummy.pygments", pyname=language)
        else:
            language = act.data()
            if language:
                self.setLanguage(self.supportedLanguages[language][1])
        
    def __resetLanguage(self):
        """
        Private method used to reset the language selection.
        """
        if (
            self.lexer_ is not None and
            (self.lexer_.lexer() == "container" or
             self.lexer_.lexer() is None)
        ):
            self.__textEdit.SCN_STYLENEEDED.disconnect(self.__styleNeeded)
        
        self.apiLanguage = ""
        self.lexer_ = None
        self.__textEdit.setLexer()
        self.__setMonospaced(self.useMonospaced)
        
        if Preferences.getEditor("OverrideEditAreaColours"):
            self.__textEdit.setColor(
                Preferences.getEditorColour("EditAreaForeground"))
            self.__textEdit.setPaper(
                Preferences.getEditorColour("EditAreaBackground"))
        
        self.languageChanged.emit(self.apiLanguage)
        
    def setLanguage(self, filename, initTextDisplay=True, pyname=""):
        """
        Public method to set a lexer language.
        
        @param filename filename used to determine the associated lexer
            language (string)
        @param initTextDisplay flag indicating an initialization of the text
            display is required as well (boolean)
        @param pyname name of the pygments lexer to use (string)
        """
        self.__bindLexer(filename, pyname=pyname)
        self.__textEdit.recolor()
        self.__checkLanguage()
        
        # set the text display
        if initTextDisplay:
            self.__setTextDisplay()
            self.__setMargins()
        
        self.languageChanged.emit(self.apiLanguage)

    def getLanguage(self, normalized=True, forPygments=False):
        """
        Public method to retrieve the language of the editor.
        
        @param normalized flag indicating to normalize some Pygments
            lexer names
        @type bool
        @param forPygments flag indicating to normalize some lexer
            names for Pygments
        @type bool
        @return language of the editor
        @rtype str
        """
        if (
            self.apiLanguage == "Guessed" or
            self.apiLanguage.startswith("Pygments|")
        ):
            lang = self.lexer_.name()
            if normalized:
                # adjust some Pygments lexer names
                if lang in ("Python 2.x", "Python"):
                    lang = "Python3"
                elif lang == "Protocol Buffer":
                    lang = "Protocol"
                    
        else:
            lang = self.apiLanguage
            if forPygments:
                # adjust some names to Pygments lexer names
                if lang == "Python3":
                    lang = "Python"
                elif lang == "Protocol":
                    lang = "Protocol Buffer"
        return lang
    
    def __checkLanguage(self):
        """
        Private method to check the selected language of the language submenu.
        """
        if self.apiLanguage == "":
            self.noLanguageAct.setChecked(True)
        elif self.apiLanguage == "Guessed":
            self.pygmentsAct.setChecked(True)
        elif self.apiLanguage.startswith("Pygments|"):
            act = self.languagesActGrp.checkedAction()
            if act:
                act.setChecked(False)
        else:
            self.supportedLanguages[self.apiLanguage][2].setChecked(True)
    
    def __bindLexer(self, filename, pyname=""):
        """
        Private slot to set the correct lexer depending on language.
        
        @param filename filename used to determine the associated lexer
            language (string)
        @param pyname name of the pygments lexer to use (string)
        """
        if (
            self.lexer_ is not None and
            (self.lexer_.lexer() == "container" or
             self.lexer_.lexer() is None)
        ):
            self.__textEdit.SCN_STYLENEEDED.disconnect(self.__styleNeeded)
        
        filename = os.path.basename(filename)
        language = Preferences.getEditorLexerAssoc(filename)
        if language == "Python":
            language = "Python3"
        if language.startswith("Pygments|"):
            pyname = language.split("|", 1)[1]
            language = ""
        
        if not self.filetype:
            if not language and pyname:
                self.filetype = pyname
            else:
                self.filetype = language
        
        from . import Lexers
        self.lexer_ = Lexers.getLexer(language, self.__textEdit, pyname=pyname)
        if self.lexer_ is None:
            self.__textEdit.setLexer()
            self.apiLanguage = ""
            return
        
        if pyname:
            if pyname.startswith("Pygments|"):
                self.apiLanguage = pyname
            else:
                self.apiLanguage = "Pygments|{0}".format(pyname)
        else:
            if language == "Protocol":
                self.apiLanguage = language
            else:
                # Change API language for lexer where QScintilla reports
                # an abbreviated name.
                self.apiLanguage = self.lexer_.language()
                if self.apiLanguage == "POV":
                    self.apiLanguage = "Povray"
                elif self.apiLanguage == "PO":
                    self.apiLanguage = "Gettext"
        self.__textEdit.setLexer(self.lexer_)
        if self.lexer_.lexer() == "container" or self.lexer_.lexer() is None:
            self.__textEdit.SCN_STYLENEEDED.connect(self.__styleNeeded)
        
        # get the font for style 0 and set it as the default font
        key = (
            'Scintilla/Guessed/style0/font'
            if pyname and pyname.startswith("Pygments|") else
            'Scintilla/{0}/style0/font'.format(self.lexer_.language())
        )
        fdesc = Preferences.getSettings().value(key)
        if fdesc is not None:
            font = QFont([fdesc[0]], int(fdesc[1]))
            self.lexer_.setDefaultFont(font)
        self.lexer_.readSettings(Preferences.getSettings(), "Scintilla")
        if self.lexer_.hasSubstyles():
            self.lexer_.readSubstyles(self.__textEdit)
        
        # now set the lexer properties
        self.lexer_.initProperties()
        
        self.lexer_.setDefaultColor(self.lexer_.color(0))
        self.lexer_.setDefaultPaper(self.lexer_.paper(0))
    
    def __styleNeeded(self, position):
        """
        Private slot to handle the need for more styling.
        
        @param position end position, that needs styling (integer)
        """
        self.lexer_.styleText(self.__textEdit.getEndStyled(), position)
    
    def __bindName(self, line0):
        """
        Private method to generate a dummy filename for binding a lexer.
        
        @param line0 first line of text to use in the generation process
            (string)
        @return dummy file name to be used for binding a lexer (string)
        """
        bindName = ""
        line0 = line0.lower()
        
        # check first line if it does not start with #!
        if line0.startswith(("<html", "<!doctype html", "<?php")):
            bindName = "dummy.html"
        elif line0.startswith(("<?xml", "<!doctype")):
            bindName = "dummy.xml"
        elif line0.startswith("index: "):
            bindName = "dummy.diff"
        elif line0.startswith("\\documentclass"):
            bindName = "dummy.tex"
        
        if not bindName and self.filetype:
            # check filetype
            from . import Lexers
            supportedLanguages = Lexers.getSupportedLanguages()
            if self.filetype in supportedLanguages:
                bindName = supportedLanguages[self.filetype][1]
            elif self.filetype in ["Python", "Python3", "MicroPython"]:
                bindName = "dummy.py"
        
        if not bindName and line0.startswith("#!"):
            # #! marker detection
            if (
                "python3" in line0 or
                "python" in line0
            ):
                bindName = "dummy.py"
                self.filetype = "Python3"
            elif ("/bash" in line0 or "/sh" in line0):
                bindName = "dummy.sh"
            elif "ruby" in line0:
                bindName = "dummy.rb"
                self.filetype = "Ruby"
            elif "perl" in line0:
                bindName = "dummy.pl"
            elif "lua" in line0:
                bindName = "dummy.lua"
            elif "dmd" in line0:
                bindName = "dummy.d"
                self.filetype = "D"
        
        if not bindName:
            # mode line detection: -*- mode: python -*-
            match = re.search(r"mode[:=]\s*([-\w_.]+)", line0)
            if match:
                mode = match.group(1).lower()
                if mode in ["python3", "pypy3"]:
                    bindName = "dummy.py"
                    self.filetype = "Python3"
                elif mode == "ruby":
                    bindName = "dummy.rb"
                    self.filetype = "Ruby"
                elif mode == "perl":
                    bindName = "dummy.pl"
                elif mode == "lua":
                    bindName = "dummy.lua"
                elif mode in ["dmd", "d"]:
                    bindName = "dummy.d"
                    self.filetype = "D"
        
        if not bindName:
            bindName = self.__curFile
        
        return bindName
    
    ##########################################################
    ## Methods needed for the search functionality
    ##########################################################
    
    def getSRHistory(self, key):
        """
        Public method to get the search or replace history list.
        
        @param key list to return (must be 'search' or 'replace')
        @return the requested history list (list of strings)
        """
        return self.srHistory[key][:]
    
    def textForFind(self):
        """
        Public method to determine the selection or the current word for the
        next find operation.
        
        @return selection or current word (string)
        """
        if self.__textEdit.hasSelectedText():
            text = self.__textEdit.selectedText()
            if '\r' in text or '\n' in text:
                # the selection contains at least a newline, it is
                # unlikely to be the expression to search for
                return ''
            
            return text
        
        # no selected text, determine the word at the current position
        return self.__getCurrentWord()
    
    def __getWord(self, line, index):
        """
        Private method to get the word at a position.
        
        @param line number of line to look at
        @type int
        @param index position to look at
        @type int
        @return the word at that position
        @rtype str
        """
        wc = self.__textEdit.wordCharacters()
        if wc is None:
            pattern = r"\b[\w_]+\b"
        else:
            wc = re.sub(r'\w', "", wc)
            pattern = r"\b[\w{0}]+\b".format(re.escape(wc))
        rx = (
            re.compile(pattern)
            if self.__textEdit.caseSensitive() else
            re.compile(pattern, re.IGNORECASE)
        )
        
        text = self.text(line)
        for match in rx.finditer(text):
            start, end = match.span()
            if start <= index <= end:
                return match.group()
        
        return ""
    
    def __getCurrentWord(self):
        """
        Private method to get the word at the current position.
        
        @return the word at that current position
        """
        line, index = self.getCursorPosition()
        return self.__getWord(line, index)
        
    def showSearchWidget(self):
        """
        Public method to show the search widget.
        """
        self.__replaceWidget.hide()
        self.__searchWidget.show()
        self.__searchWidget.show(self.textForFind())
    
    def __searchNext(self):
        """
        Private slot to handle the search next action.
        """
        if self.__replaceWidget.isVisible():
            self.__replaceWidget.findNext()
        else:
            self.__searchWidget.findNext()
    
    def __searchPrev(self):
        """
        Private slot to handle the search previous action.
        """
        if self.__replaceWidget.isVisible():
            self.__replaceWidget.findPrev()
        else:
            self.__searchWidget.findPrev()
    
    def showReplaceWidget(self):
        """
        Public method to show the replace widget.
        """
        self.__searchWidget.hide()
        self.__replaceWidget.show(self.textForFind())
    
    def __searchClearMarkers(self):
        """
        Private method to clear the search markers of the active window.
        """
        self.clearSearchIndicators()
    
    def activeWindow(self):
        """
        Public method to fulfill the ViewManager interface.
        
        @return reference to the text edit component (QsciScintillaCompat)
        """
        return self.__textEdit
    
    def setSearchIndicator(self, startPos, indicLength):
        """
        Public method to set a search indicator for the given range.
        
        @param startPos start position of the indicator (integer)
        @param indicLength length of the indicator (integer)
        """
        self.__textEdit.setIndicatorRange(
            self.searchIndicator, startPos, indicLength)
    
    def clearSearchIndicators(self):
        """
        Public method to clear all search indicators.
        """
        self.__textEdit.clearAllIndicators(self.searchIndicator)
        self.__markedText = ""
    
    def __markOccurrences(self):
        """
        Private method to mark all occurrences of the current word.
        """
        word = self.__getCurrentWord()
        if not word:
            self.clearSearchIndicators()
            return
        
        if self.__markedText == word:
            return
        
        self.clearSearchIndicators()
        ok = self.__textEdit.findFirstTarget(
            word, False, self.__textEdit.caseSensitive(), True, 0, 0)
        while ok:
            tgtPos, tgtLen = self.__textEdit.getFoundTarget()
            self.setSearchIndicator(tgtPos, tgtLen)
            ok = self.__textEdit.findNextTarget()
        self.__markedText = word
    
    ##########################################################
    ## Methods exhibiting some QScintilla API methods
    ##########################################################
    
    def setText(self, txt, filetype=None):
        """
        Public method to set the text programatically.
        
        @param txt text to be set (string)
        @param filetype type of the source file (string)
        """
        self.__textEdit.setText(txt)
        
        if filetype is None:
            self.filetype = ""
        else:
            self.filetype = filetype
        
        eolMode = self.__getEditorConfig("EOLMode", nodefault=True)
        if eolMode is None:
            fileEol = self.__textEdit.detectEolString(txt)
            self.__textEdit.setEolModeByEolString(fileEol)
        else:
            self.__textEdit.convertEols(eolMode)
        
        self.__textEdit.setModified(False)
        self.setWindowModified(False)
    
    def gotoLine(self, line, pos=1):
        """
        Public slot to jump to the beginning of a line.
        
        @param line line number to go to
        @type int
        @param pos position in line to go to
        @type int
        """
        self.__textEdit.setCursorPosition(line - 1, pos - 1)
        self.__textEdit.ensureLineVisible(line - 1)
        self.__textEdit.setFirstVisibleLine(line - 1)
        self.__textEdit.ensureCursorVisible()
    
    #######################################################################
    ## Methods implementing the interface to EditorConfig
    #######################################################################
    
    def __loadEditorConfig(self, fileName=""):
        """
        Private method to load the EditorConfig properties.
        
        @param fileName name of the file
        @type str
        """
        if not fileName:
            fileName = self.__curFile
        
        self.__editorConfig = self.__loadEditorConfigObject(fileName)
        
        if fileName:
            self.__setTabAndIndent()
    
    def __loadEditorConfigObject(self, fileName):
        """
        Private method to load the EditorConfig properties for the given
        file name.
        
        @param fileName name of the file
        @type str
        @return EditorConfig dictionary
        @rtype dict
        """
        editorConfig = {}
        
        if fileName:
            try:
                editorConfig = editorconfig.get_properties(fileName)
            except editorconfig.EditorConfigError:
                EricMessageBox.warning(
                    self,
                    self.tr("EditorConfig Properties"),
                    self.tr("""<p>The EditorConfig properties for file"""
                            """ <b>{0}</b> could not be loaded.</p>""")
                    .format(fileName))
        
        return editorConfig
    
    def __getEditorConfig(self, option, nodefault=False, config=None):
        """
        Private method to get the requested option via EditorConfig.
        
        If there is no EditorConfig defined, the equivalent built-in option
        will be used (Preferences.getEditor(). The option must be given as the
        Preferences option key. The mapping to the EditorConfig option name
        will be done within this method.
        
        @param option Preferences option key
        @type str
        @param nodefault flag indicating to not get the default value from
            Preferences but return None instead
        @type bool
        @param config reference to an EditorConfig object or None
        @type dict
        @return value of requested setting or None if nothing was found and
            nodefault parameter was True
        @rtype any
        """
        if config is None:
            config = self.__editorConfig
        
        if not config:
            if nodefault:
                return None
            else:
                value = self.__getOverrideValue(option)
                if value is None:
                    # no override
                    value = Preferences.getEditor(option)
                return value
        
        try:
            if option == "EOLMode":
                value = config["end_of_line"]
                if value == "lf":
                    value = QsciScintilla.EolMode.EolUnix
                elif value == "crlf":
                    value = QsciScintilla.EolMode.EolWindows
                elif value == "cr":
                    value = QsciScintilla.EolMode.EolMac
                else:
                    value = None
            elif option == "DefaultEncoding":
                value = config["charset"]
            elif option == "InsertFinalNewline":
                value = Utilities.toBool(config["insert_final_newline"])
            elif option == "StripTrailingWhitespace":
                value = Utilities.toBool(config["trim_trailing_whitespace"])
            elif option == "TabWidth":
                value = int(config["tab_width"])
            elif option == "IndentWidth":
                value = config["indent_size"]
                if value == "tab":
                    value = self.__getEditorConfig("TabWidth", config=config)
                else:
                    value = int(value)
            elif option == "TabForIndentation":
                value = config["indent_style"] == "tab"
        except KeyError:
            value = None
        
        if value is None and not nodefault:
            # use Preferences as default in case of error
            value = self.__getOverrideValue(option)
            if value is None:
                # no override
                value = Preferences.getEditor(option)
        
        return value
    
    def __getOverrideValue(self, option):
        """
        Private method to get an override value for the current file type.
        
        @param option Preferences option key
        @type str
        @return override value; None in case nothing is defined
        @rtype any
        """
        if option in ("TabWidth", "IndentWidth"):
            overrides = Preferences.getEditor("TabIndentOverride")
            language = self.filetype or self.apiLanguage
            if language in overrides:
                if option == "TabWidth":
                    return overrides[self.filetype][0]
                elif option == "IndentWidth":
                    return overrides[self.filetype][1]
        
        return None
    
    #######################################################################
    ## Methods supporting the outline view below
    #######################################################################
    
    def __resetChangeTimer(self):
        """
        Private slot to reset the parse timer.
        """
        self.__changeTimer.stop()
        self.__changeTimer.start()
    
    def __editorChanged(self):
        """
        Private slot handling changes of the editor language or file name.
        """
        supported = self.__sourceOutline.isSupportedLanguage(
            self.getLanguage())
        
        self.__sourceOutline.setVisible(supported)
        
        line, pos = self.getCursorPosition()
        lang = self.getLanguage()
        self.__setSbFile(line + 1, pos, language=lang)
    
    #######################################################################
    ## Methods supporting zooming
    #######################################################################
    
    def __zoomIn(self):
        """
        Private method to handle the zoom in action.
        """
        self.zoomIn()
        self.sbZoom.setValue(self.getZoom())
        
    def __zoomOut(self):
        """
        Private method to handle the zoom out action.
        """
        self.zoomOut()
        self.sbZoom.setValue(self.getZoom())
        
    def __zoomReset(self):
        """
        Private method to reset the zoom factor.
        """
        self.__zoomTo(0)
        
    def __zoom(self):
        """
        Private method to handle the zoom action.
        """
        from QScintilla.ZoomDialog import ZoomDialog
        dlg = ZoomDialog(self.getZoom(), self, None, True)
        if dlg.exec() == QDialog.DialogCode.Accepted:
            value = dlg.getZoomSize()
            self.__zoomTo(value)
        
    def __zoomTo(self, value):
        """
        Private slot to zoom to a given value.
        
        @param value zoom value to be set (integer)
        """
        self.zoomTo(value)
        self.sbZoom.setValue(self.getZoom())

eric ide

mercurial