Пример #1
0
def parseHeadline(s):
    """
    Parse a headline of the form @kind:name=val
    Return (kind,name,val).
    Leo 4.11.1: Ignore everything after @data name.
    """
    kind = name = val = None
    if g.match(s, 0, g.u('@')):
        i = g.skip_id(s, 1, chars=g.u('-'))
        i = g.skip_ws(s, i)
        kind = s[1: i].strip()
        if kind:
            # name is everything up to '='
            if kind == g.u('data'):
                # i = g.skip_ws(s,i)
                j = s.find(g.u(' '), i)
                if j == -1:
                    name = s[i:].strip()
                else:
                    name = s[i: j].strip()
            else:
                j = s.find(g.u('='), i)
                if j == -1:
                    name = s[i:].strip()
                else:
                    name = s[i: j].strip()
                    # val is everything after the '='
                    val = s[j + 1:].strip()
    # g.trace("%50s %10s %s" %(name,kind,val))
    return kind, name, val
Пример #2
0
    def toMarkdown(self):
        references = ''
        i = 1
        # doc = QString() # the full document
        doc = g.u('')
        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()
                para = g.u('')
                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
Пример #3
0
def parseHeadline(s):
    """
    Parse a headline of the form @kind:name=val
    Return (kind,name,val).
    Leo 4.11.1: Ignore everything after @data name.
    """
    kind = name = val = None
    if g.match(s, 0, g.u('@')):
        i = g.skip_id(s, 1, chars=g.u('-'))
        i = g.skip_ws(s, i)
        kind = s[1:i].strip()
        if kind:
            # name is everything up to '='
            if kind == g.u('data'):
                # i = g.skip_ws(s,i)
                j = s.find(g.u(' '), i)
                if j == -1:
                    name = s[i:].strip()
                else:
                    name = s[i:j].strip()
            else:
                j = s.find(g.u('='), i)
                if j == -1:
                    name = s[i:].strip()
                else:
                    name = s[i:j].strip()
                    # val is everything after the '='
                    val = s[j + 1:].strip()
    # g.trace("%50s %10s %s" %(name,kind,val))
    return kind, name, val
Пример #4
0
    def toMarkdown(self):
        references = ''
        i = 1
        # doc = QString() # the full document
        doc = g.u('')
        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()
                para = g.u('')
                iterator = block.begin()
                while iterator != block.end():
                    fragment = iterator.fragment()
                    if fragment.isValid():
                        char_format = fragment.charFormat()
                        # pylint: disable=no-member
                        # EKR: I'm not sure whether this warning is valid.
                        # I'm going to kill it because this is an experimental plugin.
                        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
Пример #5
0
    def qtKey(self, event):
        '''
        Return the components of a Qt key event.

        Modifiers are handled separately.

        Return (keynum, text, toString, ch).

        keynum: event.key()
        ch:     g.u(chr(keynum)) or '' if there is an exception.
        toString:
            For special keys: made-up spelling that become part of the setting.
            For all others:   QtGui.QKeySequence(keynum).toString()
        text:   event.text()
        '''
        keynum = event.key()
        text = event.text()  # This is the unicode character!
        qt = QtCore.Qt
        d = {
            qt.Key_Alt:
            'Key_Alt',
            qt.Key_AltGr:
            'Key_AltGr',
            # On Windows, when the KeyDown event for this key is sent,
            # the Ctrl+Alt modifiers are also set.
            qt.Key_Control:
            'Key_Control',  # MacOS: Command key
            qt.Key_Meta:
            'Key_Meta',
            # MacOS: Control key, Alt-Key on Microsoft keyboard on MacOs.
            qt.Key_Shift:
            'Key_Shift',
            qt.Key_NumLock:
            'Num_Lock',
            # 868.
        }
        if d.get(keynum):
            if 0:  # Allow bare modifier key.
                toString = d.get(keynum)
            else:
                toString = ''
        else:
            toString = QtGui.QKeySequence(keynum).toString()
        # Fix bug 1244461: Numpad 'Enter' key does not work in minibuffer
        if toString == 'Enter':
            toString = 'Return'
        if toString == 'Esc':
            toString = 'Escape'
        try:
            ch1 = chr(keynum)
        except ValueError:
            ch1 = ''
        try:
            ch = g.u(ch1)
        except UnicodeError:
            ch = ch1
        text = g.u(text)
        toString = g.u(toString)
        return keynum, text, toString, ch
Пример #6
0
 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(url),new=2,autoraise=True)
     else:
         QTextEdit.mouseReleaseEvent(self,event)
Пример #7
0
 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(url),new=2,autoraise=True)
     else:
         QTextEdit.mouseReleaseEvent(self,event)
