attrib_edit.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 » attrib_edit.py
#@+leo-ver=4-thin
#@+node:tbrown.20091029123555.5319:@thin attrib_edit.py
#@<< docstring >>
#@+node:tbrown.20091009210724.10972:<< docstring >>
'''

attrib_edit.py - Edit attributes in v.u
=======================================

This plugin creates a frame for editing attributes similar to::

    Name:   Fred Blogs
    Home:   555-555-5555
    Work:   555-555-5556

``attrib_edit`` is also intended to provide attribute editing for
other plugins, see below.

The attributes can be stored in different ways, three modes are implemented
currently:

"v.u mode"
  These attributes are stored in the "unknownAttributes" (uA) data for
  each node, accessed via ``v.u``.
"Field:"
  Attributes are lines starting (no whitespace) with "AttributeName:" in
  the body text.
"@Child"
  Attributes are the head strings of child nodes when the head string
  starts with '@AttributeName' where the first letter (second character)
  must be capitalized.

The plugin defines the following commands, available either in the
plugin's sub-menu in the Plugins menu, or as ``Alt-X attrib-edit-*``.

attrib-edit-modes
    Select which attribute setting / getting modes to use.  More than one mode
    can be used at the same time.

    You can also control which modes are active by listing them in 
    ``@settings -> @data attrib_edit_active_modes``, e.g.::

        Field:
        @Child
        # v.u mode

    would cause only the "Field:" and "@Child" modes to be active be default.

attrib-edit-manage
    Select which attributes, from allattributesseenso import 
    far in this outline, to include on the current node.

attrib-edit-scan
    Scan the entire outline for attributes so ``attrib-edit-manage``
    has the complete list.

attrib-edit-create
    Create a new attribute on the current node.  If "Field:" or "@Child" modes
    are active, they simply remind you how to create an attribute in the log pane.
    If the "v.u mode" mode is active, you're prompted for a path for the attribute,
    e.g.::

        "addressbook First"

    to store the attribute in v.u['addressbook']['_edit']['First']

    As a convenience, entering a path like::

        "todo metadata created|creator|revised"

    would create::

        v.u.['todo']['metadata']['_edit']['created']
        v.u.['todo']['metadata']['_edit']['creator']
        v.u.['todo']['metadata']['_edit']['revised']


Technical details
+++++++++++++++++

See the source for complete documentation for use with other
plugins, here are some points of interest:

- in addition to ``v.u['addressbook']['_edit']['first']`` paths
  like ``v.u['addressbook']['_edit']['_int']['age']`` may be used
  to identify type, although currently there's no difference in
  the edit widget.

- in future the plugin may allow other plugins to register
  to provide attribute path information, instead of just
  scanning for ['_edit'] entries in v.u.

- currently there's no sorting of the attributes in "v.u mode", which is
  a problem for some applications.  It's unclear where the
  desired order would be stored, without even more repetition
  in v.u.  When other plugins can register to manipulate the
  attribute list each plugin could address this, with unordered
  presentation in the absence of the client plugin.

- There's code to have the editor appear in a tab instead
  of its own area under the body editor, but (a) this is
  always being buried by output in the log window, and
  (b) there's a bug which leaves some (harmless) ghost 
  widgets in the background.  Enable by @setting
  ``attrib_edit_placement`` to 'tab'.

'''
#@-node:tbrown.20091009210724.10972:<< docstring >>
#@nl

#@@language python
#@@tabwidth -4

#@<< imports >>
#@+node:tbrown.20091009210724.10973:<< imports >>
import leo.core.leoGlobals as g
import re
if g.app.gui.guiName() == "qt":
    import leo.core.leoPlugins as leoPlugins
    import os

    from PyQt4 import QtCore,QtGui
    Qt = QtCore.Qt
#@-node:tbrown.20091009210724.10973:<< imports >>
#@nl
__version__ = "0.1"
#@<< version history >>
#@+node:tbrown.20091009210724.10974:<< version history >>
#@@killcolor

#@+at 
#@nonl
# Use and distribute under the same terms as leo itself.
# 
# 0.1 TNB
#   - initial version
#@-at
#@nonl
#@-node:tbrown.20091009210724.10974:<< version history >>
#@nl

