The CodeEditor class has more than two dozen base classes! I considered
writing a script to analyze those classes, but that turned out not to be
necessary. I simply created clones of the base classes and studied those,
summarizing the results in a table given below.
This post discusses what I learned.
*Overview*
The CodeEditor class contains no members! No class vars, ivars, or
methods. Nothing. It exists only to "collect" the members of subclasses!
Each base class provides:
- Class-specific methods. Each method becomes a method of the CodeEditor
class, so all "public" members of all base classes must have unique names.
In other words, encapsulation is broken. As a workaround, public of base
class x have names of the form *x*. It's ugly, but it works.
- Overrides. cff's show that:
- 11 base classes define the *_styleElements*, class var.
- 14 base classes define the *keyPressEvent *method.
- 12 base classes define the *paintEvent *method.
*The order of base classes defines the order in which overridden methods
are called*. Calls to, say, super().paintEvent() determine drawing order.
The drawing can happen "in front of" or "in back of" other drawing. This
ordering of method calls appears to be the *only* reason for have all these
subclasses!
*The CodeEditor class and its base classes*
The following table summarize the members defined in the CodeEditor class
and its base classes. The base classes of CodeEditor are shown in order,
and that order sometimes matters. All base classes are subclasses only of
Object, except for the CodeEditorBase class, which is a subclass of
QPlainText.
class CodeEditor
# no members!
class HighlightCurrentLine
# _styleElements, *highlight*, paintEvent
class HighlightMatchingOccurrences
# _styleElements, *highlight*, paintEvent
class HighlightMatchingBracket
# _styleElements, *highlight*, paintEvent
class FullUnderlines
# Only paintEvent
class IndentationGuides
# _styleElements, set/showIndentationGuides, paintEvent
class CodeFolding
# Only paintEvent
class LongLineIndicator
# _styleElements, set/longLineIndicatorPosition, paintEvent
class ShowWhitespace
# set/showWhitespace (no paintEvent)
class ShowLineEndings
# set/showLineEndings (no paintEvent)
class Wrap
# set/showWrap (no paintEvent)
class BreakPoints
# _styleElements, *BreakPoint*, paintEvent, resizeEvent
class LineNumbers
# _styleElements, *LineNumbers*, paintEvent, resizeEvent
class AutoCompletion
# *Completion*, keyPressEvent
class Calltip #must follow AutoCompletion class.
# _styleElements, *calltip*, focusOutEvent, keyPressEvent
class Indentation,
# Only keyPressEvent.
class MoveLinesUpDown,
# Only keyPressEvent.
class ScrollWithUpDownKeys,
# Only keyPressEvent.
class HomeKey,
# Only keyPressEvent.
class EndKey,
# Only keyPressEvent.
class NumpadPeriodKey,
# Only keyPressEvent.
class AutoIndent,
# *autoIndent*.
class PythonAutoIndent,
# Only keyPressEvent.
class AutoCloseQuotesAndBrackets,
# Only keyPressEvent.
class SyntaxHighlighting,
# _styleElements, parser, setParser.
class SmartCopyAndPaste, # overrides cut(), copy(), paste()
# cut, copy, paste, pasteAndSelect.
class CodeEditorBase (QPlainText), # must be the last base class.
# Several dozen methods.
*Alternatives*
Imo, the CodeEditor class stretches class design to near the breaking
point. It would be easy to derive CodeEditor from QPlainText only.
Following the "explicit is better than implicit" principle, one could
define a single paintEvent method that would do all drawing in a specified
order. I would do this in Leo, if we end up using any of the paintEvent
code. This new organization could be tried in pyzo itself in a new branch,
say paint.
Similarly, the _styleElements class vars could be replaced by a single
table. That's moot for Leo because Leo has its own configuration code.
Humorously, CodeEditorBase.getStyleElementDescriptions collects these
descriptions. They all could be moved into a single table in the
CodeEditor class. But to repeat, this is all moot.
Likewise, the various keyPressEvent methods are unlikely to become part of
Leo.
*Summary*
The two dozen base classes for the CodeEditor class define an implicit
calling order for overridden methods such as paintEvent and keyPressEvent.
It has virtually no other purpose. Using all those base classes means that
base classes must use naming conventions to ensure their "public" members
do not collide with methods of other base classes. This is far from
elegant.
With this new understanding, we see that the bizarre class scheme is
completely optional. Moving code to Leo will be straightforward. The
various paintEvent methods seem the most interesting. It would be
straightforward to replace all the overrides of paintEvent with a single
master painter in some Leo class.
Edward
--
You received this message because you are subscribed to the Google Groups
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.