Пример #8
0
    def qtKey(self, event):
        '''
        Return the components of a Qt key event.

        Modifiers are handled separately.

        Return (keynum, text, toString, ch).

        keynum: event.key()
        ch:     g.u(chr(keynum)) or '' if there is an exception.
        toString:
            For special keys: made-up spelling that become part of the setting.
            For all others:   QtGui.QKeySequence(keynum).toString()
        text:   event.text()
        '''
        keynum = event.key()
        text = event.text() # This is the unicode character!
        qt = QtCore.Qt
        d = {
            qt.Key_Alt: 'Key_Alt',
            qt.Key_AltGr: 'Key_AltGr',
                # On Windows, when the KeyDown event for this key is sent,
                # the Ctrl+Alt modifiers are also set.
            qt.Key_Control: 'Key_Control', # MacOS: Command key
            qt.Key_Meta: 'Key_Meta',
                # MacOS: Control key, Alt-Key on Microsoft keyboard on MacOs.
            qt.Key_Shift: 'Key_Shift',
            qt.Key_NumLock: 'Num_Lock',
                # 868.
        }
        if d.get(keynum):
            if 0: # Allow bare modifier key.
                toString = d.get(keynum)
            else:
                toString = ''
        else:
            toString = QtGui.QKeySequence(keynum).toString()
        # Fix bug 1244461: Numpad 'Enter' key does not work in minibuffer
        if toString == 'Enter':
            toString = 'Return'
        if toString == 'Esc':
            toString = 'Escape'
        try:
            ch1 = chr(keynum)
        except ValueError:
            ch1 = ''
        try:
            ch = g.u(ch1)
        except UnicodeError:
            ch = ch1
        text = g.u(text)
        toString = g.u(toString)
        return keynum, text, toString, ch
Пример #9
0
    def qtKey(self, event):
        '''
        Return the components of a Qt key event.

        Modifiers are handled separately.

        Return keynum,text,toString,ch

        keynum: event.key()
        ch:     g.u(chr(keynum)) or '' if there is an exception.
        toString:
            For special keys: made-up spelling that become part of the setting.
            For all others:   QtGui.QKeySequence(keynum).toString()
        text:   event.text()
        '''
        trace = False and not g.unitTesting
        keynum = event.key()
        text = event.text() # This is the unicode text.
        qt = QtCore.Qt
        d = {
            qt.Key_Shift: 'Key_Shift',
            qt.Key_Control: 'Key_Control', # MacOS: Command key
            qt.Key_Meta: 'Key_Meta', # MacOS: Control key, Alt-Key on Microsoft keyboard on MacOs.
            qt.Key_Alt: 'Key_Alt',
            qt.Key_AltGr: 'Key_AltGr',
                # On Windows, when the KeyDown event for this key is sent,
                # the Ctrl+Alt modifiers are also set.
        }
        if d.get(keynum):
            toString = d.get(keynum)
        else:
            toString = QtGui.QKeySequence(keynum).toString()
        # Fix bug 1244461: Numpad 'Enter' key does not work in minibuffer
        if toString == 'Enter':
            toString = 'Return'
        try:
            ch1 = chr(keynum)
        except ValueError:
            ch1 = ''
        try:
            ch = g.u(ch1)
        except UnicodeError:
            ch = ch1
        text = g.u(text)
        toString = g.u(toString)
        if trace and self.keyIsActive:
            mods = '+'.join(self.qtMods(event))
            g.trace(
                'keynum %7x ch %3s toString %s %s' % (
                keynum, repr(ch), mods, repr(toString)))
        return keynum, text, toString, ch
Пример #10
0
    def returnPressed(self):

        t = g.u(self.ui.lineEdit.text())
        if not t.strip():
            return

        if t == g.u('m'):
            self.scon.doShowMarked()
        else:
            self.scon.doSearch(t)

        if self.scon.its:
            self.ui.listWidget.blockSignals(True)  # don't jump to first hit
            self.ui.listWidget.setFocus()
            self.ui.listWidget.blockSignals(False)  # ok, respond if user moves
Пример #11
0
def walk_tree(node, vns=None, seq=None):
    if vns is None:
        vns = {}
    if seq is None:
        seq = []
    if not node.gnx in seq:
        seq.append(node.gnx)
    pgnx = node.parent.gnx
    v = vns.get(node.gnx, (node.h, g.u('').join(node.b), g.u(' ').join(
        n.gnx
        for n in node.children), [], 1 if node.b else 0, pickle.dumps(node.u)))
    v[3].append(pgnx)
    vns[node.gnx] = v
    for n in node.children:
        walk_tree(n, vns, seq)
    return vns, seq
Пример #12
0
    def returnPressed(self):

        self.scon.freeze()
        t = g.u(self.ui.lineEdit.text())
        if not t.strip():
            return

        if t == g.u('m'):
            self.scon.doShowMarked()
        else:        
            self.scon.doSearch(t)

        if self.scon.its:
            self.ui.listWidget.blockSignals(True) # don't jump to first hit
            self.ui.listWidget.setFocus()
            self.ui.listWidget.blockSignals(False) # ok, respond if user moves