#@+others
#@+node:tbrown.20091009210724.10975:init
def init():

    if g.app.gui.guiName() != "qt":
        print('attrib_edit.py plugin not loading because gui is not Qt')
        return False

    leoPlugins.registerHandler('after-create-leo-frame',onCreate)
    g.plugin_signon(__name__)
    return True
#@-node:tbrown.20091009210724.10975:init
#@+node:tbrown.20091009210724.10976:onCreate
def onCreate (tag,key):

    c = key.get('c')

    attrib_edit_Controller(c)
#@-node:tbrown.20091009210724.10976:onCreate
#@+node:tbrown.20091103080354.1400:class AttributeGetter
class AttributeGetter(object):

    implementations = []

    typeMap = {
        '_int': int,
        '_float': float,
        '_bool': bool,
    }

    @classmethod
    def register(cls, subclass):
        cls.implementations.append(subclass)

    def __init__(self, c):
        self.c = c

    def name(self):
        return "ABSTRACT VIRTUAL BASE CLASS"

    def getAttribs(self, v):
        raise NotImplemented
    def setAttrib(self, v, path, value):
        raise NotImplemented
    def delAttrib(self, v, path):
        raise NotImplemented

    def helpCreate(self):
        """either a string telling user how to add an attribute, or
        True if the Getter needs to help the user create an attribute"""
        return "ABSTRACT VIRTUAL BASE CLASS"

    def longDescrip(self, path):
        """give the long description of the attribute on path 'path'.

        ASSUMES: path determines name

        E.g. attribute named 'count' might be described as 'address.people.count'
        """
        raise NotImplemented
#@-node:tbrown.20091103080354.1400:class AttributeGetter
#@+node:tbrown.20091103080354.1402:class AttributeGetterUA
class AttributeGetterUA(AttributeGetter):

    #@    @+others
    #@+node:tbrown.20091103080354.6240:__init__
    def __init__(self, c):

        AttributeGetter.__init__(self, c)
    #@-node:tbrown.20091103080354.6240:__init__
    #@+node:tbrown.20091103080354.1409:recSearch
    def recSearch(self, d, path, ans):
        """recursive search of tree of dicts for values whose
        key path is like [*][*][*]['_edit'][*] or
        [*][*][*]['_edit']['_int'][*]

        Modifies list ans
        """
        for k in d:
            if isinstance(d[k], dict):
                if k not in ('_edit', '_view'):
                    self.recSearch(d[k], path+[k], ans)
                else:
                    # k == '_edit' or '_view'
                    for ek in d[k]:
                        if ek in self.typeMap:
                            # ek is '_int' or similar
                            type_ = self.typeMap[ek]
                            for ekt in d[k][ek]:
                                ans.append((self, 
                                    ekt, d[k][ek][ekt], tuple(path+['_edit',ek,ekt]),
                                    type_, k != '_edit'))
                        else:
                            ans.append((self,
                                ek, d[k][ek], tuple(path+['_edit',ek]), str, k != '_edit'))
    #@-node:tbrown.20091103080354.1409:recSearch
    #@+node:tbrown.20091103080354.1410:getAttribs
    def getAttribs(self, v):
        """Return a list of tuples describing editable uAs.

        (class, name, value, path, type, readonly)


        e.g.

        (AttributeGetterUA, 'created', '2009-09-23', ('stickynotes','_edit','created'), str, False),
        (AttributeGetterUA, 'cars', 2, ('inventory','_edit','_int','cars'), int, False)

        Changes should be written back to
        v.uA['stickynotes']['_edit']['created'] and
        v.uA['inventory']['_edit']['_int']['cars'] respectively
        """

        ans = []
        d = v.u

        self.recSearch(d, [], ans)

        return ans
    #@-node:tbrown.20091103080354.1410:getAttribs
    #@+node:tbrown.20091103080354.1430:setAttrib
    def setAttrib(self, v, path, value):
        """copy value into dict a on path,
        e.g. a['one']['more']['level'] = value
        """

        a = v.u

        for i in path[:-1]:
            a = a.setdefault(i, {})
        a[path[-1]] = value
    #@-node:tbrown.20091103080354.1430:setAttrib
    #@+node:tbrown.20091103080354.1438:delAttrib
    def delAttrib(self, v, path):
        a = v.u
        for i in path[:-1]:
            try:
                a = a[i]
            except KeyError:
                return
        try:
            del a[path[-1]]
        except KeyError:
            pass
    #@-node:tbrown.20091103080354.1438:delAttrib
    #@+node:tbrown.20091103080354.1411:name
    def name(self):
        return "v.u mode"
    #@nonl
    #@-node:tbrown.20091103080354.1411:name
    #@+node:tbrown.20091103080354.1431:helpCreate
    def helpCreate(self):
        """does the Getter need to help the user create an attribute?"""
        return True
    #@nonl
    #@-node:tbrown.20091103080354.1431:helpCreate
    #@+node:tbrown.20091103080354.1432:createAttrib
    def createAttrib(self, v, gui_parent=None):

        path,ok = QtGui.QInputDialog.getText(gui_parent, "Enter attribute path",
            "Enter path to attribute (space separated words)")

        ns = str(path).split()  # not the QString
        if not ok or not ns:
            g.es("Cancelled")
            return

        #FIXME type_ = {True: '_view', False: '_edit'}[readonly]
        type_ = '_edit'

        if '|' in ns[-1]:
            nslist = [ ns[:-1] + [i.strip()] for i in ns[-1].split('|') ]
        else:
            nslist = [ns]

        for ns in nslist:

            if type_ not in ns:
                ns.insert(-1, type_)

            self.setAttrib(v, ns, '')

            #FIXME self.attrPaths.add(tuple(ns))
    #@-node:tbrown.20091103080354.1432:createAttrib
    #@+node:tbrown.20091103080354.1433:longDescrip
    def longDescrip(self, path):

        return '.'.join([j for j in path if j not in ('_edit','_view')])
    #@nonl
    #@-node:tbrown.20091103080354.1433:longDescrip
    #@-others

