stickynotes_plus.py :  » Development » Leo » Leo-4.7.1-final » leo » plugins » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » Leo 
Leo » Leo 4.7.1 final » leo » plugins » stickynotes_plus.py
#@+leo-ver=4-thin
#@+node:ekr.20100103093121.5339:@thin stickynotes_plus.py
#@<< docstring >>
#@+node:ekr.20100103100944.5389:<< docstring >>
''' Simple "sticky notes" feature (popout editors)

alt-x stickynote to pop out current node as a note

'''
#@-node:ekr.20100103100944.5389:<< docstring >>
#@nl

__version__ = '0.0'
#@<< version history >>
#@+node:ekr.20100103100944.5390:<< version history >>
#@@killcolor
#@+at
# 
# Put notes about each version here.
#@-at
#@nonl
#@-node:ekr.20100103100944.5390:<< version history >>
#@nl

#@<< imports >>
#@+node:ekr.20100103100944.5391:<< imports >>
import leo.core.leoGlobals as g
from leo.core import leoPlugins

# Whatever other imports your plugins uses.

g.assertUi('qt')

import sys
import webbrowser

try:
    import markdown
except ImportError:
    print('stickynotes_plus.py: can not import markdown')
    raise

from PyQt4.QtCore import (QSize,QString,QVariant,Qt,SIGNAL,QTimer)
from PyQt4.QtGui import (QAction,QApplication,QColor,QFont
        QFontMetrics, QIcon, QKeySequence, QMenu, QPixmap, QTextCursor,
        QTextCharFormat, QTextBlockFormat, QTextListFormat,QTextEdit,QPlainTextEdit)
#@nonl
#@-node:ekr.20100103100944.5391:<< imports >>
#@nl

#@+others
#@+node:ekr.20100103100944.5392:styling
stickynote_stylesheet = """
/* The body pane */
QPlainTextEdit {
    background-color: #fdf5f5; /* A kind of pink. */
    selection-color: white;
    selection-background-color: lightgrey;
    font-family: DejaVu Sans Mono;
    /* font-family: Courier New; */
    font-size: 12px;
    font-weight: normal; /* normal,bold,100,..,900 */
    font-style: normal; /* normal,italic,oblique */
}
"""

def decorate_window(w):
    w.setStyleSheet(stickynote_stylesheet)
    w.setWindowIcon(QIcon(g.app.leoDir + "/Icons/leoapp32.png"))    
    w.resize(600, 300)

#@-node:ekr.20100103100944.5392:styling
#@+node:ekr.20100103100944.5393:init
def init ():

    ok = True

    if ok:
        #leoPlugins.registerHandler('start2',onStart2)
        g.plugin_signon(__name__)

    g.app.stickynotes = {}    
    return ok
#@-node:ekr.20100103100944.5393:init
#@+node:ekr.20100103100944.5394:class FocusingPlainTextEdit
class FocusingPlaintextEdit(QPlainTextEdit):

    def __init__(self, focusin, focusout):
        QPlainTextEdit.__init__(self)        
        self.focusin = focusin
        self.focusout = focusout

    def focusOutEvent (self, event):
        #print "focus out"
        self.focusout()

    def focusInEvent (self, event):        
        self.focusin()

    def closeEvent(self, event):
        event.accept()
        self.focusout()