Пример #13
0
def showColorWheel(self, event=None):
    '''Show a Qt color dialog.'''
    c = self.c
    p = c.p
    picker = QtWidgets.QColorDialog()
    in_color_setting = p.h.startswith('@color ')
    try:
        text = QtWidgets.QApplication.clipboard().text()
        if in_color_setting:
            text = p.h.split('=', 1)[1].strip()
        color = QtGui.QColor(text)
        picker.setCurrentColor(color)
    except (ValueError, IndexError) as e:
        g.trace('error caught', e)
    if not picker.exec_():
        g.es("No color selected")
    elif in_color_setting:
        udata = c.undoer.beforeChangeNodeContents(p)
        p.h = '%s = %s' % (p.h.split(
            '=', 1)[0].strip(), g.u(picker.selectedColor().name()))
        c.undoer.afterChangeNodeContents(p, 'change-color', udata)
    else:
        text = picker.selectedColor().name()
        g.es("copied to clipboard:", text)
        QtWidgets.QApplication.clipboard().setText(text)
Пример #14
0
 def update_jupyter(self, s, keywords):
     '''Update @jupyter node in the vr pane.'''
     pc = self
     c = pc.c
     if pc.must_change_widget(QtWebKitWidgets.QWebView):
         # g.trace('===== instantiating QWebView')
         w = QtWebKitWidgets.QWebView()
         n = c.config.getInt('qweb_view_font_size')
         if n:
             settings = w.settings()
             settings.setFontSize(settings.DefaultFontSize, n)
         pc.embed_widget(w)
         assert(w == pc.w)
     else:
         w = pc.w
     url = g.getUrlFromNode(c.p)
     if url and nbformat:
         s = urlopen(url).read().decode()
         try:
             nb = nbformat.reads(s, as_version=4)
             e = HTMLExporter()
             (s, junk_resources) = e.from_notebook_node(nb)
         except nbformat.reader.NotJSONError:
             # Assume the result is html.
             pass
     elif url:
         s = 'can not import nbformt: %r' % url
     else:
         s = g.u('')
     if isQt5:
         w.hide() # This forces a proper update.
     w.setHtml(s)
     w.show()
     c.bodyWantsFocusNow()
Пример #15
0
    def liveUpdate(self):

        t = g.u(self.ui.lineEdit.text())
        if not t.strip():
            if self.scon.frozen:
                self.scon.freeze(False)
                self.scon.clear()
            return
        if len(t) < 3:
            return
        if self.scon.frozen:
            return
        if t == g.u('m'):
            self.scon.doShowMarked()
            return
        self.scon.worker.set_input(t)
Пример #16
0
 def create_nodes(self, parent, parent_d):
     '''Create the tree of nodes rooted in parent.'''
     import pprint
     trace = False and not g.unitTesting
     d = self.gnx_dict
     if trace: g.trace(parent.h, pprint.pprint(parent_d))
     for child_gnx in parent_d.get('children'):
         d2 = d.get(child_gnx)
         if trace:
             g.trace('child', pprint.pprint(d2))
         if child_gnx in self.vnodes_dict:
             # It's a clone.
             v = self.vnodes_dict.get(child_gnx)
             n = parent.numberOfChildren()
             child = leoNodes.Position(v)
             child._linkAsNthChild(parent, n)
             # Don't create children again.
         else:
             child = parent.insertAsLastChild()
             child.h = d2.get('h') or '<**no h**>'
             child.b = d2.get('b') or g.u('')
             if d2.get('gnx'):
                 child.v.findIndex = gnx = d2.get('gnx')
                 self.vnodes_dict[gnx] = child.v
             if d2.get('ua'):
                 child.u = d2.get('ua')
             self.create_nodes(child, d2)
Пример #17
0
 def update_jupyter(self, s, keywords):
     '''Update @jupyter node in the vr pane.'''
     pc = self
     c = pc.c
     if pc.must_change_widget(QtWebKitWidgets.QWebView):
         # g.trace('===== instantiating QWebView')
         w = QtWebKitWidgets.QWebView()
         n = c.config.getInt('qweb_view_font_size')
         if n:
             settings = w.settings()
             settings.setFontSize(settings.DefaultFontSize, n)
         pc.embed_widget(w)
         assert(w == pc.w)
     else:
         w = pc.w
     url = g.getUrlFromNode(c.p)
     if url and nbformat:
         s = urlopen(url).read().decode()
         try:
             nb = nbformat.reads(s, as_version=4)
             e = HTMLExporter()
             (s, junk_resources) = e.from_notebook_node(nb)
         except nbformat.reader.NotJSONError:
             # Assume the result is html.
             pass
     elif url:
         s = 'can not import nbformt: %r' % url
     else:
         s = g.u('')
     if isQt5:
         w.hide() # This forces a proper update.
     w.setHtml(s)
     w.show()
     c.bodyWantsFocusNow()
