The document

The KalamDocument document class is a simple wrapper around a QString object. The reason for using a QString to hold all text, instead of a Python string object, is straight-forward: with all the passing around of strings, converting the QStrings retrieved from the QMultiLineEdit widgets to Python strings would take far too much time. String conversion is a fairly costly operation, involving the copying of potentially large amounts of memory.

There is another reason for using QStringin this manner: a QString is mutable, and a Python string not. This means, simply put, that every time you change a single character in a Python string, a complete new copy of the string is made, and the old copy is discarded.

There are good reasons for this behavior. If Python strings were mutable, they could not be used to index Python dictionaries based on their character value, but only on the abstract object ID that all Python objects receive. Imagine the mess you would have if you changed the actual value of a key in a dictionary.

QString is a clever and optimized class. If two instances of QString have the same contents, there is a good chance that they will even share the memory needed to store the actual text. Furthermore, QString offers as rich a set of methods to mangle strings as Python does, so we don't lose much functionality. (But look carefully at the documentation for QString — some functions, such as stripWhiteSpace(), return a new string instead of working on the existing string.)

Would our editor have to store more complex information, instead of plain text, we should use the KalamDocument class to store its data perhaps in a list of paragraphs, where each paragraph is a list itself, containing words, lines and perhaps more complex objects, such as images or even active widgets — so you could embed a button or a hyperlink in your text. However, never code what you don't yet need is a excellent motto...

"""
kalamdoc.py - abstraction of a document with a certain encoding

copyright: (C) 2001, Boudewijn Rempt
email:     boud@rempt.xs4all.nl
"""
from qt import *
from resources import TRUE, FALSE

class KalamDoc(QObject):
    """
    The document represents a plain text with a certain encoding. Default
    is Unicode.

    signals: sigDocModified (boolean)
             sigDocTitleChanged (string)
             sigDocTextChanged (qstring, qwidget)

    """
    def __init__(self, *args):
        apply(QObject.__init__, (self,)+args)
        self.encoding="unicode"
        self.newDocument()
        self._fileName = None
        self._title = "Untitled"
        self._modified = FALSE
        self._text = QString()
    

Instead of wrapping a simple, silly boolean value, we now wrap s single QString object.

    def setText(self, text, view=None):
        self._text=text
        self._modified=TRUE
        self.emit(PYSIGNAL("sigDocTextChanged"),
                  (self._text, view))
    

Most of the above functions haven't changed the basic framework. Note that the slotModified function has disappeared. Modifying a text isn't as simple as flipping a single boolean.

The setText function, which is called from the KalamView class, applies brute force to the text that KalamDocument manages. Quite simply, setText replaces the internal reference to QString with a reference to the QString that was presented by the calling view. The text has been modified, and this is recorded in the administrative _modified variable. Finally, by emitting the "sigDocTextChanged" Python signal, all views that show this document are told to update their display.

The view parameter has a default value of None — this means the change does not originate with any view, and will be applied to all views.