AttributeGetter.register(AttributeGetterUA)
#@-node:tbrown.20091103080354.1402:class AttributeGetterUA
#@+node:tbrown.20091103080354.1420:class AttributeGetterAt
class AttributeGetterAt(AttributeGetter):

    #@    @+others
    #@+node:tbrown.20091103080354.6238:__init__
    def __init__(self, c):

        AttributeGetter.__init__(self, c)
    #@-node:tbrown.20091103080354.6238:__init__
    #@+node:tbrown.20091103080354.1422:getAttribs
    def getAttribs(self, v):
        """Return a list of tuples describing editable uAs.

        (class, name, value, path, type, readonly)


        e.g.

        (AttributeGetterUA, 'created', '2009-09-23', ('stickynotes','_edit','created'), str, False),
        (AttributeGetterUA, 'cars', 2, ('inventory','_edit','_int','cars'), int, False)

        Changes should be written back to
        v.uA['stickynotes']['_edit']['created'] and
        v.uA['inventory']['_edit']['_int']['cars'] respectively
        """

        ans = []

        for n in v.children:
            if n.h and n.h[0] == '@' and ('A' <= n.h[1] <= 'Z'):
                words = n.h[1:].split(None, 1)
                if not words:
                    continue
                if len(words) == 1:
                    words.append('')
                ans.append( (self, words[0], words[1], words[0], str, False) )
        return ans
    #@-node:tbrown.20091103080354.1422:getAttribs
    #@+node:tbrown.20091103080354.6237:setAttrib
    def setAttrib(self, v, path, value):


        for n in v.children:
            if n.h[0] == '@' and ('A' <= n.h[1] <= 'Z'):
                words = n.h[1:].split(None, 1)
                if len(words) == 1:
                    words.append('')
                if words[0] == path:
                    n.h = "@%s %s" % (path, value)
                    break
        else:
            p = self.c.vnode2position(v)
            n = p.insertAsLastChild()
            n.h = "@%s %s" % (path, value)
    #@-node:tbrown.20091103080354.6237:setAttrib
    #@+node:tbrown.20091103080354.6244:delAttrib
    def delAttrib(self, v, path):

        for n in v.children:
            if n.h[0] == '@' and ('A' <= n.h[1] <= 'Z'):
                words = n.h[1:].split(None, 1)
                if not words:
                    continue
                if words[0] == path:
                    p = self.c.vnode2position(n)
                    p.doDelete()
                    break
    #@-node:tbrown.20091103080354.6244:delAttrib
    #@+node:tbrown.20091103080354.1423:name
    def name(self):
        return "@Child"
    #@nonl
    #@-node:tbrown.20091103080354.1423:name
    #@+node:tbrown.20091103080354.1443:helpCreate
    def helpCreate(self):
        return "Add a child named '@AttributeName'"
    #@nonl
    #@-node:tbrown.20091103080354.1443:helpCreate
    #@+node:tbrown.20091103080354.1435:longName
    def longDescrip(self, path):

        return path
    #@nonl
    #@-node:tbrown.20091103080354.1435:longName
    #@-others