#@-node:ekr.20100103100944.5394:class FocusingPlainTextEdit
#@+node:ekr.20100103100944.5395:class SimpleRichText
class SimpleRichText(QTextEdit):
    def __init__(self, focusin, focusout):
        QTextEdit.__init__(self)        
        self.focusin = focusin
        self.focusout = focusout
        self.createActions()

        #self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)

    def focusOutEvent ( self, event ):
        #print "focus out"
        self.focusout()

    def focusInEvent ( self, event ):        
        self.focusin()


    def closeEvent(self, event):
        event.accept()        

    def createActions(self):
        self.boldAct = QAction(self.tr("&Bold"), self)
        self.boldAct.setCheckable(True)
        self.boldAct.setShortcut(self.tr("Ctrl+B"))
        self.boldAct.setStatusTip(self.tr("Make the text bold"))
        self.connect(self.boldAct, SIGNAL("triggered()"), self.setBold)
        self.addAction(self.boldAct)

        boldFont = self.boldAct.font()
        boldFont.setBold(True)
        self.boldAct.setFont(boldFont)

        self.italicAct = QAction(self.tr("&Italic"), self)
        self.italicAct.setCheckable(True)
        self.italicAct.setShortcut(self.tr("Ctrl+I"))
        self.italicAct.setStatusTip(self.tr("Make the text italic"))
        self.connect(self.italicAct, SIGNAL("triggered()"), self.setItalic)
        self.addAction(self.italicAct)

    def setBold(self):
        format = QTextCharFormat()
        if self.boldAct.isChecked():
                weight = QFont.Bold
        else:
                weight = QFont.Normal
        format.setFontWeight(weight)
        self.setFormat(format)

    def setItalic(self):
        format = QTextCharFormat()
        #format.setFontItalic(self.__italic.isChecked())
        format.setFontItalic(self.italicAct.isChecked())
        self.setFormat(format)

    def setUnderline(self):
        format = QTextCharFormat()
        format.setFontUnderline(self.__underline.isChecked())
        self.setFormat(format)

    def setFormat(self, format):
        self.textCursor().mergeCharFormat(format)
        self.mergeCurrentCharFormat(format)

    def bold(self):
        print("bold")

    def italic(self):
        print("italic")