Пример #18
0
def showColorWheel(self, event=None):
    '''Show a Qt color dialog.'''
    c = self.c; p = c.p
    picker = QtWidgets.QColorDialog()
    in_color_setting = p.h.startswith('@color ')
    try:
        text = QtWidgets.QApplication.clipboard().text()
        if in_color_setting:
            text = p.h.split('=', 1)[1].strip()
        color = QtGui.QColor(text)
        picker.setCurrentColor(color)
    except (ValueError, IndexError) as e:
        g.trace('error caught', e)
        pass
    if not picker.exec_():
        g.es("No color selected")
    elif in_color_setting:
        udata = c.undoer.beforeChangeNodeContents(p)
        p.h = '%s = %s'%(p.h.split('=', 1)[0].strip(),
                         g.u(picker.selectedColor().name()))
        c.undoer.afterChangeNodeContents(p, 'change-color', udata)
    else:
        text = picker.selectedColor().name()
        g.es("copied to clipboard:", text)
        QtWidgets.QApplication.clipboard().setText(text)
Пример #19
0
 def focusin():
     if v is c.p.v:
         if v.b.encode('utf-8') != nf.toPlainText():
             # only when needed to avoid scroll jumping
             nf.setPlainText(g.u(v.b))
         nf.setWindowTitle(v.h)
         nf.dirty = False
Пример #20
0
def showFonts(self, event=None):
    '''Open a tab in the log pane showing a font picker.'''
    c = self.c; p = c.p

    picker = QtWidgets.QFontDialog()
    if p.h.startswith('@font'):
        (name, family, weight, slant, size) = leoConfig.parseFont(p.b)
    else:
        name, family, weight, slant, size = None, None, False, False, 12
    try:
        font = QtGui.QFont()
        if family: font.setFamily(family)
        font.setBold(weight)
        font.setItalic(slant)
        font.setPointSize(size)
        picker.setCurrentFont(font)
    except ValueError:
        pass
    if not picker.exec_():
        g.es("No font selected")
    else:
        font = picker.selectedFont()
        udata = c.undoer.beforeChangeNodeContents(p)
        comments = [x for x in g.splitLines(p.b) if x.strip().startswith('#')]

        defs = [
            '\n' if comments else '',
            '%s_family = %s\n'%(name, font.family()),
            '%s_weight = %s\n'%(name, 'bold' if font.bold() else 'normal'),
            '%s_slant = %s\n'%(name, 'italic' if font.italic() else 'roman'),
            '%s_size = %s\n'%(name, font.pointSizeF())
        ]

        p.b = g.u('').join(comments + defs)
        c.undoer.afterChangeNodeContents(p, 'change-font', udata)
Пример #21
0
 def create_nodes(self, parent, parent_d):
     '''Create the tree of nodes rooted in parent.'''
     import pprint
     trace = False and not g.unitTesting
     d = self.gnx_dict
     if trace: g.trace(parent.h, pprint.pprint(parent_d))
     for child_gnx in parent_d.get('children'):
         d2 = d.get(child_gnx)
         if trace:
             g.trace('child', pprint.pprint(d2))
         if child_gnx in self.vnodes_dict:
             # It's a clone.
             v = self.vnodes_dict.get(child_gnx)
             n = parent.numberOfChildren()
             child = leoNodes.Position(v)
             child._linkAsNthChild(parent, n)
             # Don't create children again.
         else:
             child = parent.insertAsLastChild()
             child.h = d2.get('h') or '<**no h**>'
             child.b = d2.get('b') or g.u('')
             if d2.get('gnx'):
                 child.v.findIndex = gnx = d2.get('gnx')
                 self.vnodes_dict[gnx] = child.v
             if d2.get('ua'):
                 child.u = d2.get('ua')
             self.create_nodes(child, d2)
Пример #22
0
    def properties(self, event=None):
        """Display a modal properties dialog for this plugin"""
        if self.hasapply:

            def callback(name, data):
                self.updateConfiguration(data)
                self.mod.applyConfiguration(self.config)
                self.writeConfiguration()

            buttons = ['Apply']
        else:
            callback = None
            buttons = []
        self.config = config = ConfigParser.ConfigParser()
        config.read(self.configfilename)
        # Load config data into dictionary of dictianaries.
        # Do no allow for nesting of sections.
        data = {}
        for section in config.sections():
            options = {}
            for option in config.options(section):
                #g.pr('config', section, option )
                options[option] = g.u(config.get(section, option))
            data[section] = options
        # Save the original config data. This will not be changed.
        self.sourceConfig = data
        # Open a modal dialog and wait for it to return.
        # Provide the dialog with a callback for the 'Appply' function.
        title = "Properties of " + self.name
        result, data = g.app.gui.runPropertiesDialog(title, data, callback, buttons)
        if result != 'Cancel' and data:
            self.updateConfiguration(data)
            self.writeConfiguration()