AttributeGetter.register(AttributeGetterAt)
#@-node:tbrown.20091103080354.1420:class AttributeGetterAt
#@+node:tbrown.20091103080354.1427:class AttributeGetterColon
class AttributeGetterColon(AttributeGetter):

    #@    @+others
    #@+node:tbrown.20091103080354.6242:__init__
    def __init__(self, c):

        AttributeGetter.__init__(self, c)
    #@-node:tbrown.20091103080354.6242:__init__
    #@+node:tbrown.20091103080354.1428:getAttribs
    def getAttribs(self, v):

        ans = []
        parts = v.b.split('\n',100)

        for i in parts[:99]:
            if not i or i[0].isspace():
                continue
            words = i.split(None, 1)
            if words and len(words[0]) and words[0][-1] == ':':
                if len(words) == 1:
                    words.append('')
                ans.append( (self, words[0][:-1], words[1], words[0][:-1], str, False) )

        return ans
    #@-node:tbrown.20091103080354.1428:getAttribs
    #@+node:tbrown.20091103080354.6246:setAttrib
    def setAttrib(self, v, path, value):

        parts = v.b.split('\n',100)

        for n,i in enumerate(parts[:99]):
            words = i.split(None, 1)
            if words and len(words[0]) and words[0][-1] == ':' and words[0][:-1] == path:
                parts[n] = "%s: %s" % (path, value)
                v.b = '\n'.join(parts)
                break
        else:
            v.b = "%s: %s\n%s" % (path, value, v.b)
    #@-node:tbrown.20091103080354.6246:setAttrib
    #@+node:tbrown.20091103080354.6248:delAttrib
    def delAttrib(self, v, path):

        parts = v.b.split('\n',100)

        for n,i in enumerate(parts[:99]):
            words = i.split(None, 1)
            if words and len(words[0]) and words[0][-1] == ':' and words[0][:-1] == path:
                del parts[n]
                v.b = '\n'.join(parts)
                break
    #@-node:tbrown.20091103080354.6248:delAttrib
    #@+node:tbrown.20091103080354.1429:name
    def name(self):
        return "Field:"
    #@nonl
    #@-node:tbrown.20091103080354.1429:name
    #@+node:tbrown.20091103080354.1441:helpCreate
    def helpCreate(self):
        return "Add 'AttributeName:' to the text"
    #@nonl
    #@-node:tbrown.20091103080354.1441:helpCreate
    #@+node:tbrown.20091103080354.1437:longName
    def longDescrip(self, path):

        return path
    #@nonl
    #@-node:tbrown.20091103080354.1437:longName
    #@-others

AttributeGetter.register(AttributeGetterColon)
#@-node:tbrown.20091103080354.1427:class AttributeGetterColon
#@+node:tbrown.20091028131637.1353:class ListDialog
class ListDialog(QtGui.QDialog):

    #@    @+others
    #@+node:tbrown.20091028131637.1354:__init__
    def __init__(self, parent, title, text, entries):

        self.entries = entries

        QtGui.QDialog.__init__(self, parent)

        vbox = QtGui.QVBoxLayout()


        sa = QtGui.QScrollArea()
        salo = QtGui.QVBoxLayout()
        frame = QtGui.QFrame()
        frame.setLayout(salo)

        self.buttons = []

        for entry in entries:
            hbox = QtGui.QHBoxLayout()
            cb = QtGui.QCheckBox(entry[0])
            self.buttons.append(cb)
            if entry[1]:
                cb.setCheckState(Qt.Checked)
            hbox.addWidget(cb)
            salo.addLayout(hbox)

        sa.setWidget(frame)
        vbox.addWidget(sa)

        hbox = QtGui.QHBoxLayout()

        ok = QtGui.QPushButton("Ok")
        cancel = QtGui.QPushButton("Cancel")

        QtCore.QObject.connect(ok, QtCore.SIGNAL('clicked(bool)'), self.writeBack)
        QtCore.QObject.connect(cancel, QtCore.SIGNAL('clicked(bool)'), self.reject)

        hbox.addWidget(ok)
        hbox.addWidget(cancel)
        vbox.addLayout(hbox)

        self.setLayout(vbox)


    #@-node:tbrown.20091028131637.1354:__init__
    #@+node:tbrown.20091028131637.1359:writeBack
    def writeBack(self, event=None):

        for n,i in enumerate(self.buttons):
            self.entries[n][1] = (i.checkState() == Qt.Checked)

        self.accept()
    #@-node:tbrown.20091028131637.1359:writeBack
    #@-others