#@-node:ekr.20100103100944.5395:class SimpleRichText
#@+node:ekr.20100103100944.5396:class notetextedit
class notetextedit(QTextEdit):

    (Bold, Italic, Pre, List, Remove,
     Plain, Code, H1, H2, H3, Anchor,Save) = range(12)

    #@    @+others
    #@+node:ekr.20100103100944.5397:__init__
    def __init__(self, get_markdown, save, parent=None):
        super(notetextedit, self).__init__(parent)

        self.save = save

        self.setLineWrapMode(QTextEdit.WidgetWidth)
        self.setTabChangesFocus(True)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setMinimumWidth(300)

        self.setMouseTracking(True)

        font = QFont()
        font.setPointSize(10)
        font.setFamily("helvetica")
        document = self.document()
        document.setDefaultFont(font)

        self.font = font

        document.setDefaultStyleSheet("pre{margin-top:0px; margin-bottom:0px} li{margin-top:0px; margin-bottom:0px}")

        QTimer.singleShot(0, get_markdown)

    #@-node:ekr.20100103100944.5397:__init__
    #@+node:ekr.20100103100944.5398:focusOutEvent
    def focusOutEvent__(self, event):
        #print "focus out"
        self.focusout()

    #@-node:ekr.20100103100944.5398:focusOutEvent
    #@+node:ekr.20100103100944.5399:focusInEvent
    def focusInEvent__(self, event):        
        self.focusin()

    #@-node:ekr.20100103100944.5399:focusInEvent
    #@+node:ekr.20100103100944.5400:toggleItalic
    def toggleItalic(self):
        if self.which_header():
            return
        #self.setFontItalic(not self.fontItalic())
        italic = self.fontItalic()
        cursor = self.textCursor()
        char_format = QTextCharFormat()
        char_format.setFont(self.font)
        char_format.setFontItalic(not italic)
        cursor.setCharFormat(char_format)

    #@-node:ekr.20100103100944.5400:toggleItalic
    #@+node:ekr.20100103100944.5401:toggleUnderline
    def toggleUnderline(self):
        #not in use, markdown doesn't support
        self.setFontUnderline(not self.fontUnderline())

    #@-node:ekr.20100103100944.5401:toggleUnderline
    #@+node:ekr.20100103100944.5402:make_plain_text
    def make_plain_text(self):
        cursor = self.textCursor()

        char_format = QTextCharFormat()
        char_format.setFont(self.font)

        cursor.setCharFormat(char_format)

        block_format = QTextBlockFormat()
        block_format.setNonBreakableLines(False)
        cursor.setBlockFormat(block_format)

    #@-node:ekr.20100103100944.5402:make_plain_text
    #@+node:ekr.20100103100944.5403:make_pre_block
    def make_pre_block(self):
        cursor = self.textCursor()
        block_format = cursor.blockFormat()
        if block_format.nonBreakableLines():
            block_format.setNonBreakableLines(False)
            cursor.setBlockFormat(block_format)
            char_format = QTextCharFormat()
            char_format.setFontFixedPitch(False)
            cursor.setCharFormat(char_format)
        else:
            block_format.setNonBreakableLines(True)
            cursor.setBlockFormat(block_format)

            char_format = QTextCharFormat()
            char_format.setFontFixedPitch(True)
            cursor.setCharFormat(char_format)

    #@-node:ekr.20100103100944.5403:make_pre_block
    #@+node:ekr.20100103100944.5404:toggleBold
    def toggleBold(self):
        #self.setFontWeight(QFont.Normal if self.fontWeight() > QFont.Normal else QFont.Bold)
        if self.which_header():
            return
        bold = self.fontWeight() > QFont.Normal
        cursor = self.textCursor()
        char_format = QTextCharFormat()
        char_format.setFont(self.font)
        char_format.setFontWeight(QFont.Normal if bold else QFont.Bold)
        cursor.setCharFormat(char_format)

    #@-node:ekr.20100103100944.5404:toggleBold
    #@+node:ekr.20100103100944.5405:toggleCode
    def toggleCode(self):
        if self.which_header():
            return
        cursor = self.textCursor()
        #if not cursor.hasSelection():
        #    return

        char_format = cursor.charFormat()

        if char_format.fontFixedPitch():
            # didn't do exhaustive testing but appear to need both statements
            char_format.setFontFixedPitch(False)
            char_format.setFontFamily("helvetica")
        else:
            char_format.setFontFixedPitch(True)
            char_format.setFontFamily("courier")

        char_format.setFontItalic(False)
        char_format.setFontWeight(QFont.Normal)

        cursor.setCharFormat(char_format)

    #@-node:ekr.20100103100944.5405:toggleCode
    #@+node:ekr.20100103100944.5406:create_anchor
    def create_anchor(self):
        cursor = self.textCursor()
        if not cursor.hasSelection():
            return
        text = g.u(cursor.selectedText()) # need unicode for if below

        if text.startswith('http://'):
            text = '<a href="{0}">{1}</a> '.format(text, text[7:])
        else:
            text = '<a href="http://{0}">{0}</a> '.format(text)

        # the below works but doesn't pick up highlighting of an anchor - would have to do the underlining and blue color
        #format = QTextCharFormat()
        #format.setAnchor(True)
        #format.setAnchorHref(text)
        #cursor.setCharFormat(format)
        ##self.setTextCursor(cursor)

        #this also works and generates highlighting
        cursor.deleteChar()
        cursor.insertHtml(text) # also self.insertHtml should work

    #@-node:ekr.20100103100944.5406:create_anchor
    #@+node:ekr.20100103100944.5407:create_list
    def create_list(self):
        cursor = self.textCursor()
        if not cursor.hasSelection():
            return
        cursor.createList(QTextListFormat.ListDecimal)

    #@-node:ekr.20100103100944.5407:create_list
    #@+node:ekr.20100103100944.5408:make_heading
    def make_heading(self, heading):
        # not finished
        cursor = self.textCursor()
        cursor.select(QTextCursor.BlockUnderCursor) #QTextCursor.LineUnderCursor

        char_format = QTextCharFormat()
        #font = self.font this is a problem  because it changes self.font gets changed below
        font = QFont()
        font.setFamily("helvetica")
        font.setPointSize({1:20, 2:15, 3:12}[heading])
        font.setBold(True)
        char_format.setFont(font)

        cursor.setCharFormat(char_format)

    #@-node:ekr.20100103100944.5408:make_heading
    #@+node:ekr.20100103100944.5409:sizeHint
    def sizeHint(self): # this makes the text box taller when launched than if I don't have it
        return QSize(self.document().idealWidth() + 5, self.maximumHeight())

    #@-node:ekr.20100103100944.5409:sizeHint
    #@+node:ekr.20100103100944.5410:contextMenuEvent
    def contextMenuEvent(self, event): # this catches the context menu right click
        self.textEffectMenu()

    #@-node:ekr.20100103100944.5410:contextMenuEvent
    #@+node:ekr.20100103100944.5411:keyPressEvent__
    def keyPressEvent__(self, event):
        # needed because text edit is not going to recognize short cuts because will do something with control key
        # not needed if have global shortcuts
        if event.modifiers() & Qt.ControlModifier:
            handled = False
            if event.key() == Qt.Key_A:
                self.create_anchor()
                handled = True
            elif event.key() == Qt.Key_B:
                self.toggleBold()
                handled = True
            elif event.key() == Qt.Key_I:
                self.toggleItalic()
                handled = True
            #elif event.key() == Qt.Key_K:
                #self.colorMenu()
                #handled = True
            elif event.key() == Qt.Key_M:
                self.textEffectMenu()
                handled = True
            elif event.key() == Qt.Key_P:
                self.make_plain_text()
                handled = True
            elif event.key() == Qt.Key_Z:
                self.make_pre_block()
                handled = True
            elif event.key() == Qt.Key_U:
                self.toggleUnderline()
                handled = True
            if handled:
                event.accept()
                return

        QTextEdit.keyPressEvent(self, event)

    #@-node:ekr.20100103100944.5411:keyPressEvent__
    #@+node:ekr.20100103100944.5412:fontFixedPitch
    def fontFixedPitch(self):
        cursor = self.textCursor()
        format = cursor.charFormat()
        return format.fontFixedPitch()

    #@-node:ekr.20100103100944.5412:fontFixedPitch
    #@+node:ekr.20100103100944.5413:which_header
    def which_header(self):
        cursor = self.textCursor()
        char_format = cursor.charFormat()
        ps = char_format.font().pointSize()
        return {20:'H1', 15:'H2', 12:'H3'}.get(ps)


    #@-node:ekr.20100103100944.5413:which_header
    #@+node:ekr.20100103100944.5414:textEffectMenu
    def textEffectMenu(self):
        format = self.currentCharFormat()
        cursor = self.textCursor()
        blockformat = cursor.blockFormat()
        menu = QMenu("Text Effect")
        for text, shortcut, data, checked in (
                ("&Bold", "Ctrl+B", notetextedit.Bold,
                 self.fontWeight() > QFont.Normal),
                ("&Italic", "Ctrl+I", notetextedit.Italic,
                 self.fontItalic()),
                ("&Monospaced", None, notetextedit.Code,
                 self.fontFixedPitch())
                ): 

            action = menu.addAction(text, self.setTextEffect)
            #if shortcut is not None:
                #action.setShortcut(QKeySequence(shortcut)) # becau
            action.setData(QVariant(data))
            action.setCheckable(True)
            action.setChecked(checked)

        menu.addSeparator()

        action = menu.addAction("Anchor", self.setTextEffect)
        action.setData(notetextedit.Anchor)

        action = menu.addAction("Code Block", self.setTextEffect)
        action.setData(notetextedit.Pre)

        action = menu.addAction("Numbered List", self.setTextEffect)
        action.setData(notetextedit.List)

        header_menu = QMenu("Header")
        action = header_menu.addAction('H1', self.setTextEffect)
        action.setData(notetextedit.H1)
        action.setCheckable(True)
        action.setChecked(self.which_header()=='H1')

        action = header_menu.addAction('H2', self.setTextEffect)
        action.setData(notetextedit.H2)
        action.setCheckable(True)
        action.setChecked(self.which_header()=='H2')

        action = header_menu.addAction('H3', self.setTextEffect)
        action.setData(notetextedit.H3)
        action.setCheckable(True)
        action.setChecked(self.which_header()=='H3')

        action = menu.addAction("Remove All Formatting", self.setTextEffect)
        action.setData(notetextedit.Remove)

        menu.addMenu(header_menu)

        menu.addSeparator()

        action = menu.addAction("Save", self.setTextEffect)
        action.setData(notetextedit.Save)

        self.ensureCursorVisible()
        menu.exec_(self.viewport().mapToGlobal(self.cursorRect().center()))

    #@-node:ekr.20100103100944.5414:textEffectMenu
    #@+node:ekr.20100103100944.5415:setTextEffect
    def setTextEffect(self):
        action = self.sender()
        if action is not None and isinstance(action, QAction):
            what = action.data().toInt()[0]
            if what == notetextedit.Bold:
                self.toggleBold()

            elif what == notetextedit.Italic:
                self.toggleItalic()

            elif what == notetextedit.Code:
                self.toggleCode()

            elif what == notetextedit.Anchor:
                self.create_anchor()

            elif what == notetextedit.Pre:
                self.make_pre_block()

            elif what == notetextedit.Remove:
                self.make_plain_text()

            elif what == notetextedit.List:
                self.create_list()

            elif what == notetextedit.H1:
                self.make_heading(1)

            elif what == notetextedit.H2:
                self.make_heading(2)

            elif what == notetextedit.H3:
                self.make_heading(3)

            elif what == notetextedit.Save:
                self.save()

    #@-node:ekr.20100103100944.5415:setTextEffect
    #@+node:ekr.20100103100944.5416:mouseMoveEvent
    def mouseMoveEvent(self, event):
        #print "mouseMoveEvent"
        pos = event.pos()
        anch = self.anchorAt(pos)
        self.viewport().setCursor(Qt.PointingHandCursor if anch else Qt.IBeamCursor)
        QTextEdit.mouseMoveEvent(self, event) #? recursion

    #@-node:ekr.20100103100944.5416:mouseMoveEvent
    #@+node:ekr.20100103100944.5417:mouseReleaseEvent
    def mouseReleaseEvent(self, event):
        #print("mouseReleaseEvent")
        pos = event.pos()
        url = g.u(self.anchorAt(pos))

        if url:            
            if not url.startswith('http://'): #linux seems to need this
                url = 'http://{0}'.format(url)
            webbrowser.open(g.u(x), new=2, autoraise=True)
        else:
            QTextEdit.mouseReleaseEvent(self, event)

    #@-node:ekr.20100103100944.5417:mouseReleaseEvent
    #@+node:ekr.20100103100944.5418:insertFromMimeData
    def insertFromMimeData(self, source):
        # not sure really necessary since it actually appears to paste URLs correctly
        # I am stripping the http
        print("Paste")
        text = g.u(source.text())
        if len(text.split())==1 and (text.startswith('http://') or 'www' in text or '.com' in text or '.html' in text):
            if text.startswith('http://'):
                text = '<a href="{0}">{1}</a> '.format(text, text[7:])
            else:
                text = '<a href="http://{0}">{0}</a> '.format(text)
            self.insertHtml(text)
        else:   
            QTextEdit.insertFromMimeData(self, source)

    #@-node:ekr.20100103100944.5418:insertFromMimeData
    #@+node:ekr.20100103100944.5419:toMarkdown
    def toMarkdown(self):
        references = ''
        i = 1
        doc = QString() # the full document
        block = self.document().begin() # block is like a para; text fragment is sequence of same char format
        while block.isValid():
            #print "block=",block.text()
            if block.blockFormat().nonBreakableLines():
                doc += '    '+block.text()+'\n'
            #elif block.textList():
                #textList = block.textList()
                #print block.textList().count()
                #print g.u(block.textList().itemText(block))
                #print block.textList().itemNumber(block)
                #print block.textList().item(block.textList().itemNumber(block)).text()
                #doc += textList.itemText(block) + ' ' + textList.item(textList.itemNumber(block)).text() + '\n\n'
            else:
                if block.textList():
                    doc += '  '+block.textList().itemText(block) + ' ' 
                para = QString()
                iterator = block.begin()
                while iterator != block.end():
                    fragment = iterator.fragment()
                    if fragment.isValid():
                        char_format = fragment.charFormat()
                        text = g.u(Qt.escape(fragment.text())) # turns chars like < into entities &lt;
                        font_size = char_format.font().pointSize()
                        # a fragment can only be an anchor, italics or bold
                        if char_format.isAnchor():
                            ref = text if text.startswith('http://') else 'http://{0}'.format(text)
                            # too lazy right now to check if URL has already been referenced but should
                            references += "  [{0}]: {1}\n".format(i,ref)                            
                            text = "[{0}][{1}]".format(text,i)
                            i+=1
                        elif font_size > 10:
                            if font_size > 15:
                                text = '#{0}'.format(text)
                            elif font_size > 12:
                                text = '##{0}'.format(text)
                            else:
                                text = '###{0}'.format(text)
                        elif char_format.fontFixedPitch(): #or format.fontFamily=='courier':
                            text = QString("`%1`").arg(text)
                        elif char_format.fontItalic():
                            text = QString("*%1*").arg(text)
                        elif char_format.fontWeight() > QFont.Normal: #font-weight:600; same as for an H1; H1 font-size:xx-large; H1 20; H2 15 H3 12
                            text = QString("**%1**").arg(text)

                        para += text
                    iterator += 1
                doc += para+'\n\n'
            block = block.next()
        return doc+references

    #@-node:ekr.20100103100944.5419:toMarkdown
    #@-others