Пример #23
0
 def focusin():
     if v is c.p.v:
         if v.b.encode('utf-8') != nf.toPlainText():
             # only when needed to avoid scroll jumping
             nf.setPlainText(g.u(v.b))
         nf.setWindowTitle(v.h)
         nf.dirty = False
Пример #24
0
    def liveUpdate(self):

        t = g.u(self.ui.lineEdit.text())
        if not t.strip():
            if self.scon.frozen:
                self.scon.freeze(False)
                self.scon.clear()
            return
        if len(t) < 3:
            return
        if self.scon.frozen:
            return
        if t == g.u('m'):
            self.scon.doShowMarked()
            return
        self.scon.worker.set_input(t)
Пример #25
0
def showFonts(self, event=None):
    '''Open a tab in the log pane showing a font picker.'''
    c = self.c; p = c.p

    picker = QtWidgets.QFontDialog()
    if p.h.startswith('@font'):
        (name, family, weight, slant, size) = leoConfig.parseFont(p.b)
    else:
        name, family, weight, slant, size = None, None, False, False, 12
    try:
        font = QtGui.QFont()
        if family: font.setFamily(family)
        font.setBold(weight)
        font.setItalic(slant)
        font.setPointSize(size)
        picker.setCurrentFont(font)
    except ValueError:
        pass
    if not picker.exec_():
        g.es("No font selected")
    else:
        font = picker.selectedFont()
        udata = c.undoer.beforeChangeNodeContents(p)
        comments = [x for x in g.splitLines(p.b) if x.strip().startswith('#')]

        defs = [
            '\n' if comments else '',
            '%s_family = %s\n'%(name, font.family()),
            '%s_weight = %s\n'%(name, 'bold' if font.bold() else 'normal'),
            '%s_slant = %s\n'%(name, 'italic' if font.italic() else 'roman'),
            '%s_size = %s\n'%(name, font.pointSizeF())
        ]

        p.b = g.u('').join(comments + defs)
        c.undoer.afterChangeNodeContents(p, 'change-font', udata)
Пример #26
0
    def properties(self, event=None):
        """Display a modal properties dialog for this plugin"""
        if self.hasapply:

            def callback(name, data):
                self.updateConfiguration(data)
                self.mod.applyConfiguration(self.config)
                self.writeConfiguration()

            buttons = ['Apply']
        else:
            callback = None
            buttons = []
        self.config = config = ConfigParser.ConfigParser()
        config.read(self.configfilename)
        # Load config data into dictionary of dictianaries.
        # Do no allow for nesting of sections.
        data = {}
        for section in config.sections():
            options = {}
            for option in config.options(section):
                #g.pr('config', section, option )
                options[option] = g.u(config.get(section, option))
            data[section] = options
        # Save the original config data. This will not be changed.
        self.sourceConfig = data
        # Open a modal dialog and wait for it to return.
        # Provide the dialog with a callback for the 'Appply' function.
        title = "Properties of " + self.name
        result, data = g.app.gui.runPropertiesDialog(title, data, callback, buttons)
        if result != 'Cancel' and data:
            self.updateConfiguration(data)
            self.writeConfiguration()
Пример #27
0
def get_data(node):
    data = blines(node)
    for x in subtree(node):
        if x.b and not x.h.startswith('@'):
            data.extend(blines(x))
            if not x.b[-1].endswith('\n'):
                data.append(g.u('\n'))
    return data
Пример #28
0
def get_data(node):
    data = blines(node)
    for x in subtree(node):
        if x.b and not x.h.startswith('@'):
            data.extend(blines(x))
            if not x.b[-1].endswith('\n'):
                data.append(g.u('\n'))
    return data
    def end (self,completion=''):

        body = self.body
        cpl = self.completer
        if not completion:
            completion = g.u(cpl.currentCompletion())
        if completion:
            cmpl = g.u(completion).split(None,1)[0]
            cmpl = g.u(cmpl)
            prefix = g.u(cpl.completionPrefix())
            tc = body.textCursor()
            extra = len(cmpl) - len(prefix)
            tc.movePosition(tc.Left)
            tc.movePosition(tc.EndOfWord)
            tc.insertText(cmpl[-extra:])
            body.setTextCursor(tc)
        self.kill()