#@-node:tbrown.20091028131637.1353:class ListDialog
#@+node:tbrown.20091010211613.5257:class editWatcher
class editWatcher(object):
    """class to supply widget for editing attribute and handle
    its textChanged signal"""

    def __init__(self, c, v, class_, name, value, path, type_):
        """v - node whose attribute we edit
        name - name of edited attribute
        value - initial value of edited attribute
        path - dictionary key path to attribute in v.u
        type_ - attribute type
        """
        self.c = c
        self.v = v
        self.class_ = class_
        self.name = name
        self.value = value
        self.path = path
        self.type_ = type_
        self._widget = None

    def widget(self):
        """return widget for editing this attribute"""
        if not self._widget:
            self._widget = QtGui.QLineEdit(str(self.value))
            QtCore.QObject.connect(self._widget, 
                QtCore.SIGNAL("textChanged(QString)"), self.updateValue)
            self._widget.focusOutEvent = self.lostFocus
            # see lostFocus()
        return self._widget

    def updateValue(self, newValue):
        """copy value from widget to v.u"""
        self.class_.setAttrib(self.v, self.path, self.type_(newValue))
        self.v.setDirty()

    def lostFocus(self, event):
        """Can activate this in in widget(), but it stops tabbing through
        the attributes - unless we can check that none of our siblings
        has focus..."""
        sibs = self._widget.parent().findChildren(QtGui.QLineEdit)
        for i in sibs:
            if i.hasFocus():
                break
        else:
            self.c.redraw()

    #X def setValue(a, path, value):
    #X     """copy value into dict a on path,
    #X     e.g. a['one']['more']['level'] = value
    #X     """
    #X     for i in path[:-1]:
    #X         a = a.setdefault(i, {})
    #X     a[path[-1]] = value