#@-node:ekr.20100103100944.5396:class notetextedit
#@+node:ekr.20100103100944.5420:g.command('stickynote')
@g.command('stickynote')
def stickynote_f(event):
    """ Launch editable 'sticky note' for the node """

    c= event['c']
    p = c.p
    v = p.v
    def focusin():
        #print "focus in"
        if v is c.p.v:
            nf.setPlainText(v.b)
            nf.setWindowTitle(p.h)
            nf.dirty = False


    def focusout():
        #print "focus out"
        if not nf.dirty:
            return
        v.b = nf.toPlainText()
        v.setDirty()
        nf.dirty = False
        p = c.p
        if p.v is v:
            c.selectPosition(c.p)


    nf = FocusingPlaintextEdit(focusin, focusout)
    nf.dirty = False
    decorate_window(nf)
    nf.setWindowTitle(p.h)
    nf.setPlainText(p.b)
    p.setDirty()

    def textchanged_cb():
        nf.dirty = True

    nf.connect(nf,
        SIGNAL("textChanged()"),textchanged_cb)

    nf.show()

    g.app.stickynotes[p.gnx] = nf
#@-node:ekr.20100103100944.5420:g.command('stickynote')
#@+node:ekr.20100103100944.5421:g.command('stickynoter')
@g.command('stickynoter')
def stickynoter_f(event):
    """ Launch editable 'sticky note' for the node """

    c= event['c']
    p = c.p
    v = p.v
    def focusin():
        print("focus in")
        if v is c.p.v:
            nf.setHtml(v.b)
            nf.setWindowTitle(p.h)
            nf.dirty = False


    def focusout():
        print("focus out")
        if not nf.dirty:
            return
        v.b = nf.toHtml()
        v.setDirty()
        nf.dirty = False
        p = c.p
        if p.v is v:
            c.selectPosition(c.p)


    nf = LessSimpleRichText(focusin, focusout)
    nf.dirty = False
    decorate_window(nf)
    nf.setWindowTitle(p.h)
    nf.setHtml(p.b)
    p.setDirty()

    def textchanged_cb():
        nf.dirty = True

    nf.connect(nf,
        SIGNAL("textChanged()"),textchanged_cb)

    nf.show()

    g.app.stickynotes[p.gnx] = nf
