The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

PyFrame Guide to wxPython

Copyright and License information Home

__ A B C D E F G H I L M P R S T U V W

wxStyledTextCtrl - Multiple Views

  • GetDocPointer

  • SetDocPointer

  • CreateDocument

  • AddRefDocument

  • ReleaseDocument

  • Example

  • Another Viewpoint

Summary:

An interesting STC feature is the ability to have multiple views of the same Document. This can be used to provide split views of a document within one wxFrame (using a splitter window and two STC instances) or within multiple wxFrames. Changes to the Document in one window are reflected in other windows displaying the same Document.

Backgrounder:

The two most fundamental parts of the STC architecture are the Document and Editor classes. An Editor displays the contents of an instance of a Document class. Internally, a Document instance maintains a reference count and a list of Editor windows in which the Document appears.

Each STC instance displays a single Document instance. Creation of a STC instance causes a blank Document instance to be created with a reference count (see AddRefDocument) of 1. A C++ pointer to the Document instance is held in an STC internal variable called pdoc. When a different document instance is selected into the STC by using SetDocPointer, the reference count of the Document instance that's active prior to the call to SetDocPointer is decremented; when it becomes zero then the Document instance is deleted. This previous document also deletes the editor window from its list of Editor windows.

You can increment the reference count by using AddRefDocument and decrement it by using ReleaseDocument; which will also delete the Document instance when the reference count becomes zero.

You can create more Document instances by using CreateDocument, but only one at a time is displayed. You select the instance to display using SetDocPointer.

----

GetDocPointer()

Returns a pointer to the active document held by the STC. It's the document that's currently being displayed by the window. This 'pointer' is actually a string object of the form:

 XXXXXXXX_void_p

(on a 32-bit system, anyway) where XXXXXXXX is the actual 32-bit pointer (left-padded to 8 characters with underscores if needed). You should check the return value since it's possible to get None as a return value.

Also see AddRefDocument

top

----

SetDocPointer(pointer_string)

If you are holding a valid 'pointer' to a Document then you can poke it into the STC instance with the SetDocPointer method. Returns None.

The pointer_string parameter must be set to a valid 'pointer' that was obtained by calling GetDocPointer. As a special case you can pass None and the STC will create a new, empty Document and display it. The 'previous' document removes the current Editor window from its windows list. It also decrements its reference count by 1; if the reference count becomes zero then the document is deleted.

top

----

CreateDocument()

This method creates a new Document, but only returns it; the Document is not selected into the STC instance. The return value is a pointer string as shown in GetDocPointer. You should check the return value since it's possible to get None as a return value.

The reference count of the Document is 1.

Also see AddRefDocument for more information about reference counts.

Important: some internal STC parameters are maintained on a document-by-document basis. See these notes about tabs, and SetWordChars, . Also, folding information is maintained on a document-by-document basis as well. If you are performing your own styling (as opposed to allowing a lexer to do it) be aware that the number of styling bits is set to 5 when a new document is created. Note that if you are using the HTML lexer on a document and create a new document that's also to have HTML displayed and properly colorized, you need to set the number of styling bits to 7 right away!

top

----

AddRefDocument(pointer_string)

AddRefDocument adds 1 to the reference count for the Document whose pointer-string you pass in as a parameter. This reference count should not be confused with the Python reference count; this reference count is maintained in the Document data structure internal to the STC instance.

Why would you want to do this? You need to use extra care if your intention is to swap Documents in and out of a STC instance. When you use SetDocPointer the Document that is in view before you use SetDocPointer will have its reference count decremented.

If that reduces the reference count to zero then the Document is deleted. If you later pass in the pointer-string for a Document that's been deleted then you will get a run-time error. Generally, as soon as you obtain a pointer-string from the STC you should use this method to increment the reference count. In any case it needs to be done if you select a different document into the STC. Use ReleaseDocument when you are actually done with the Document; e.g., when the enclosing frame is closed or upon a similar event. This is a tricky aspect of STC programming, and if ignored will cause memory leaks and/or run-time errors.

If you want to use SetDocPointer() for multiple-Document support then you should use GetDocPointer() first and increment the reference count (with AddRefDocument()) before calling SetDocPointer() with the new pointer or the Document being displayed prior to the SetDocPointer() call will be deleted.

top

----

ReleaseDocument(pointer_string)

ReleaseDocument decrements the reference count of the Document instance described by pointer_string. If the count becomes zero then the Document instance is deleted.

top

----

Example:

Note that this is an untested example.

 from wxPython.stc import *
 
 class DocumentEditor(wxStyledTextCtrl):
     def __init__(self,parentWin, default_text='', documentName):
                wxStyledTextCtrl.__init__(self,parentWin,wxNewId()) 
                self.documentName = documentName        #name of currently-viewed document
                documentViews = {}                      #name->Document-pointer-string mapping
 
        def addDocument(self,textContent,name):
                """add a new document. 
                        textContent is the initial text to go in it, 
                        name is a name to use when referring to this 
                        document
                """
                currentDocument = self.GetDocPointer()  #get the document that's currently being shown
                self.AddRefDocument(currentDocument)    #bump its reference count
                documentViews[self.documentName] = currentDocument   #keep this pointer-string 'handle'
                newDoc = self.CreateDocument()          #create a new document
                self.SetDocPointer(newDoc)              #make it shown
                self.SetText(textContent)               #set its initial text
                self.documentName = name                #name of currently-viewed document
                
        def swapDocuments(self,name):
                "replaces the current document with a previously created one"
                if not hasattr(self.documentViews,name): #be sure that the name is valid!
                        return
                currentDocument = self.GetDocPointer()  #get the document that's currently being shown
                self.AddRefDocument(currentDocument)    #bump its reference count
                documentViews[self.documentName] = currentDocument   #keep this pointer-string 'handle'
                
                newDoc = documentView[name]             #get the previous document pointer-string
                self.SetDocPointer(newDoc)              #show the desired document
                #Note: important to do ReleaseDocument AFTER SetDocPointer or the doc might get deleted prior to SetDocPointer!!!
                self.ReleaseDocument(newDoc)            #dec the reference count 
 
                del documentViews[name]                 #don't keep around an old document p-s 'handle'
                self.documentName = name                #name of currently-viewed document
                
          
                
                

top

----

Another viewpoint:

The following is some information from the Scintilla-Interest list (by Greg Smith), note that the terminology is that of Scintilla, not wxSTC, but you may find the information useful.

 Multiple views
 A Scintilla window and the document that it displays are separate entities.
 When you create a new window, you also create a new, empty document. Each
 document has a reference count that is initially set to 1. The document also
 has a list of the Scintilla windows that are linked to it so when any window
 changes the document, all other windows in which it appears are notified to
 cause them to update. The system is arranged in this way so that you can
 work with many documents in a single Scintilla window and so you can display
 a single document in multiple windows (for use with splitter windows).
 
 SCI_GETDOCPOINTER
 This returns a pointer to the document currently in use by the window. It
 has no other effect.
 
 SCI_SETDOCPOINTER(,document *pDoc)
 This message does the following:
 1. It removes the current window from the list held by the current document.
 2. It reduces the reference count of the current document by 1.
 3. If the reference count reaches 0, the document is deleted.
 4. pDoc is set as the new document for the window.
 5. If pDoc was 0, a new, empty document is created and attached to the
 window.
 
 SCI_CREATEDOCUMENT
 This message creates a new, empty document and returns a pointer to it. This
 document is not selected into the editor and starts with a reference count
 of 1. This means that you have ownership of it and must either reduce its
 reference count by 1 after using SCI_SETDOCPOINTER so that the Scintilla
 window owns it or you must make sure that you reduce the reference count by
 1 with SCI_RELEASEDOCUMENT before you close the application to avoid memory
 leaks.
 
 SCI_ADDREFDOCUMENT(, document *pDoc)
 This increases the reference count of a document by 1. If you want to
 replace the current document in the Scintilla window and take ownership of
 the current document, for example if you are editing many documents in one
 window, do the following:
 1. Use SCI_GETDOCPOINTER to get a pointer to the document, pDoc.
 2. Use SCI_ADDREFDOCUMENT(0, pDoc) to increment the reference count.
 3. Use SCI_SETDOCPOINTER(0, pNewDoc) to set a different document or
 SCI_SETDOCPOINTER(0, 0) to set a new, empty document.
 
 SCI_RELEASEDOCUMENT(, document *pDoc)
 This message reduces the reference count of the document identified by pDoc.
 pDoc must be the result of SCI_GETDOCPOINTER or SCI_CREATEDOCUMENT and must
 point at a document that still exists. If you call this on a document with a
 reference count of 1 that is still attached to a Scintilla window, bad
 things will happen. To keep the world spinning in its orbit you must balance
 each call to SCI_CREATEDOCUMENT or SCI_ADDREFDOCUMENT with a call to
 SCI_RELEASEDOCUMENT.

top

1 POD Error

The following errors were encountered while parsing the POD:

Around line 173:

Non-ASCII character seen before =encoding in ' '. Assuming CP1252