#@-node:tbrown.20091010211613.5257:class editWatcher
#@+node:tbrown.20091009210724.10979:class attrib_edit_Controller
class attrib_edit_Controller:

    '''A per-commander class that manages attribute editing.'''

    #@    @+others
    #@+node:tbrown.20091009210724.10981:__init__
    def __init__ (self, c):

        self.c = c
        c.attribEditor = self

        self.pname = "_attrib_edit_frame"  # used to tag out panel

        active = c.config.getData('attrib_edit_active_modes') or []

        self.getsetters = []
        for i in AttributeGetter.implementations:
            s = i(c)
            self.getsetters.append([s, (s.name() in active) ])
        if not active:
            self.getsetters[0][1] = True  # turn on the first one

        self.attrPaths = set()  # set of tuples (getter-class, path)

        self.handlers = [
           ('select3', self.updateEditor),
        ]

        for i in self.handlers:
            leoPlugins.registerHandler(i[0], i[1])

        # 'body' or 'tab' mode
        self.guiMode = c.config.getString('attrib_edit_placement') or 'body'

        if self.guiMode == 'body':
            self.holder = QtGui.QSplitter(QtCore.Qt.Vertical)
            self.holder.setMinimumWidth(300)
            os = c.frame.top.leo_body_frame.parent()
            self.holder.addWidget(c.frame.top.leo_body_frame)
            os.addWidget(self.holder)
            self.parent = self.holder
        elif self.guiMode == 'tab':
            self.parent = QtGui.QFrame()
            self.holder = QtGui.QHBoxLayout()
            self.parent.setLayout(self.holder)
            c.frame.log.createTab('Attribs', widget = self.parent)
    #@-node:tbrown.20091009210724.10981:__init__
    #@+node:tbrown.20091009210724.10983:__del__
    def __del__(self):
        for i in self.handlers:
            leoPlugins.unregisterHandler(i[0], i[1])
    #@-node:tbrown.20091009210724.10983:__del__
    #@+node:tbrown.20091009210724.11210:initForm
    def initForm(self):
        """set up self.form, the blank form layout before adding edit widgets"""
        self.editors = []

        w = self.holder

        for i in w.findChildren(QtCore.QObject):
            if i.objectName() == self.pname:
                i.hide()
                i.deleteLater()

        pnl = QtGui.QFrame()
        pnl.setObjectName(self.pname)
        self.form = QtGui.QFormLayout()
        self.form.setVerticalSpacing(0)
        pnl.setLayout(self.form)
        pnl.setAutoFillBackground(True)
        w.addWidget(pnl)
    #@-node:tbrown.20091009210724.11210:initForm
    #@+node:tbrown.20091009210724.11047:updateEditor
    def updateEditor(self,tag,k):
        """update edit panel when new node selected"""

        if k['c'] != self.c: return  # not our problem

        self.updateEditorInt()
    #@-node:tbrown.20091009210724.11047:updateEditor
    #@+node:tbrown.20091028100922.1493:updateEditorInt
    def updateEditorInt(self):

        c = self.c

        self.initForm()

        for attr in self.getAttribs():
            class_, name, value, path, type_, readonly = attr
            if readonly:
                self.form.addRow(QtGui.QLabel(name), QtGui.QLabel(str(value)))

            else:
                editor = editWatcher(c, c.currentPosition().v, class_, name, value, path, type_)
                self.editors.append(editor)

                self.form.addRow(QtGui.QLabel(name), editor.widget())
    #@-node:tbrown.20091028100922.1493:updateEditorInt
    #@+node:tbrown.20091103080354.1405:recSearch
    def JUNKrecSearch(self, d, path, ans):
        """recursive search of tree of dicts for values whose
        key path is like [*][*][*]['_edit'][*] or
        [*][*][*]['_edit']['_int'][*]

        Modifies list ans
        """
        for k in d:
            if isinstance(d[k], dict):
                if k not in ('_edit', '_view'):
                    self.recSearch(d[k], path+[k], ans)
                else:
                    # k == '_edit' or '_view'
                    for ek in d[k]:
                        if ek in self.typeMap:
                            # ek is '_int' or similar
                            type_ = self.typeMap[ek]
                            for ekt in d[k][ek]:
                                ans.append((ekt, d[k][ek][ekt], tuple(path+['_edit',ek,ekt]),
                                    type_, k != '_edit'))
                        else:
                            ans.append((ek, d[k][ek], tuple(path+['_edit',ek]), str, k != '_edit'))
    #@-node:tbrown.20091103080354.1405:recSearch
    #@+node:tbrown.20091103080354.1406:getAttribs
    def getAttribs(self, v = None):
        """Return a list of tuples describing editable uAs.

        (class, name, value, path, type, readonly)


        e.g.

        (class, 'created', '2009-09-23', ('stickynotes','_edit','created'), str, False),
        (class, 'cars', 2, ('inventory','_edit','_int','cars'), int, False)

        Changes should be written back to
        v.uA['stickynotes']['_edit']['created'] and
        v.uA['inventory']['_edit']['_int']['cars'] respectively
        """

        ans = []
        if not v:
            v = self.c.currentPosition().v

        for getter, isOn in self.getsetters:

            if not isOn:
                continue

            ans.extend(getter.getAttribs(v))


        for ns in ans:
            self.attrPaths.add( (ns[0], ns[1], ns[3]) )  # class, name, path

        return ans
    #@-node:tbrown.20091103080354.1406:getAttribs
    #@+node:tbrown.20091029101116.1413:addAttrib
    def addAttrib(self, attrib):

        attrib[0].setAttrib(self.c.currentPosition().v, attrib[2], '')
    #@-node:tbrown.20091029101116.1413:addAttrib
    #@+node:tbrown.20091029101116.1414:delAttrib
    def delAttrib(self, attrib):

        attrib[0].delAttrib(self.c.currentPosition().v, attrib[2])
    #@-node:tbrown.20091029101116.1414:delAttrib
    #@+node:tbrown.20091029101116.1424:scanAttribs
    def scanAttribs(self):
        """scan all of c for attrbutes"""
        for v in self.c.all_unique_nodes():
            self.getAttribs(v)  # updates internal list of attribs
        g.es("%d attributes found" % len(self.attrPaths))
    #@nonl
    #@-node:tbrown.20091029101116.1424:scanAttribs
    #@+node:tbrown.20091011151836.14788:createAttrib
    def createAttrib(self, event=None, readonly=False):

        ans = []

        for getter, isOn in self.getsetters:
            if not isOn:
                continue

            if getter.helpCreate() is True:
                ans.append(getter)
            else:
                g.es("For '%s' attributes:\n  %s" % (getter.name(), getter.helpCreate()))

        if len(ans) > 1:
            g.es('ERROR: more than one attribute type (%s) active' %
            ', '.join([i.name() for i in ans]), color='red')
        elif ans:
            ans[0].createAttrib(self.c.currentPosition().v, gui_parent=self.parent)
            self.updateEditorInt()
            self.c.currentPosition().v.setDirty()
            self.c.redraw()
    #@-node:tbrown.20091011151836.14788:createAttrib
    #@+node:tbrown.20091028131637.1358:manageAttrib
    def manageAttrib(self):

        attribs = [(i[0],i[1],i[3]) for i in self.getAttribs()]

        dat = []
        for attr in self.attrPaths:

            txt = attr[0].longDescrip(attr[2])

            active = attr in attribs

            dat.append([txt, active, attr])

        if not dat:
            g.es('No attributes seen (yet)')
            return

        dat.sort(key=lambda x: x[0])

        res = ListDialog(self.parent, "Enter attribute path",
            "Enter path to attribute (space separated words)", 
            dat)

        res.exec_()

        if res.result() == QtGui.QDialog.Rejected:
            return

        # check for deletions
        for i in dat:
            if i[2] in attribs and not i[1]:
                res = QtGui.QMessageBox(QtGui.QMessageBox.Question,
                    "Really delete attributes?","Really delete attributes?",
                    QtGui.QMessageBox.Ok|QtGui.QMessageBox.Cancel, self.parent)
                if res.exec_() == QtGui.QMessageBox.Cancel:
                    return
                break

        # apply changes
        for i in dat:
            if i[2] in attribs and not i[1]:
                self.delAttrib(i[2])
            elif i[2] not in attribs and i[1]:
                self.addAttrib(i[2])

        self.updateEditorInt()
        self.c.redraw()

    #@-node:tbrown.20091028131637.1358:manageAttrib
    #@+node:tbrown.20091103080354.1415:manageModes
    def manageModes(self):

        modes = [ [i[0].name(), i[1]] for i in self.getsetters ]

        res = ListDialog(self.parent, "Enter attribute path",
            "Enter path to attribute (space separated words)", 
            modes)

        res.exec_()

        if res.result() == QtGui.QDialog.Rejected:
            return

        for n,i in enumerate(modes):
            self.getsetters[n][1] = i[1]

        self.updateEditorInt()
    #@-node:tbrown.20091103080354.1415:manageModes
    #@-others
#@-node:tbrown.20091009210724.10979:class attrib_edit_Controller
#@+node:tbrown.20091029101116.1415:cmd_Modes
def cmd_Modes(c):
   c.attribEditor.manageModes()
#@-node:tbrown.20091029101116.1415:cmd_Modes
#@+node:tbrown.20091103080354.1413:cmd_Manage
def cmd_Manage(c):
   c.attribEditor.manageAttrib()
#@-node:tbrown.20091103080354.1413:cmd_Manage
#@+node:tbrown.20091029101116.1419:cmd_Create
def cmd_Create(c):
   c.attribEditor.createAttrib()
#@-node:tbrown.20091029101116.1419:cmd_Create
#@+node:tbrown.20091029101116.1421:cmd_CreateReadonly
def Xcmd_CreateReadonly(c):
   c.attribEditor.createAttrib(readonly=True)
#@-node:tbrown.20091029101116.1421:cmd_CreateReadonly
#@+node:tbrown.20091029101116.1426:cmd_Scan
def cmd_Scan(c):
   c.attribEditor.scanAttribs()
#@-node:tbrown.20091029101116.1426:cmd_Scan
#@-others
#@nonl
#@-node:tbrown.20091029123555.5319:@thin attrib_edit.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.