Пример #30
0
        def do_edit_h():
            p, w = self.get_current_pos()

            new, r = QInputDialog.getText(None, "Edit headline", "", QLineEdit.Normal, p.h)
            if not r:
                return
            new = g.u(new)
            p.h = new
            w.setWindowTitle(new)
Пример #31
0
        def do_edit_h():
            p, w = self.get_current_pos()        

            new, r = QInputDialog.getText(None, "Edit headline", "", QLineEdit.Normal, p.h)
            if not r: 
                return
            new = g.u(new)
            p.h = new
            w.setWindowTitle(new)
Пример #32
0
 def returnPressed(self):
     w = self.ui.listWidget
     self.scon.freeze()
     t = g.u(self.ui.lineEdit.text())
     if not t.strip():
         return
     # Handle Easter eggs.
     if t == g.u('m'):
         self.scon.doShowMarked()
     elif t == g.u('h'):
         self.scon.doSearchHistory()
     else:
         self.scon.doSearch(t)
     if self.scon.its:
         w.blockSignals(True)
             # don't jump to first hit
         w.setFocus()
         w.blockSignals(False)
Пример #33
0
 def returnPressed(self):
     w = self.ui.listWidget
     self.scon.freeze()
     t = g.u(self.ui.lineEdit.text())
     if not t.strip():
         return
     # Handle Easter eggs.
     if t == g.u('m'):
         self.scon.doShowMarked()
     elif t == g.u('h'):
         self.scon.doSearchHistory()
     else:
         self.scon.doSearch(t)
     if self.scon.its:
         w.blockSignals(True)
         # don't jump to first hit
         w.setFocus()
         w.blockSignals(False)
Пример #34
0
 def focusout():
     #print "focus out"
     if not nf.dirty:
         return
     v.b = g.u(nf.toPlainText())
     v.setDirty()
     nf.dirty = False
     p = c.p
     if p.v is v:
         c.selectPosition(c.p)
Пример #35
0
 def focusout():
     # print("focus out")
     if not nf.dirty:
         return
     v.b = g.u(nf.toHtml())
     v.setDirty()
     nf.dirty = False
     p = c.p
     if p.v is v:
         c.selectPosition(c.p)
Пример #36
0
 def focusout():
     if nf.dirty:
         v.b = g.u(nf.toHtml())
         v.setDirty()
         nf.dirty = False
         p = c.p
         if p.v is v:
             c.selectPosition(c.p)
         # Fix #249: Leo and Stickynote plugin do not request to save
         c.setChanged(True)
         c.redraw()
Пример #37
0
 def focusout():
     if nf.dirty:
         v.b = g.u(nf.toHtml())
         v.setDirty()
         nf.dirty = False
         p = c.p
         if p.v is v:
             c.selectPosition(c.p)
         # Fix #249: Leo and Stickynote plugin do not request to save
         c.setChanged(True)
         c.redraw()
Пример #38
0
 def focusout():
     if nf.dirty:
         if v.b.encode('utf-8') != nf.toPlainText():
             v.b = g.u(nf.toPlainText())
             v.setDirty()
             # Fix #249: Leo and Stickynote plugin do not request to save
             c.setChanged(True)
         nf.dirty = False
         p = c.p
         if p.v is v:
             c.selectPosition(c.p)
         c.redraw()
Пример #39
0
 def focusout():
     if nf.dirty:
         if v.b.encode('utf-8') != nf.toPlainText():
             v.b = g.u(nf.toPlainText())
             v.setDirty()
             # Fix #249: Leo and Stickynote plugin do not request to save
             c.setChanged(True)
         nf.dirty = False
         p = c.p
         if p.v is v:
             c.selectPosition(c.p)
         c.redraw()
Пример #40
0
 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)
Пример #41
0
    def __init__(self, *args, **kwargs):
        """Set ivars"""
        super().__init__(*args, **kwargs)
        self.root = LeoNode()

        self.root.h = g.u('ROOT')
        # changes type from [] to str, done by endElement() for other vnodes

        self.cur = self.root
        self.idx = {}
        self.in_ = None
        self.in_attrs = {}
        self.path = []
Пример #42
0
 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)
Пример #43
0
    def __init__(self, *args, **kwargs):
        """Set ivars"""
        ContentHandler.__init__(self, *args, **kwargs)
        self.root = LeoNode()

        self.root.h = g.u('ROOT')
        # changes type from [] to str, done by endElement() for other vnodes

        self.cur = self.root
        self.idx = {}
        self.in_ = None
        self.in_attrs = {}
        self.path = []
Пример #44
0
def walk_tree(node, vns=None, seq=None):
    if vns is None:
        vns = {}
    if seq is None:
        seq = []
    if not node.gnx in seq:
        seq.append(node.gnx)
    pgnx = node.parent.gnx
    v = vns.get(node.gnx, 
        (
            node.h,
            g.u('').join(node.b),
            g.u(' ').join(n.gnx for n in node.children),
            [],
            1 if node.b else 0,
            pickle.dumps(node.u)
        ))
    v[3].append(pgnx)
    vns[node.gnx] = v
    for n in node.children:
        walk_tree(n, vns, seq)
    return vns, seq