#@-node:ekr.20100103100944.5421:g.command('stickynoter')
#@+node:ekr.20100103100944.5422:g.command('stickynoteplus')
@g.command('stickynoteplus')
def stickynoter_f(event):
    """ Launch editable 'sticky note' for the node """

    c= event['c']
    p = c.p
    v = p.v
    def get_markdown(): #focusin():
        print("focus in")
        if v is c.p.v:
            nf.setHtml(markdown.markdown(v.b))
            nf.setWindowTitle(p.h)
            nf.dirty = False


    def save(): #focusout():
        print("focus out")
        if not nf.dirty:
            return
        v.b = nf.toMarkdown()
        v.setDirty()
        nf.dirty = False
        p = c.p
        if p.v is v:
            c.selectPosition(c.p)


    nf = notetextedit(get_markdown, save)
    nf.dirty = False
    decorate_window(nf)
    nf.setWindowTitle(p.h)
    nf.setHtml(p.b)
    p.setDirty()

    def textchanged_cb():
        nf.dirty = True

    nf.connect(nf,
        SIGNAL("textChanged()"),textchanged_cb)

    nf.show()

    g.app.stickynotes[p.gnx] = nf
#@-node:ekr.20100103100944.5422:g.command('stickynoteplus')
#@-others
#@nonl
#@-node:ekr.20100103093121.5339:@thin stickynotes_plus.py
#@-leo
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.