Wiki
Show
Ignore:
Timestamp:
06/12/08 04:59:28 (4 years ago)
Author:
Chuck.Esterbrook
Message:

Add a new "Key / Value" view in Object Explorer based on SWF.ListView?.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • cobra/trunk/Source/ObjectExplorer-WinForms.cobra

    r1519 r1521  
    1414class ObjectExplorer 
    1515    inherits Form 
    16     implements ITreeBuilder 
     16    implements ITreeBuilder, IObjectView 
    1717    """ 
    1818    Shows a tree view of one or more objects on the right and their properties. By drilling down 
     
    3232        [ ] Change the path to a text field that can be copied and pasted 
    3333        [ ] Add an "Up" button to back up in the tree view? Maybe. Backspace in the treeview already does this. 
     34        [ ] May wish to replace the ListView with a DataGridView to get more comfortable spacing between text and grid lines 
    3435 
    3536    IDEAS 
     
    5960    var _objectIdStrip as LabelStrip 
    6061    var _textBox as TextBox 
     62    var _objectViewsTabControl as TabControl 
     63    var _objectListView as ListView 
    6164    var _propertyGrid as PropertyGrid 
    6265 
     
    129132        _textBox.parent = split.panel1 
    130133 
     134        _objectViewsTabControl = TabControl() 
     135        _objectViewsTabControl.dock = DockStyle.Fill 
     136        _objectViewsTabControl.parent = split.panel2 
     137 
     138        page = TabPage('Key / Value') 
     139        _objectListView = ListView() 
     140        _objectListView.view = View.Details 
     141        _objectListView.gridLines = true 
     142        _objectListView.fullRowSelect = true 
     143        _objectListView.columns.add('Key') 
     144        _objectListView.columns.add('View') 
     145        _objectListView.dock = DockStyle.Fill 
     146        _objectListView.parent = page 
     147         
     148        _objectViewsTabControl.tabPages.add(page) 
     149         
     150        page = TabPage('Property Grid') 
    131151        _propertyGrid = PropertyGrid() 
    132152        _propertyGrid.dock = DockStyle.Fill 
    133         _propertyGrid.parent = split.panel2 
     153        _propertyGrid.parent = page 
     154         
     155        _objectViewsTabControl.tabPages.add(page) 
    134156         
    135157        split.splitterWidth += 2 
     
    348370        node.nodes.add(XTreeNode.newDummyNode) 
    349371         
     372        node = XTreeNode('Key Value View', '', _objectListView) 
     373        uiNode.nodes.add(node) 
     374        node.nodes.add(XTreeNode.newDummyNode) 
     375         
    350376        node = XTreeNode('PropertyGrid', '', _propertyGrid) 
    351377        uiNode.nodes.add(node) 
     
    371397        else             
    372398            _textBox.text = CobraCore.toTechString(obj) 
     399        # object views on right hand side 
     400        _populateObjectListView(obj) 
    373401        _propertyGrid.selectedObject = obj 
    374          
     402 
     403    def _populateObjectListView(obj as Object?) 
     404        listView = _objectListView 
     405        listView.beginUpdate 
     406        try 
     407            listView.items.clear 
     408            for info in _keyValuesOf(obj) 
     409                key = info[0] to String 
     410                value = info[1] 
     411                # isGood = info[2] to bool 
     412                item = ListViewItem(key) 
     413                item.subItems.add(CobraCore.toTechString(value)) 
     414                listView.items.add(item) 
     415 
     416            if obj inherits AssertException 
     417                _addEntryMode = 2 
     418                try 
     419                    obj.extendObjectTable(this) 
     420                finally 
     421                    _addEntryMode = 0 
     422 
     423            for i in 2, _objectListView.autoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent) 
     424        finally 
     425            listView.endUpdate 
     426 
    375427    def _updatePathStrip 
    376428        node = _treeView.selectedNode to XTreeNode? 
     
    424476            node.nodes.count == 0 or not (node.nodes[0] to XTreeNode).isDummy 
    425477        body 
    426             # need on-the-fly expanding 
    427             node.nodes.removeAt(0) 
     478            node.nodes.removeAt(0)  # the dummy node 
    428479            obj = node.value 
    429             propInfos = List<of PropertyInfo>((obj to Object).getType.getProperties) 
    430             propInfos.sort(ref .comparePropInfo) 
    431             for propInfo in propInfos 
    432                 if propInfo.name == 'Item'  # used for indexing. technically could be named something else, but this works in practice 
    433                     continue 
    434                 value = nil 
    435                 isGood = false 
    436                 try 
    437                     value = propInfo.getValue(obj, nil) 
    438                     isGood = true 
    439                 catch exc as Exception 
    440                     if exc inherits TargetInvocationException and exc.innerException 
    441                         exc = exc.innerException to ! 
    442                     value = 'Caught during get: [exc.getType.name]: [exc.message]' 
    443                 propName = .cobraMemberNameFor(propInfo.name) 
    444                 child = XTreeNode('[propName] == [CobraCore.toTechString(value)]', propName, value) 
     480            for info in _keyValuesOf(obj) 
     481                key = info[0] to String 
     482                value = info[1] 
     483                isGood = info[2] to bool 
     484                child = XTreeNode('[key] == [CobraCore.toTechString(value)]', key, value)                
    445485                if isGood 
    446486                    if not .isPrimitive(value) 
    447487                        child.nodes.add(XTreeNode.newDummyNode) 
    448488                node.nodes.add(child) 
    449             lb = c'[' 
    450             if obj inherits System.Collections.IList 
    451                 for i in obj.count 
    452                     value = nil 
    453                     isGood = false 
    454                     try 
    455                         value = obj[i] 
    456                         isGood = true 
    457                     catch exc as Exception 
    458                         value = 'Caught during IList[lb][i]]: [exc.getType.name]: [exc.message]' 
    459                     child = XTreeNode('[lb][i]] == [CobraCore.toTechString(value)]', '[lb][i]]', value) 
    460                     if isGood 
    461                         if not .isPrimitive(value) 
    462                             child.nodes.add(XTreeNode.newDummyNode) 
    463                     node.nodes.add(child) 
    464             else if obj inherits System.Collections.IDictionary 
    465                 keys = System.Collections.ArrayList(obj.keys) 
    466                 keys.sort 
    467                 for key in keys 
    468                     value = nil 
    469                     isGood = false 
    470                     try 
    471                         value = obj[key] 
    472                         isGood = true 
    473                     catch exc as Exception 
    474                         value = 'Caught during IDictionary[lb][key]]: [exc.getType.name]: [exc.message]' 
    475                     lb = c'[' 
    476                     child = XTreeNode('[lb][CobraCore.toTechString(key)]] == [CobraCore.toTechString(value)]', '[lb][CobraCore.toTechString(key)]]', value) 
    477                     if isGood 
    478                         if not .isPrimitive(value) 
    479                             child.nodes.add(XTreeNode.newDummyNode) 
    480                     node.nodes.add(child) 
    481             else if obj inherits AssertException 
     489            if obj inherits AssertException 
    482490                _nodeStack = Stack<of XTreeNode>() 
    483491                _nodeStack.push(node) 
    484                 obj.populateTreeWithExpressions(this) 
     492                _addEntryMode = 1 
     493                try 
     494                    obj.populateTreeWithExpressions(this) 
     495                finally 
     496                    _addEntryMode = 0 
    485497                _nodeStack = nil 
     498             
     499    def _keyValuesOf(obj as dynamic?) as IEnumerable<of List<of dynamic?>> 
     500        """ 
     501        Yields a series of [keyName, value, isGood] for the given object. 
     502        The series includes properties, indexed elements of IList and keyed elements of IDictionary. 
     503        The keyName is a string. The value could be anything including nil. 
     504        When isGood is false, an exception was caught when retrieving the value and consequently the value says 'Caught during...'. 
     505         
     506        This method can be used to populate a detailed view of the object, a list of subnodes in a treeview, etc. 
     507         
     508        Does *not* check for AssertException to invoke any of its special methods for displaying subexpressions. 
     509        """ 
     510        if obj is nil, yield break 
     511        yield ['.getType', obj.getType, true] 
     512        yield ['.toTechString', obj, true] 
     513        propInfos = List<of PropertyInfo>((obj to Object).getType.getProperties) 
     514        propInfos.sort(ref .comparePropInfo) 
     515        for propInfo in propInfos 
     516            if propInfo.name == 'Item'  # used for indexing. technically could be named something else, but this works in practice 
     517                continue 
     518            value = nil 
     519            isGood = false 
     520            try 
     521                value = propInfo.getValue(obj, nil) 
     522                isGood = true 
     523            catch exc as Exception 
     524                if exc inherits TargetInvocationException and exc.innerException 
     525                    exc = exc.innerException to ! 
     526                value = 'Caught during get: [exc.getType.name]: [exc.message]' 
     527            propName = .cobraMemberNameFor(propInfo.name) 
     528            yield [propName, value, isGood] 
     529        lb = c'[' 
     530        if obj inherits System.Collections.IList 
     531            for i in obj.count 
     532                propName = '[lb][i]]' 
     533                value = nil 
     534                isGood = false 
     535                try 
     536                    value = obj[i] 
     537                    isGood = true 
     538                catch exc as Exception 
     539                    value = 'Caught during IList[propName]: [exc.getType.name]: [exc.message]' 
     540                yield [propName, value, isGood] 
     541        else if obj inherits System.Collections.IDictionary 
     542            keys = System.Collections.ArrayList(obj.keys) 
     543            keys.sort 
     544            for dictKey in keys 
     545                propName = '[lb][CobraCore.toTechString(dictKey)]]' 
     546                value = nil 
     547                isGood = false 
     548                try 
     549                    value = obj[dictKey] 
     550                    isGood = true 
     551                catch exc as Exception 
     552                    value = 'Caught during IDictionary[propName]: [exc.getType.name]: [exc.message]' 
     553                lb = c'[' 
     554                yield [propName, value, isGood] 
    486555 
    487556    def comparePropInfo(a as PropertyInfo, b as PropertyInfo) as int 
     
    510579        """ 
    511580 
     581    var _addEntryMode = 0 
     582 
    512583    def indent 
    513584        nodes = _nodeStack.peek.nodes 
     
    520591 
    521592    def addEntry(key as String, value as dynamic?) 
    522         text = '[key] == [CobraCore.toTechString(value)]' 
    523         node = XTreeNode(text, key, value) 
    524         _nodeStack.peek.nodes.add(node) 
     593        branch _addEntryMode 
     594            on 1 
     595                text = '[key] == [CobraCore.toTechString(value)]' 
     596                node = XTreeNode(text, key, value) 
     597                _nodeStack.peek.nodes.add(node) 
     598            on 2 
     599                item = ListViewItem(key) 
     600                item.subItems.add(CobraCore.toTechString(value)) 
     601                _objectListView.items.add(item) 
     602            else 
     603                throw FallThroughException(_addEntryMode) 
    525604 
    526605