Пример #45
0
def main(src, dest):
    print('src', src)
    print('dest', dest)
    root = get_leo_data(g.readFileIntoEncodedString(src))
    root.gnx = 'hidden-root-vnode-gnx'
    vns, seq = walk_tree(root)
    data = vnode_data(vns, seq[1:])  # skip hidden root
    with sqlite3.connect(dest) as conn:
        resetdb(conn)
        conn.executemany(sqls('insert-vnode'), data)
        conn.commit()
    acc = []
    settings_harvester(root, [], acc)
    for gnx, kind, name, value, cond in acc:
        if kind == g.u('data'):
            value = repr(value)[:30]

        print(cond or "always", kind, name, pprint.pformat(value))
Пример #46
0
def settings_harvester(node, conds, acc):
    if conds:
        if isSimpleSetting(node):
            harvest_one_simple_setting(node, conds, acc)
        elif isCondition(node):
            descend(node, conds + [node], acc)
        elif isComplexSetting(node):
            harvest_one_complex_setting(node, conds, acc)
        elif node.h.startswith('@ignore'):
            pass
        else:
            descend(node, conds, acc)
    elif node.h.startswith('@ignore'):
        pass
    elif node.h.startswith(g.u('@settings')):
        descend(node, [True], acc)
    else:
        descend(node, conds, acc)
Пример #47
0
def main(src, dest):
    print('src', src)
    print('dest', dest)
    root = get_leo_data(g.readFileIntoEncodedString(src))
    root.gnx = 'hidden-root-vnode-gnx'
    vns, seq = walk_tree(root)
    data = vnode_data(vns, seq[1:]) # skip hidden root
    with sqlite3.connect(dest) as conn:
        resetdb(conn)
        conn.executemany(sqls('insert-vnode'), data)
        conn.commit()
    acc = []
    settings_harvester(root, [], acc)
    for gnx, kind, name, value, cond in acc:
        if kind == g.u('data'):
            value = repr(value)[:30]
        
        print(cond or "always", kind, name, pprint.pformat(value))
Пример #48
0
def settings_harvester(node, conds, acc):
    if conds:
        if isSimpleSetting(node):
            harvest_one_simple_setting(node, conds, acc)
        elif isCondition(node):
            descend(node, conds + [node], acc)
        elif isComplexSetting(node):
            harvest_one_complex_setting(node, conds, acc)
        elif node.h.startswith('@ignore'):
            pass
        else:
            descend(node, conds, acc)
    elif node.h.startswith('@ignore'):
        pass
    elif node.h.startswith(g.u('@settings')):
        descend(node, [True], acc)
    else:
        descend(node, conds, acc)
Пример #49
0
    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
Пример #50
0
    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
Пример #51
0
    def endElement(self, name):
        """decode unknownAttributes when t element is done"""

        self.in_ = None
        # could maintain a stack, but we only need to know for
        # character collection, so it doesn't matter

        if name == 'v':
            self.cur.h = g.u('').join(self.cur.h)
            self.cur = self.cur.parent
            if self.path:
                del self.path[-1]

        if name == 't':
            nd = self.idx[self.in_attrs['tx']]
            for k in nd.u:
                s = nd.u[k]
                if not k.startswith('str_'):
                    try:
                        s = loads(unhexlify(s))
                    except Exception:
                        pass

                nd.u[k] = s
Пример #52
0
    def endElement(self, name):
        """decode unknownAttributes when t element is done"""

        self.in_ = None
        # could maintain a stack, but we only need to know for
        # character collection, so it doesn't matter

        if name == 'v':
            self.cur.h = g.u('').join(self.cur.h)
            self.cur = self.cur.parent
            if self.path:
                del self.path[-1]

        if name == 't':
            nd = self.idx[self.in_attrs['tx']]
            for k in nd.u:
                s = nd.u[k]
                if not k.startswith('str_'):
                    try:
                        s = loads(unhexlify(s))
                    except Exception:
                        pass

                nd.u[k] = s
Пример #53
0
    def addButton(self, which, type_="move", v=None, parent=None):
        '''Add a button that creates a target for future moves.'''
        c = self.c
        p = c.p
        if v is None:
            v = p.v
        sc = scriptingController(c)
        mb = quickMoveButton(self, v, which, type_=type_)
        txt = self.txts[type_]

        if parent:  # find parent button
            for i in self.buttons:
                if i[0].target.gnx == parent:
                    parent = i[1]
                    break
            else:
                g.es('Move to button parent not found, placing at top level')
                parent = None

        header = v.anyAtFileNodeName() or v.h  # drop @auto etc.

        text = txt + ":" + header if txt else header
        # createButton truncates text.

        if parent and g.app.gui.guiName() == "qt":
            pb = parent.button
            rc = QtWidgets.QAction(text, pb)
            rc.triggered.connect(mb.moveCurrentNodeToTarget)
            pb.insertAction(pb.actions()[0], rc)  # insert at top
            b = None
            mb.has_parent = True
            t = QtCore.QString(
                c.config.getString('mod_scripting_subtext') or '')
            if not g.u(pb.text()).endswith(g.u(t)):
                pb.setText(pb.text() + t)
        else:
            b = sc.createIconButton(
                args=None,
                text=text,
                command=mb.moveCurrentNodeToTarget,
                statusLine='%s current node to %s child of %s' %
                (type_.title(), which, v.h),
                kind="quick-move")
            if g.app.gui.guiName() == "qt":

                def cb_goto_target(checked, c=c, v=v):
                    p = c.vnode2position(v)
                    c.selectPosition(p)
                    c.redraw()

                def cb_set_parent(checked, c=c, v=v, first=which, type_=type_):
                    c.quickMove.set_parent(v, first, type_)

                def cb_permanent(checked, c=c, v=v, type_=type_, first=which):
                    c.quickMove.permanentButton(v=v, type_=type_, first=first)

                # def cb_clear(event=None, c=c, v=v):
                #     c.quickMove.clearButton(v)

                for cb, txt in [
                    (cb_goto_target, 'Goto target'),
                    (cb_permanent, 'Make permanent'),
                        # (cb_clear, 'Clear permanent'),
                    (cb_set_parent, 'Set parent'),
                ]:
                    but = b.button
                    rc = QtWidgets.QAction(txt, but)
                    rc.triggered.connect(cb)
                    but.insertAction(but.actions()[-1], rc)
                    # insert rc before Remove Button

        self.buttons.append((mb, b))
Пример #54
0
 def focusin():
     if v is c.p.v:
         nf.setHtml(g.u(v.b))
         nf.setWindowTitle(p.h)
         nf.dirty = False
Пример #55
0
    def onHeadChanged (self,p,undoType='Typing',s=None,e=None):

        '''Officially change a headline.'''

        trace = False and not g.unitTesting
        verbose = False

        c = self.c ; u = c.undoer
        if not p:
            if trace: g.trace('** no p')
            return

        item = self.getCurrentItem()
        if not item:
            if trace and verbose: g.trace('** no item')
            return
        if not e:
            e = self.getTreeEditorForItem(item)
        if not e:
            if trace and verbose: g.trace('** not editing')
            return

        s = g.u(e.text())

        if g.doHook("headkey1",c=c,p=c.p,v=c.p,s=s):
            return

        self.closeEditorHelper(e,item)
        oldHead = p.h
        changed = s != oldHead
        if changed:
            # New in Leo 4.10.1.
            if trace: g.trace('new',repr(s),'old',repr(p.h))
            #@+<< truncate s if it has multiple lines >>
            #@+node:ekr.20120409185504.10028: *4* << truncate s if it has multiple lines >>
            # Remove trailing newlines before warning of truncation.
            while s and s[-1] == '\n':
                s = s[:-1]

            # Warn if there are multiple lines.
            i = s.find('\n')
            if i > -1:
                s = s[:i]
                if s != oldHead:
                    g.warning("truncating headline to one line")

            limit = 1000
            if len(s) > limit:
                s = s[:limit]
                if s != oldHead:
                    g.warning("truncating headline to",limit,"characters")
            #@-<< truncate s if it has multiple lines >>
            p.initHeadString(s)
            item.setText(0,s) # Required to avoid full redraw.
            undoData = u.beforeChangeNodeContents(p,oldHead=oldHead)
            if not c.changed: c.setChanged(True)
            # New in Leo 4.4.5: we must recolor the body because
            # the headline may contain directives.
            c.frame.body.recolor(p,incremental=True)
            dirtyVnodeList = p.setDirty()
            u.afterChangeNodeContents(p,undoType,undoData,
                dirtyVnodeList=dirtyVnodeList)

        g.doHook("headkey2",c=c,p=c.p,v=c.p,s=s)

        # This is a crucial shortcut.
        if g.unitTesting: return

        if changed:
            self.redraw_after_head_changed()

        if 0: # Don't do this: it interferes with clicks, and is not needed.
            if self.stayInTree:
                c.treeWantsFocus()
            else:
                c.bodyWantsFocus()

        p.v.contentModified()
        c.outerUpdate()
Пример #56
0
 def focusin():
     if v is c.p.v:
         nf.setHtml(g.u(v.b))
         nf.setWindowTitle(p.h)
         nf.dirty = False