From VisualWorks®, 7.6 of February 8, 2008 on March 3, 2008 at 9:42:51 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <name>Trippy</name> <environment>Tools</environment> <private>false</private> <imports> private Smalltalk.* </imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> <class> <name>Navigator</name> <environment>Tools.Trippy</environment> <super>UI.ApplicationModel</super> <private>false</private> none visit shell inspector inspectorClasses inspectorCache inspectorHolder <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.Navigator
A navigator is a container interface for an inspector. An inspector displays an individual object, while a navigator provides a wider context of objects to be displayed, as well as manages the choice of inspectors that can display a given object. For example, a hierarchy navigator displays a hierarchy of objects. When a hierarchy element is selected, the navigator determines what inspectors can be used to display it, updates the view selection tabs accordingly, and installs one of those inspectors to actually display the object. Instance Variables: visit <Visit> The current object's visit. As the user changes objects within the navigator, visits are updated to reflect the travel. shell <InspectorShell> The parent inspector shell. inspector <Inspector> The currently installed inspector. inspectorClasses <Array of: Class> Classes of inspectors that can present the current object. inspectorHolder <SelectionInList> The model of the view selection tab control.
</comment> <class> <name>NullNavigator</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Navigator</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.NullNavigator
This is a navigator focused on a single object and not actually providing any navigation options. It does take care of view switches. Or in other words, it as a couch potato with a remote control. This is what sits between an inspector shell and an inspector when the "Explore" menu is set to "Off".
</comment> <class> <name>ObjectSegment</name> <environment>Tools.Trippy</environment> <super>Core.Magnitude</super> <private>false</private> none firstIndex lastIndex firstPart lastPart <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.ObjectSegment
When an object is broken into groups of parts to keep the list of parts of a reasonable size, instances of this class represent those groups. Instance Variables: firstIndex <Integer> Index of the first element of this segment within the page's sequence of keys. lastIndex <Integer> Ditto of the last element. firstKey <Integer> Key of the first element, cached here to allow printing. lastKey <Integer> Ditto of the last element.
</comment> <class> <name>InspectorHolder</name> <environment>Tools.Trippy</environment> <super>UI.ApplicationModel</super> <private>false</private> none inspector <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.InspectorHolder
InspectorHolder is used when a single inspector has to be embedded within another interface, without any fancy things like diving or navigation. In that case, InspectorHolder is embedded, and the inspector is placed inside the holder. The holder provides the interface an inspector expects from its container application, thus not requiring anything special from the actual application that embeds the inspection. Instance Variables: inspector <Inspector>
</comment> <class> <name>Visit</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none object owner children <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.Visit
This is a record of visiting an object. Typically when we visit an object, we get there from some other object--that is, some other visit. This is the owner visit. The owner visit may be nil in some cases--for example, when the current visit is the root of the visit hierarchy, that is, the object we originally opened the inspector on. Starting from an object, we may go visit some other related objects. Those would be child visits. Instance Variables: object <Object> The object we are visiting. owner <Visit | nil> The owner visit or nil. children <OrderedCollection of: Visit> Visits that this object is the owner of.
</comment> <class> <name>Inspector</name> <environment>Tools.Trippy</environment> <super>UI.ApplicationModel</super> <private>false</private> none object container <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.Inspector
This is an abstract superclass of inspectors. An inspector is a module that plugs into a Navigator to present a view of a single object. The navigator creates it and tells what object to inspect. Inspector class also provides a set of methods for safely interrogating the state of objects. This is an important service to provide for Inspector components, so that we do the "right" thing with regard to proxies and other objects which are sensitive to what API's they expose. See the class side protocols: 'utilities-printing' and 'utilities-object queries'. Subclasses must implement the following messages: actions copyStateTo: private refresh Instance Variables: container <InspectorHolder | InspectorShell> the object that provides navigation services for the inspector object <Object> The object being inspected. Shared Variables: CanonicalBasicSizeMethod <CompiledMethod> We keep our own compiled version of the primitive method for determining an object size. We can then invoke this method on an inspected object without regards to whether it actually supports the API itself or not. CanonicalClassMethod <CompiledMethod> We keep our own compiled version of the primitive method for determining the class of an object. CanonicalInstVarAtMethod <CompiledMethod> We keep our own compiled version of the primitive method for fetching an inst var by index. CanonicalIsImmutableMethod <CompiledMethod> We keep our own compiled version of the primitive method for determining an objects imutability.
</comment> <class> <name>BehaviorInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Inspector</super> <private>false</private> none textHolder sideHolder protocolListHolder methodListHolder inheritanceStop <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.BehaviorInspector
This is an unusual inspector, which is actually a browser on the class of the inspected object. It is here both as an example of a custom Inspector pluggable into the framework, and as a stand-in for an embedded browser until we have a browser that can actually be reused inside other interfaces. There is an important difference between how this inspector treats classes vs other objects. For non-class objects, the inspector shows instance-side and class-side methods. Instance methods are initially displayed, and "self" is bound to the inspected object if the instance/class switch is on the instance side, and to the class of the inspected object if the switch is on the class side. For class objects, the inspector preserves the typical browser perspective. That is, the straighforward approach would place methods for messages that can be sent to the inspected object (a class) on the instance side, and methods for messages that can be sent to the class of the object (a metaclass) on the class side. This would be confusing because methods visible in that case on the instance side would be the methods we see in regular browsers on the class side. For example, if we inspected "Model", the inspector would show methods of the Model class on the instance side and instance methods of Metaclass on the class side. Instead, the inspector retains the browser perspective and shows instance and class methods of the Model class, with class side pre-selected. "self" in that case is bound to the inspected object (a class) if the class swith is selected, and to nil if the instance side is selected.
</comment> <class> <name>Part</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none object <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.Part
Instances of Part are used by PartListAbstractInspector and subclasses to represent elements of the left hand side list in the inspector. A part knows its object and is responsible for obtaining its value (if it has a value as some parts don't), setting it (if the part is not read-only), supplying the text to be displayed in the inspector's right hand side pane. Instance Variables: object <Object> The Whole.
</comment> <class> <name>KeyedElement</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Part</super> <private>false</private> none key <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.KeyedElement
A part of an object accessible by sending messages #at: and #at:put:. Elements of both Dictionaries and Arrays are keyed elements. Instance Variables: key <Object> The #at: argument used to retrieve the part value.
</comment> <class> <name>VisualComponentProxy</name> <environment>Tools.Trippy</environment> <super>Graphics.VisualPart</super> <private>false</private> none actualComponent <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.VisualComponentProxy
This is a helper class for the VisualComponentInspectorPage. It allows displaying a preview of any visual component without ripping it out of the hierarchy it normally belongs to, by pretending to be a visual component itself and delegating the important messages to the real visual component. Instance Variables: actualComponent <VisualComponent> The VisualComponent being previewed.
</comment> <class> <name>OwnerNavigator</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Navigator</super> <private>false</private> none ownerInspector fieldListHolder vicinity <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.OwnerNavigator
This one's navigation context is the owner object, that is parts of the object we were inspecting before diving into the current object. This navigator is what takes care of Explore>Forward and Explore>Backward menu settings. Instance Variables: ownerInspector <PartListAbstractInspector> The owner inspector (see above) that supplies us with the list of parts of the owner object. These parts are the context for navigation. fieldListHolder <SelectionInList> The model of the field list. vicinity <#owner | #self> #owner if this navigator does "Explore>Backward", or #self if it does "Explore>Forward". This affects the menu check marks, and also what happens when we zoom into a part.
</comment> <class> <name>UndoAction</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none savedValues <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.UndoAction
This is an abstract superclass of a group of subclasses representing undo editing actions in inspector pages. Whenever a change is done on a page, the page creates an undo action and sticks it in the undo history of that page. This is how undo works. Subclasses must implement the following messages: accessing explanation undoIn: Instance Variables: savedValues <ExportBundle> The page typically has to save information about objects removed from the page, or values replaced in the page. The information is saved as an ExportBundle for now. When we roll OrderedDictionaries in, we can fix everything to use OrderedDictionary instead.
</comment> <class> <name>RemovalUndo</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.UndoAction</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.RemovalUndo
This action undoes removal of object parts. It remembers the removed parts and inserts them back if applied.
</comment> <class> <name>InstVarRemovalUndo</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.RemovalUndo</super> <private>false</private> none definingClasses <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.InstVarRemovalUndo
This removal undo action remember defining classes of instance variables removed from an instance, so they can be put back into the right places. Instance Variables: definingClasses <Array of: Class> An array "parallel" to the part collection stored by the superclass, remembering the defining class of a respective part in the part array.
</comment> <class> <name>NamedVariable</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Part</super> <private>false</private> none name class index protected <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.NamedVariable
This part represents a named instance variable of an object. Instance Variables: name <String> The name of the variable class <ClassDescription> The class where the variable is defined (or a subclass of one) index <Integer> The index of the variable in the index (future argument to #instVarAt:) protected <Boolean> Does this variable require warnings and confirmations before allowing changes to it (also indicates a change in the icon to show the shield
</comment> <class> <name>PartSnapshot</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none part value <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.PartSnapshot
This is a snapshot of a part state. A regular part does not store its current value and instead gets it from the object each time it is needed. A snapshot is there for cases when it is necessary to remember the current part value because it may change in future. Instance Variables: part <Part> The original part. value <Object> The remembered part value.
</comment> <class> <name>DragController</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none page view viewState <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.DragController
Drag controllers are things attached to inspector pages to take care of drag-and-drop related operations. This way drag and drop behaviour is pluggable and is not tied to the page inheritance hierarchy structure. This is an abstract superclass of a group of actual drag controllers. In the idea world this things would not be necessary and list views and other widgets could control drag and drop in a flexibly enough way. Subclasses must implement the following messages: private doDrop: showDropFeedbackFor: Instance Variables: page <InspectorPage> The page for which drag and drop is controlled. view <SelectionView> The list view on the page where the drag/drop is happening. viewState <Object> Just anything a controller needs to store to save the state of the view before we started providing visual drag-and-drop feedback in it.
</comment> <class> <name>ReplaceOnlyDragController</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.DragController</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.ReplaceOnlyDragController
This is a drag-and-drop controller for inspectors that support dropping things on top of part but not inserting new things between parts. For example, a basic inspector.
</comment> <class> <name>OverriddenMethodDefinition</name> <environment>Tools.Trippy</environment> <super>Tools.MethodDefinition</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.OverriddenMethodDefinition
These method definitions represent superclass methods in a method list of a behavior inspector that have been overriden by other methods deeper down the inheritance chain of the class we are looking at.
</comment> <class> <name>SelfPart</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Part</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.SelfPart
My purposed is to simply display the object itself and provide the stylized 'self' label and appropriate icons.
</comment> <class> <name>PartVisit</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Visit</super> <private>false</private> none ownerInspector <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.PartVisit
This is a special (and the most common) case of visiting an object, when the object we visit is a part (an instance variable or a collection element) of some other object. In this case, what we remember as the 'object' is really the part of the owner we are visiting rather than the object itself. The object is supplied by the part on demand, thus avoiding any unwanted caching. This is important since the value of a part may change behind the scenes at any time. To allow inspecting siblings, we also need to remember the owner inspector, that is the inspector which was displaying the part we are visiting. It can supply us with the full list that the currently visited part was a member of. Instance Variables: ownerInspector <Inspector>
</comment> <class> <name>TextAttribute</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Part</super> <private>false</private> none label text textBlock <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.TextAttribute
This is a part that does not have a value that can be copied or set. It only provides a text that can be displayed in the inspector's right hand side pane, but cannot be dove into. Instance Variables: label <String | UserMessage> The text used to identify the part in the UI. text <Text | nil> The part text, unless generated dynamically. textBlock <BlockClosure | nil> The block that generates the part text. If nil, the text is static and is stored in the 'text' instance variable.
</comment> <class> <name>Hierarchy</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none id label root parentBlock childrenBlock <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.Hierarchy
Instances of this class can be returned by any object from the #inspectorHierarchies message to identify hierarchies the object is a member of. Instance Variables: id <Symbol> Identifier of a hierarchy, used internally by the inspector to tell hierarchies apart. The only requirement is that hierarchies returned together by a single object all have different ids. label <String | UserMessage> The text used by the UI to describe this hierarchy, such as 'Component'. root <Object | nil> The root of the hierarchy. If the root is nil, the inspector will try to discover the root by chasing parent pointers from the initial object. parentBlock <BlockClosure> A block which, given an object, returns a parent of that object in the hierarchy, or nil if the object has no parent or the parent could not be determined. childrenBlock <BlockClosure> A block which, given an object, returns a collection of children of that object in the hierarchy. If the object has no children, either an empty collection or a nil are acceptable.
</comment> <class> <name>PageDriver</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none page <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.PageDriver
Instances of this class are plug-ins that work in concert with LinearInspectorPages to support two apperances of those pages: unsegemented and segmented. A driver encapsulates the differences that exist between those appearance modes. This class provides the behaviour of unsegmented pages, i.e. those that present all keys in a single list, assuming there are not too many of them. Instance Variables: page <LinearInspectorPage> The page we are helping.
</comment> <class> <name>SegmentedPageDriver</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.PageDriver</super> <private>false</private> none segmentSize <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.SegmentedPageDriver
This is a page driver (see explanation in the superclass) that provides the behaviour of segmented pages, i.e. those that break keys into segments, or pages, and only show the keys of the currently selected page(s). Instance Variables: segmentSize <Integer> The number of keys per segment. Last segment typically contains fewer keys, of course.
</comment> <class> <name>PartListAbstractInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Inspector</super> <private>false</private> none driver segmentListHolder fieldListHolder textHolder dragController undoHistory <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.PartListAbstractInspector
A part list inspector presents an object as a collection of parts, one or more of them selectable at a time. As the number of parts can be very large, an inspector can support two interface styles. One has a single list of parts, the other uses two lists to break parts into smaller selectable segments. The behavior that depends on the type of the currently attached interface is outsourced to a separate object called a 'driver'. The driver for a single-list interface is an instance of PageDriver; the driver for a two-list interface is a SegmentedPageDriver. A driver may register itself as a dependent of some aspects of its inspector. This is an abstract class that implements some behavior reusable by subclasses and leaves parts of it up to subclasses to implement. An object is treated as a sequence of parts. A part is an instance of a subclass of Part. An inspector is responsible for generating the list of parts of the object it is open on. Becase the list can potentially be very long, the protocol for decomposing the object includes three messages that together don't require the complete list to be built. The methods are in the 'decomposing' protocol: partCount partAt: anInteger partsAtAll: integerCollection Individual parts are responsible for retrieving their values from the object, formatting values for display, etc. The following messages are used to determined whether and what parts are currently selected in the part list. hasSingleSelection -- True if exactly one part is selected. hasMultiSelection -- True if more than one part is selected. hasSelection -- True if at least one part is selected = hasSingleSelection OR hasMultiSelection. selections -- Answer a sequence of selected parts, potentially empty. selection -- If a single part is selected, answer it. Fail otherwise. These messages are used to change the selection: select: aPart selectAll: partCollection
</comment> <class> <name>BasicInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.PartListAbstractInspector</super> <private>false</private> none fixedFields sortSelector <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.BasicInspector
An inspector showing an object's instance variables, named and indexed. And object can add "extra attributes" to the list, such as 'source' and 'bytecode' of CompiledCode or 'comment' of a class. Instance Variables: fixedFields <Array of: Part> Parts representing extra attributes and named instance variables. Parts for indexed variables are cheap to create and therefore created on demand. sortSelector <Symbol> Used to sort the list of named instance variables, either by index (#lessByIndexThan:) or by name (#lessByNameThan:)
</comment> <class> <name>PreviewingInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.BasicInspector</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.PreviewingInspector
This inspector page can present any object that understands #displayOn: and #preferredBounds messages. The inspector page includes a preview area showing the object.
</comment> <class> <name>ReplacementUndo</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.UndoAction</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.ReplacementUndo
This action undoes assignment of new values to parts. It remembers the parts assigned to and their old values and restores them if applied.
</comment> <class> <name>DerivedAttribute</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Part</super> <private>false</private> none label value valueBlock <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.DerivedAttribute
An instance can be returned by any object as an element of a collection of extra attributes (see #inspectorExtraAttributes message). It identifies a part of the object which is not a physical attribute (not a named or indexed variable) but can be calculated and is important enough to show it together with "real" attributes. Instance Variables: label <String | UserMessage> The text used by the UI to identify this attribute. value <Object | nil> The value of the attribute if not calculated dynamically. valueBlock <BlockClosure | nil> The block to calculate the value of the attribute. If nil, the value is static and is stored in the 'value' instance variable.
</comment> <class> <name>SetInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.PartListAbstractInspector</super> <private>false</private> none linearized <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.SetInspector
An inspector for objects supporting the set interface, that is messages size collect: remove: add: Instance Variables: linearized <Array of: SetElements> Elements of the set, arranged in their displayStrings' increasing lexicographic order.
</comment> <class> <name>SetElement</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Part</super> <private>false</private> none element <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.SetElement
This part represents an element of a set, or some other unkeyed collection where the only thing that is known is whether an object is in the collection or not. Instance Variables: element <Object>
</comment> <class> <name>DictionaryInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.PartListAbstractInspector</super> <private>false</private> none linearizedParts valueOrKeyHolder <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.DictionaryInspector
An inspector for objects that support the following interface: size -- Answering the number of elements the object contains. keys -- Answering a collection of <size> elements. at: -- Taking one of the elements of <keys> collection and returning an object. at:put: -- Taking one of the elements of <keys> collection and any object. Typical clients are Dictionaries and KeyedCollections. Instance Variables: linearizedParts <Array of: KeyedElement> Parts representing the key-value pairs of the object, arranged in the keys' displayString lexicographic order. valueOrKeyHolder <ValueHolder with: <#key | #value>> Whether the inspector should display the value or the key of the selected element.
</comment> <class> <name>PoolDictionaryInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.DictionaryInspector</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.PoolDictionaryInspector
This is essentially a dictionary inspector with NameSpace-specific menu actions like 'browse references'.
</comment> <class> <name>SequenceInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.PartListAbstractInspector</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.SequenceInspector
An inspector for collections that support the resizeable sequence interface: size -- Answers the number of element in the sequence. The order of elements is preserved. at: -- Takes an Integer in the 1..<size> range and answers an element at that position. at:put: -- Takes an Integer in the 1..<size> range and an object and places the object at that position. add: -- Appends the argument object at the end, increasing the size by one. add:beforeIndex: -- Inserts the argument object at the specified position so that all other objects are "pushed back" in the collection. removeAtIndex: -- Removes the element at the specified index, reducing the collection size by one.
</comment> <class> <name>ArrayInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.SequenceInspector</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.ArrayInspector
An inspector for unresizeable sequences, that is collections that allow all messages listed in the SequenceInspector's comment except: add: add:beforeIndex: removeAtIndex: The inspector "cheats" to make these unresizeable sequences appear resizeable.
</comment> <class> <name>IndexedVariable</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Part</super> <private>false</private> none index <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.IndexedVariable
This part represents a part of an object that can be accessed by sending the object #basicAt: and #basicAt:put: messages. Instance Variables: index <Integer> The part index
</comment> <class> <name>TextEditorInspector</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Inspector</super> <private>false</private> none textHolder <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.TextEditorInspector
The inspector for Text and String subclasses, with a single text editor window. Accepted text is coerced to the original class of the inspected object and then becomes the inspected object. Instance Variables: textHolder <ValueHolder with: String> The model for the text editor
</comment> <class> <name>InspectorShell</name> <environment>Tools.Trippy</environment> <super>UI.ApplicationModel</super> <private>false</private> none origin trail current installedNavigator menuBarHolder evaluationPaneVisible textHolder <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.InspectorShell
This is the top-level window of the inspector. Beneath the surface, an inspector is composed of three collaborating applications: 1) A Shell, an instance of InspectorShell, provides the top-level interface elements such as the menu bar and the tool bar, and also represents the object exploration session by keeping track of the history of object visits. 2) A Navigator is a subapplication of the shell which defines the current navigation context--that is, objects we can easily choose for inspection. It also manages the possible inspectors that can be used for a given object 3) An Inspector is a subapplication of Navigator which takes care of showing the details of a particular *single* object, in a particular way. For example, imagine we looks at a hierarchy of visual parts making up a window. In this case, the top-level InspectorShell contains a HierarchyNavigator that shows all the members of a hierarchy. When a member is selected, the navigator updates the tab control to list all the inspectors (subclasses of Inspector, to be precise) that can be used to display the selected member. When an inspector class is selected, the navigators creates an instance of the selected class and installs it as the current Inspector. Instance Variables: origin <Visit> The root of the object visit tree for this inspector session. In other words, this is the visit of the object this inspector has been opened on first. trail <OrderedCollection of: Navigator> The navigators we go through with Back/Forward buttons. current <Integer> The index of the current visit of the trail. installedNavigator <Navigator> The navigator currently used. menuBarHolder <ValueHolder with: Menu> The model of the menu bar of the inspector window. evaluationPaneVisible <Boolean> Whether the evaluation pane is currently visible; affects widget layout. textHolder <ValueHolder with: Text> Evaluation pane's model Shared Variables: SharedTextHolder <ValueHolder with: Text> The holder on text that all evaluation panes share as their model so the code may be persistent within the image.
</comment> <class> <name>HierarchyNavigator</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.Navigator</super> <private>false</private> none hierarchy originalVisit hierarchyHolder root <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.HierarchyNavigator
This navigator displays a hierarchy of objects, such as a hierarchy of visual components or a class hierarchy. One of the objects is the "original"; that is the one that was the entry point into the hierarchy. For example, you find a CompositePart and select "Explore>Component Hierarchy". The hierarchy will include the full component tree with the root in the ScheduledWindow, but the CompositePart is the entry point. The inspector area always shows the currently selected hierarchy member, and the visit tree is updated as selections are made. New visits into the hierarchy members are registered as children of the original element's visit. Instance Variables: hierarchy <Hierarchy> The Hierarchy (see the class) representing the hierarchy we navigate. originalVisit <Visit> Visit of the object which was the entry point of the hierarchy (see above). hierarchyHolder <IndentedTreeSelectionInList> The model of the hierarchy view. root <Object> The root object of the hierarchy.
</comment> <class> <name>VisitTreeNavigator</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.HierarchyNavigator</super> <private>false</private> none startingVisit <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.VisitTreeNavigator
The visit tree navigator displays the tree of Visits of the container inspector shell, thus showing all objects visited in this inspector session. While this is essentially a hierarchy navigator, there are two important differences between it and the stock hierarchy navigator: 1. The objects displayed in the hierarchy list are Visits, yet objects inspected are objects of those Visits rather than Visits themselves. 2. Selecting a hierarchy element does not change the Visit tree, since navigation through the visit tree is "meta-navigation" we don't want to keep track of. 3. (so it's three important differences) Zooming in (double-clicking) on a hierarchy element does not change the visit tree but changes the trail of objects used by the shell for backward/forward movement. Instance Variables: startingVisit <Visit> The visit and originalVisit inherited from the parent are ignored and are dummy objects not hooked up to the actual visit tree of the inspector shell. This variable keeps onto the visit of the object we started to review the history from, so that we can still make the right initial selection when first opening the navigator.
</comment> <class> <name>InsertionUndo</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.UndoAction</super> <private>false</private> none newKeys <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.InsertionUndo
InsertionUndo saves the information necessary to undo insertion of new elements into an object. Instance Variables: newKeys <Collection of: Object> A collection of objects identifying the inserted parts. The kind of the keys depends on the inspector that creates the undo, since it is the inspector that will later execute the undo is necessary. The receiver is only responsible to preserving the collection, which is treated as an opaque handle.
</comment> <class> <name>InsertReplaceDragController</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.DragController</super> <private>false</private> none <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.InsertReplaceDragController
InsertReplaceDragController implements drag policy for the lists where it makes sense to both drop objects on top of elements and between elements.
</comment> <class> <name>Action</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none label actionBlock enablementBlock <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.Action
A sequence of Actions can be returned by any object in response to the #inspectorActions message. Each Action represents a user-level action this object can perform, and is presented by the inspector as menu choices. Instance Variables: label <String | UserMessage> Used by the UI to describe this action. actionBlock <BlockClosure> A 0-argument block evaluated when the user invokes the action. enablementBlock <BlockClosure> A 0-argument block evaluated by the inspector to determine if the action is available.
</comment> <class> <name>UndoActionGroup</name> <environment>Tools.Trippy</environment> <super>Tools.Trippy.UndoAction</super> <private>false</private> none actions <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.UndoActionGroup
A sequence of other UndoActions that will all be applied on order if this action is applied. Instance Variables: actions <SequenceableCollection of: UndoAction> Grouped actions.
</comment> <class> <name>Clipboard</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none parts values zeroStandIn <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.Clipboard
Clipboard implements a clipboard that can hold collections of objects copied from inspector pages. Objects are associated with their keys so they can be properly inserted when pasted as a group into another object. The clipboard normally holds onto the objects weakly so they can "fall off" the clipboard if nothing else holds onto them. However, it is possible to "lock" the clipboard so it creates an additional set of strong links to its contents. Instance Variables: parts <OrderedCollection of: Part> Collection of the most recently pasted parts. values <WeakArray of: Object> Values of the most recently pasted parts (since parts normally fetch values from their objects, captured values have to be stored separately). zeroStandIn <Object> A unique object that replaces zeros when they are pasted , to distinguish "real" pasted zeros from those that result from objects getting GCed. Shared Variables: Default <Clipboard> The clipboard instance shared by all inspectors.
</comment> <class> <name>Collaborator</name> <environment>Tools.Trippy</environment> <super>Core.Object</super> <private>false</private> none label object objectBlock varName <imports></imports> <category>Tools-Trippy</category> <attributes> <package>Tools-Trippy</package> </attributes> </class> <comment> Tools.Trippy.Collaborator
A sequence of Collaborators can be returned by any object in response to the #inspectorCollaborators message. It lists objects that are likely to be interesting to the user inspecting the receiver. For example, a View might return its Model and Controller as collaborators. Collaborators are added to the "Go" menu of the inspector. Instance Variables: label <String | UserMessage> Description of the collaborator, used in the UI--for example, as a menu item label. object <Object | nil> The collaborator object, if not determined dynamically by 'objectBlock'. objectBlock <BlockClosure | nil> The block returning the collaborator object when evaluated. If nil, the collaborator is assigned statically and stored in the 'object' variable. varName <String | nil> If the collaborator is stored in one of the instance variables of the receiver, this holds the name of the variable to help the inspector better keep track of where we are.
</comment> <name>SharedTextHolder</name> <environment>Tools.Trippy.InspectorShell</environment> <private>false</private> <constant>false</constant> <category>evaluation</category> <initializer>String new asValue</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>EvaluationPaneWasLastShown</name> <environment>Tools.Trippy.InspectorShell</environment> <private>false</private> <constant>false</constant> <category>evaluation</category> <initializer>false</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>PageSize</name> <environment>Tools.Trippy</environment> <private>false</private> <constant>false</constant> <category>Defaults</category> <initializer>200</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>CanonicalInstVarAtMethod</name> <environment>Tools.Trippy.Inspector</environment> <private>false</private> <constant>false</constant> <category>CanonicalMethodImplementations</category> <initializer>(CompiledMethod withPrimitive: 73 numArgs: 1 ifFail: [:error | nil]) mclass: nil; yourself</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>CanonicalBasicSizeMethod</name> <environment>Tools.Trippy.Inspector</environment> <private>false</private> <constant>false</constant> <category>CanonicalMethodImplementations</category> <initializer>(CompiledMethod withPrimitive: 62 numArgs: 0 ifFail: [:error | 0]) mclass: nil; yourself</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>CanonicalClassMethod</name> <environment>Tools.Trippy.Inspector</environment> <private>false</private> <constant>false</constant> <category>CanonicalMethodImplementations</category> <initializer>(CompiledMethod withPrimitive: 111 numArgs: 0 ifFail: [:error | Core.Error raiseErrorString: #errPrimitiveFailed << #dialogs >> 'a primitive has failed' asString]) mclass: nil; yourself</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>UseSimpleInspector</name> <environment>Tools.Trippy.Inspector</environment> <private>false</private> <constant>false</constant> <category>preferences</category> <initializer>false</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>CanonicalIsImmutableMethod</name> <environment>Tools.Trippy.Inspector</environment> <private>false</private> <constant>false</constant> <category>CanonicalMethodImplementations</category> <initializer>(CompiledMethod withPrimitive: 1063 numArgs: 0 ifFail: [:error | false]) mclass: nil; yourself</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>Default</name> <environment>Tools.Trippy.Clipboard</environment> <private>false</private> <constant>false</constant> <category>singleton</category> <initializer>nil</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>MaxMenuEntryWidth</name> <environment>Tools.Trippy.BehaviorInspector</environment> <private>false</private> <constant>false</constant> <category>Menus</category> <initializer>60</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <name>MaxSelectorSubMenuEntries</name> <environment>Tools.Trippy.BehaviorInspector</environment> <private>false</private> <constant>false</constant> <category>Menus</category> <initializer>20</initializer> <attributes> <package>Tools-Trippy</package> </attributes> <methods> Tools.Trippy.Navigator <category>accessing</category>
inspector ^inspector
inspector: anInspector inspector := anInspector
object ^visit object
vicinity "Identify the group of objects the navigator presents. This is used by things like the menu code to indicate the current vicinity." self subclassResponsibility
visit ^visit
</methods> <methods> Tools.Trippy.Navigator <category>initialize-release</category>
initialize: aVisit shell: aShell inspector: anInspector visit := aVisit. shell := aShell. inspector := anInspector. inspector container: self. self inspectorHolder selectionIndexHolder onChangeSend: #inspectorSelectionChanged to: self. self refreshInspectorClasses
installedWith: aBuilder
</methods> <methods> Tools.Trippy.Navigator <category>aspects</category>
inspectorHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^inspectorHolder isNil ifTrue: [inspectorHolder := SelectionInList new] ifFalse: [inspectorHolder]
</methods> <methods> Tools.Trippy.Navigator <category>private</category>
ignoringInspectorSelectionChange: aBlock | channel | channel := self inspectorHolder selectionIndexHolder. channel retractInterestsFor: self. aBlock ensure: [channel onChangeSend: #inspectorSelectionChanged to: self]
objectInspectorClasses ^Inspector cautiousInspectorClassesFor: self object
refreshInspectorClasses | selectionIndex | self ignoringInspectorSelectionChange: [inspectorClasses := self objectInspectorClasses. self inspectorHolder list: (inspectorClasses collect: [:each | each tabLabel asString copyWithout: $&]) asList. selectionIndex := inspectorClasses indexOf: inspector class. self inspectorHolder selectionIndex: selectionIndex. inspectorCache := Array new: inspectorClasses size. inspectorCache at: selectionIndex put: inspector]
reinstallInspector | newBuilder tabControl | inspector builder: nil. tabControl := (builder componentAt: #inspector) widget. tabControl client: inspector spec: inspector specName builder: (newBuilder := builder newSubBuilder). inspector installedWith: newBuilder
replaceInspectorWithOneOn: anObject | newClass newInspector index | inspectorClasses := self objectInspectorClasses. newClass := (inspectorClasses includes: inspector class) ifTrue: [inspector class] ifFalse: [inspectorClasses first]. newInspector := newClass on: anObject. inspector copyStateTo: newInspector. inspector := newInspector. builder notNil ifTrue: [self reinstallInspector]. shell focusObjectChanged. self ignoringInspectorSelectionChange: [self inspectorHolder list: (inspectorClasses collect: [:each | each tabLabel asString copyWithout: $&]). inspectorCache := Array new: inspectorClasses size. index := inspectorClasses indexOf: inspector class. self inspectorHolder selectionIndex: index. inspectorCache at: index put: inspector]
</methods> <methods> Tools.Trippy.Navigator <category>inspector container</category>
back "Sent by the contained inspector to go back in the visit trail." ^shell back
canGoBack "Sent by the contained inspector to see if it's possible to go back in the visit trail." ^shell canGoBack
diveInto: aPart "Sent by the contained inspector to dive into its part." ^shell diveInto: aPart
partValueChanged: aPart ^shell partValueChanged: aPart
</methods> <methods> Tools.Trippy.Navigator <category>notifications</category>
changeRequest ^self inspector changeRequest
inspectorSelectionChanged | index newBuilder | index := self inspectorHolder selectionIndex. inspector := (inspectorCache at: index) isNil ifTrue: [inspectorCache at: index put: ((inspectorClasses at: index) on: self object)] ifFalse: [inspectorCache at: index]. inspector builder: nil. (builder componentAt: #inspector) widget client: inspector spec: inspector specName builder: (newBuilder := builder newSubBuilder). inspector installedWith: newBuilder. shell focusObjectChanged "it didn't but the UI update may be needed anyway"
</methods> <methods> Tools.Trippy.Navigator <category>privileged</category>
doWithOwnersToIgnore: aBlock "See the comment to Inspector>>doWithOwnersToIgnore: for a detailed explanation. Passing the buck to the real top component." shell doWithOwnersToIgnore: aBlock
enumerateOwnersToIgnore: aBlock aBlock value: self. aBlock value: visit. inspector enumerateOwnersToIgnore: aBlock
</methods> <methods> Tools.Trippy.Navigator class <category>instance creation</category>
visit: aVisit shell: aShell ^self new initialize: aVisit shell: aShell inspector: ((Inspector cautiousInspectorClassesFor: aVisit object) first on: aVisit object)
visit: aVisit shell: aShell inspector: anInspector ^self new initialize: aVisit shell: aShell inspector: anInspector
</methods> <methods> Tools.Trippy.NullNavigator <category>accessing</category>
vicinity ^#none
</methods> <methods> Tools.Trippy.NullNavigator <category>initialize-release</category>
postBuildWith: aBuilder self reinstallInspector
</methods> <methods> Tools.Trippy.ObjectSegment <category>comparing</category>
< another ^firstIndex < another firstIndex
= another ^firstIndex = another firstIndex
hash ^firstIndex hash
</methods> <methods> Tools.Trippy.ObjectSegment <category>accessing</category>
firstIndex ^firstIndex
lastIndex ^lastIndex
range ^self firstIndex to: self lastIndex
</methods> <methods> Tools.Trippy.ObjectSegment <category>displaying</category>
displayString ^(Inspector safeDisplayStringOf: firstPart) , ' ... ' , (Inspector safeDisplayStringOf: lastPart)
</methods> <methods> Tools.Trippy.ObjectSegment <category>initialize-release</category>
from: anInteger part: aPart to: anotherInteger part: anotherPart firstIndex := anInteger. firstPart := aPart. lastIndex := anotherInteger. lastPart := anotherPart
</methods> <methods> Tools.Trippy.InspectorHolder <category>inspector container</category>
back self shouldNotImplement
canGoBack ^false
diveInto: aPart aPart value inspect
doWithOwnersToIgnore: aBlock "See the comment to Inspector>>doWithOwnersToIgnore: for a detailed explanation. This class is the top component, therefore here we start trickling down enumerating junk owners on our way." self enumerateOwnersToIgnore: aBlock
enumerateOwnersToIgnore: aBlock aBlock value: self; value: builder window; value: builder window component. inspector enumerateOwnersToIgnore: aBlock
inspector ^inspector
partValueChanged: aPart "We don't keep track of any object visits."
</methods> <methods> Tools.Trippy.InspectorHolder <category>initialize-release</category>
initialize: anInspector inspector := anInspector. inspector container: self
postBuildWith: aBuilder | subBuilder | (aBuilder componentAt: #inspector) widget client: inspector spec: inspector specName builder: (subBuilder := aBuilder newSubBuilder). inspector installedWith: subBuilder
</methods> <methods> Tools.Trippy.InspectorHolder class <category>instance creation</category>
with: anInspector ^self new initialize: anInspector
withInspectorOn: anObject | inspector | inspector := (Inspector cautiousInspectorClassesFor: anObject) first on: anObject. ^self new initialize: inspector
</methods> <methods> Tools.Trippy.Visit <category>initialize-release</category>
initialize children := OrderedCollection new
object: anObject owner: aVisitOrNil object := anObject. owner := aVisitOrNil. owner notNil ifTrue: [owner addChild: self]
</methods> <methods> Tools.Trippy.Visit <category>testing</category>
hasOwner ^owner notNil
</methods> <methods> Tools.Trippy.Visit <category>accessing</category>
addChild: aVisit children add: aVisit
children ^children
forgetVisitOf: anObject children remove: (self visitOf: anObject ifNone: [^self])
forgetVisitOfPart: aPart children remove: (self visitOfPart: aPart ifNone: [^self])
object ^object
owner ^owner
visitOf: anObject ifNone: aBlock ^children detect: [:some | some object == anObject] ifNone: aBlock
visitOfPart: aPart ifNone: aBlock ^children detect: [:some | (some respondsTo: #ownerPart) and: [some ownerPart = aPart]] ifNone: aBlock
</methods> <methods> Tools.Trippy.Visit <category>printing</category>
displayString | printString | printString := Inspector safeBasicPrintStringOf: self object. ^(Inspector isImmutableObject: self object) ifTrue: [printString , ' (' , (#immutable << #dialogs >> 'immutable') asString , ')'] ifFalse: [printString]
printOn: aStream aStream nextPut: $<; print: self class; nextPutAll: ' object: '; print: self object; nextPut: $>
</methods> <methods> Tools.Trippy.Visit <category>privileged</category>
enumerateOwnersToIgnore: aBlock aBlock value: self. children do: [:each | each enumerateOwnersToIgnore: aBlock]
</methods> <methods> Tools.Trippy.Visit class <category>instance creation</category>
new ^super new initialize
object: anObject ^self new object: anObject owner: nil
object: anObject owner: aVisit ^self new object: anObject owner: aVisit
</methods> <methods> Tools.Trippy.Inspector <category>initialize-release</category>
container: anApplication container := anApplication
copyStateFromBehavior: anInspector "An inspector receives this just after it becomes the current, with the one that used to be the current passed as the argument. This is the chance to copy appropriate selections, etc. from the old inspector."
copyStateFromPartList: anInspector "An inspector receives this just after it becomes the current, with the one that used to be the current passed as the argument. This is the chance to copy appropriate selections, etc. from the old inspector."
initialize: anObject object := anObject. self refresh
initialize: anObject container: anApplication object := anObject. container := anApplication. self refresh
installedWith: aBuilder "Sent by the container after installation of the inspector interface is finished. This gives a chance to perform actions that depend on bounds of components being available, most notably #makeVisible:. It is also a very good idea to remember the builder because in the inspector framework models outlive interfaces and builders come and go." self builder: aBuilder
</methods> <methods> Tools.Trippy.Inspector <category>accessing</category>
object "Answer the object being inspected." ^object
selectedObjectOrInspectedObject ^self object
undoExplanation "Answer a string with an explanation of the possible undo action, or an empty string if no explanation is available." ^''
</methods> <methods> Tools.Trippy.Inspector <category>properties</category>
specName "Answer the name of the interface spec to use; some pages select the interface at runtime based on the properties of the object they inspect." ^#windowSpec
</methods> <methods> Tools.Trippy.Inspector <category>testing</category>
canDive "A generic page has no idea of a selection that we can dive into." ^false
canUndo "Answer whether the current inspector can undo the previous editing action. A generic page keeps no undo history and cannot undo anything." ^false
isPartList "Answer true if the inspector presents a logical view on an object as a collection of selectable parts. In general, this is not true." ^false
</methods> <methods> Tools.Trippy.Inspector <category>actions</category>
browseClass "Open a browser on the inspector object." self selectedObjectOrInspectedObject browse
changeRequest "Sent by the container application, just before destroying this inspector (by switching to another object, closing the window, etc). Answer a boolean indicating whether it is OK to do so. Do something to preserve unsaved changes if there are any." ^true
copyStateTo: anInspector "A subclass should implement this by sending an appropriate #copyStateFrom...: message to the argument inspector." self subclassResponsibility
inspectOwners | owners | owners := self selectedObjectOrInspectedObject allOwnersWeakly: true. self nukeBogusReferencesIn: owners referentContext: thisContext. ObjectMemory globalGarbageCollect. (owners reject: [:each | owners tombstone == each]) inspect
inspectReferencePath "Inspect the shortest path." #{ReferencePathCollector} ifDefinedDo: [:collectorClass | Cursor execute showWhile: [| collector allPaths | ObjectMemory globalGarbageCollect. collector := collectorClass new. self doWithOwnersToIgnore: [:junkReference | collector ignore: junkReference]. allPaths := collector allReferencePathsTo: self selectedObjectOrInspectedObject. allPaths inspect]]
selectAll "Subclasses should implement this to select 'all fields', whatever is their idea of what those fields are." self builder keyboardProcessor currentConsumer userSelectsAll
spawn "Spawn another top-level inspector window." self selectedObjectOrInspectedObject inspect
</methods> <methods> Tools.Trippy.Inspector <category>private</category>
container "Answer the higher-level application I belong to. It is typically either a Navigator if I am part of a full-blown inspector, or an InspectorHolder if I am an inspector embedded inside some other application and focused on a specific object, with no view switches or navigation possibilities." ^container isNil ifTrue: [builder window model] ifFalse: [container]
doWithOwnersToIgnore: aBlock "This is the entry point of the mechanism that allows filtering unnecessary objects for operations like inspecting all owners or finding a reference path. This message bubbles up to the top component of the inspector--either an InspectorShell or an InspectorHolder; possible by way of a Navigator. From there, the message #enumerateOwnersToIgnore: is downcast to all parts of the inspector. That message is what really does enumerate the junk owners." self container doWithOwnersToIgnore: aBlock
enumerateOwnersToIgnore: aBlock aBlock value: self
makeSelfPerformerOf: aMenu "The current menu implementation routes messages generated by a menu item to the menu item's menu bar performer. It is a complete brain damage. This utility method hacks the menu so the messages are routed to this page instead. Ugly but less so than the alternatives." aMenu menuItems do: [:each | | itemValue | itemValue := each value. itemValue isSymbol ifTrue: [each value: [self perform: itemValue]]]
nukeBogusReferencesIn: aWeakArray referentContext: aContext | ignoreThese | ignoreThese := IdentitySet new: 10. self doWithOwnersToIgnore: [:each | ignoreThese add: each]. 1 to: aWeakArray size do: [:index | | element | element := aWeakArray at: index. ((ignoreThese includes: element) or: [element == aContext]) ifTrue: [aWeakArray at: index put: aWeakArray tombstone]]
refresh "Sent by self after the 'object' instance variable has been changed. Implementations should update all secondary data structures and widgets as needed." self subclassResponsibility
</methods> <methods> Tools.Trippy.Inspector <category>menu management</category>
addObject: anObject actionsTo: aMenu "Object actions are actions published by the object using #inspectorActions method." | actions | actions := Inspector cautiousSend: #inspectorActions to: anObject else: [Array new]. actions isEmpty ifTrue: [^self]. aMenu addLine. actions do: [:each | | item | item := MenuItem labeled: each label. item enablement: each enablement. item value: [each perform]. aMenu addItem: item]
addObjectActionsTo: aMenu "Object actions are actions published by the object using #inspectorActions method." self addObject: self object actionsTo: aMenu
addObjectSubmenuTo: aMenu | objectItem objectSubmenu | objectItem := MenuItem labeled: (#_Object << #dialogs >> '&Object'). objectItem nameKey: #objectMenu. objectSubmenu := self class baseObjectSubmenu. self makeSelfPerformerOf: objectSubmenu; addObjectActionsTo: objectSubmenu. objectItem submenu: objectSubmenu. aMenu addItem: objectItem atPosition: 10.001. (aMenu atNameKey: #objectReferencePath) enabled: [#{ReferencePathCollector} isDefined]
augmentMenuBar: aMenu "The containter gives us a chance to add things to the main window menu bar." self addObjectSubmenuTo: aMenu
</methods> <methods> Tools.Trippy.Inspector class <category>instance creation</category>
on: anObject ^self new initialize: anObject
on: anObject in: anApplication ^self new initialize: anObject container: anApplication
</methods> <methods> Tools.Trippy.Inspector class <category>accessing</category>
tabLabel "Answer a String to use as a tab label of a page containing this inspector." self subclassResponsibility
useSimpleInspector ^UseSimpleInspector
useSimpleInspector: aBoolean "When set to true, Object>>inspect opens the old (classic) inspector. The default value is false, to open Trippy." "self useSimpleInspector: true" "self useSimpleInspector: false" UseSimpleInspector := aBoolean
</methods> <methods> Tools.Trippy.Inspector class <category>utilities</category>
forEmbeddingOn: anObject "Create and answer a subapplication inspecting the argument as a standalone (i.e. old-style non-diving or navigating) inspector." ^InspectorHolder withInspectorOn: anObject
openOn: anObject "Open a new top-level window to inspect the argument." ^InspectorShell openOn: anObject
</methods> <methods> Tools.Trippy.Inspector class <category>utilities-printing</category>
basicObjectPrintString: anObject "Answer a basic print string of anObject without sending any messages to it." | aStream class | aStream := WriteStream on: (String new: 16). class := self classOfObject: anObject. aStream nextPutAll: (class name first isVowel ifTrue: ['an '] ifFalse: ['a ']); print: class. ^aStream contents
bulletproofLabelStringOf: anObject "Time limit the safeLabelStringOf:. Additionally protect against halts in the print logic. This method should be used sparingly, in sutuations when we absolutely must avoid bringing up the debugger--mainly, inside the debugger itself." ^[[self safeLabelStringOf: anObject] valueWithinSeconds: 1 orDo: [self safeBasicPrintStringOf: anObject]] on: HaltInterrupt do: [:ex | [self safeBasicPrintStringOf: anObject] on: HaltInterrupt do: [:ex2 | #ErrorPrintingTheObject << #labels >> 'Error printing the object']]
safeBasicPrint: anObject on: aStream | objectClass title | ^[objectClass := self classOfObject: anObject. title := objectClass name. aStream nextPut: $a. (title at: 1) isVowel ifTrue: [aStream nextPut: $n]. aStream nextPut: $ . aStream print: objectClass] on: Error do: [:ex | aStream nextPutAll: (#ErrorPrintingObject << #dialogs >> '[Error printing the object: <1s>]' expandMacrosWith: ex description). ex return]
safeBasicPrintStringOf: anObject ^[self basicObjectPrintString: anObject] on: self safePrintingErrors do: [:ex | ex return: ((#ErrorPrintingObject << #dialogs >> '[Error printing the object: <1s>]') expandMacrosWith: ex description)]
safeDisplayStringOf: anObject ^[anObject displayString] on: self safePrintingErrors do: [:ex | ex return: (#ErrorPrintingObject << #dialogs >> '[Error printing the object: <1s>]' expandMacrosWith: ex description)]
safeLabelStringOf: anObject "Answer a string representation of anObject short enough and line break-free, for use in contexts such as a list view. Unlike safeDisplayString, favor the programmer perspective (that is, printString) and try hard to give a useful answer by falling back to basic print string if printString fails." ^[ | string | string := anObject printString. (string size > 40 or: [string trimBlanks isEmpty or: [(string includes: Character cr) or: [string includes: Character lf]]]) ifTrue: [anObject basicPrintString] ifFalse: [string] ] on: Error, BreakInterrupt do: [:ex | ex return: (self safeBasicPrintStringOf: anObject)]
safePrint: anObject on: aStream ^[anObject printOn: aStream] on: self safePrintingErrors do: [:ex | aStream nextPutAll: (#ErrorPrintingObject << #dialogs >> '[Error printing the object: <1s>]' expandMacrosWith: ex description). ex return]
safePrintingErrors ^Error , BreakInterrupt, HaltInterrupt
safePrintStringOf: anObject ^[anObject printString] on: self safePrintingErrors do: [:ex | ex return: (#ErrorPrintingObject << #dialogs >> '[Error printing the object: <1s>]' expandMacrosWith: ex description)]
</methods> <methods> Tools.Trippy.Inspector class <category>utilities-object queries</category>
basicSizeOfObject: anObject "Fetch the inst var of anObject without depending on anObject's implementation." ^CanonicalBasicSizeMethod valueWithReceiver: anObject arguments: #()
cautiousInspectorClassesFor: anObject | inspectors | inspectors := self cautiousSend: #inspectorClasses to: anObject else: [Array with: BasicInspector]. ^inspectors copyWith: BehaviorInspector
cautiousSend: aUnarySelector to: anObject else: aBlock | objectClass | objectClass := self classOfObject: anObject. ^(objectClass canUnderstand: aUnarySelector) ifTrue: [anObject perform: aUnarySelector] ifFalse: [aBlock value]
classOfObject: anObject "Determine the class of anObject without sending it's normal class method." ^CanonicalClassMethod valueWithReceiver: anObject arguments: #()
instVarOfObject: anObject at: anIndex "Fetch the inst var of anObject without depending on anObject's implementation." ^CanonicalInstVarAtMethod valueWithReceiver: anObject arguments: (Array with: anIndex)
isImmutableObject: anObject "Determine whether anObject is immutable, without using the object directly." ^CanonicalIsImmutableMethod valueWithReceiver: anObject arguments: #()
</methods> <methods> Tools.Trippy.BehaviorInspector <category>testing</category>
hasSingleSelection ^self methodListHolder selectionIndexes size = 1
isAtInstanceSide ^self sideHolder value = #instance
</methods> <methods> Tools.Trippy.BehaviorInspector <category>aspects</category>
methodListHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^methodListHolder isNil ifTrue: [methodListHolder := MultiSelectionInList new] ifFalse: [methodListHolder]
protocolListHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^protocolListHolder isNil ifTrue: [protocolListHolder := MultiSelectionInList new] ifFalse: [protocolListHolder]
sideHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^sideHolder isNil ifTrue: [sideHolder := nil asValue] ifFalse: [sideHolder]
textHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^textHolder isNil ifTrue: [textHolder := String new asValue] ifFalse: [textHolder]
</methods> <methods> Tools.Trippy.BehaviorInspector <category>private-updating</category>
methodSelectionChanged self updateText
protocolSelectionChanged self updateMethodList
refresh | selectedProtocols selectedMethods | selectedProtocols := self protocolListHolder selections. selectedMethods := self methodListHolder selections. self updateProtocolList. self protocolListHolder selections: selectedProtocols. self methodListHolder selections: selectedMethods
sideSelectionChanged inheritanceStop := self isAtInstanceSide ifTrue: [inheritanceStop soleInstance] ifFalse: [inheritanceStop class]. self updateProtocolList
updateMethodList self methodListHolder list: self computeMethodList
updateProtocolList self protocolListHolder list: self computeProtocolList
updateText self textHolder value: self computeText
</methods> <methods> Tools.Trippy.BehaviorInspector <category>initialize-release</category>
configureCodeViewController: aController | menu | aController initializeMenuForCode; autoAccept: false; doNotHandleLocally: #formatSelection. "The menu must be copied before chaging items, or else the shared menu in the class would be changed." menu := aController menu copy. aController menuHolder value: menu. (menu menuItemWithValue: #formatSelection) label: (#Format << #menus >> 'Format') asString
initialize super initialize. self protocolListHolder selectionIndexHolder onChangeSend: #protocolSelectionChanged to: self. self sideHolder value: #instance; onChangeSend: #sideSelectionChanged to: self. self methodListHolder selectionIndexHolder onChangeSend: #methodSelectionChanged to: self
initialize: anObject object := anObject. inheritanceStop := self noInheritanceInheritanceStop. self objectIsClass ifTrue: [self sideHolder value: #class]. super initialize: anObject
postBuildWith: aBuilder super postBuildWith: aBuilder. (aBuilder componentAt: #methodList) widget displayStringSelector: #simpleReverseDisplayString. self configureCodeViewController: (aBuilder componentAt: #text) widget controller
</methods> <methods> Tools.Trippy.BehaviorInspector <category>private</category>
changeRequest ^self updateRequest
classObject "Answer the class object we are to extract methods and other information from. Behaviors don't need a meta-jump because for them we simply flip the instance/class switch, to keeping everything relative to the non-metaobject base." ^self objectIsClass ifTrue: [self isAtInstanceSide ifTrue: [object] ifFalse: [object class]] ifFalse: [self isAtInstanceSide ifTrue: [object class] ifFalse: [object class class]]
definitionClassOf: aSelector from: implementingClass for: inheritingClass "Answer which of the classes for method definitions, regular MethodDefinition or OverriddenMethodDefinition is correct to represent a method with aSelector defined in implementingClass when presenting messages understood by inheritingClass." | thisClass | thisClass := inheritingClass. [thisClass ~~ implementingClass and: [thisClass notNil]] whileTrue: [(thisClass includesSelector: aSelector) ifTrue: [^OverriddenMethodDefinition]. thisClass := thisClass superclass]. ^MethodDefinition
hasUnacceptedChanges self builder isNil ifTrue: [^false]. ^(self controllerAt: #text) textHasChanged
inheritanceStop: aClass "Set the last class up the superclass chain whose methods are included into what is displayed." | originalSelections | inheritanceStop := aClass. self isAtInstanceSide ifFalse: [inheritanceStop := inheritanceStop class]. originalSelections := self protocolListHolder selections. self updateProtocolList. self protocolListHolder selections: originalSelections
interestingClasses "Answer a collection of classes we are to collect methods from, in the order from the inspected class towards superclasses. They depend on the inheritance visibility setting." | answer this | answer := OrderedCollection new. this := self classObject. [this notNil ifTrue: [answer add: this]. this == inheritanceStop or: [this isNil]] whileFalse: [this := this superclass]. ^answer
interestingMethods | theClass methods | theClass := self classObject. methods := OrderedCollection new: 10. self interestingClasses do: [:eachClass | eachClass selectors do: [:eachSelector | | defClass | defClass := self definitionClassOf: eachSelector from: eachClass for: theClass. methods add: (defClass class: theClass implementor: eachClass selector: eachSelector)]]. ^methods
noInheritanceInheritanceStop ^self nonMetaClassObject
nonMetaClassObject "Answer the object suitable to get things such as the class definition from." ^self classObject instanceBehavior
objectIsClass ^object isBehavior and: [object isMeta not]
okToUpdate | choice | choice := Dialog choose: (#AcceptUnsavedTextChanges << #dialogs >> 'Accept unsaved text changes?') labels: (Array with: (#Yes << #dialogs >> 'Yes') with: (#No << #dialogs >> 'No') with: (#Cancel << #dialogs >> 'Cancel')) values: #(#yes #no #cancel) default: #yes. choice = #cancel ifTrue: [^false]. choice = #yes ifTrue: [self acceptText]. ^true
rootMinusOneInheritanceStop "Answer a class one step before Object in the argument object class inheritance chain." | last superclass | last := self nonMetaClassObject. [(superclass := last superclass) == Object or: [superclass isNil]] whileFalse: [last := superclass]. ^last
updateRequest ^super updateRequest and: [self hasUnacceptedChanges not or: [self okToUpdate]]
</methods> <methods> Tools.Trippy.BehaviorInspector <category>accessing</category>
selectedObject ^self methodListHolder selections asArray first
</methods> <methods> Tools.Trippy.BehaviorInspector <category>actions</category>
copyStateFromBehavior: aBehaviorInspector self sideHolder value ~= aBehaviorInspector sideHolder value ifTrue: [self sideHolder value: aBehaviorInspector sideHolder value]. self protocolListHolder selections: aBehaviorInspector protocolListHolder selections. self methodListHolder selections: aBehaviorInspector methodListHolder selections
copyStateTo: aPage aPage notNil ifTrue: [aPage copyStateFromBehavior: self]
findMethod | selector matchingMethods chosenMethod | selector := '*'. [selector := Dialog request: (#FindSelectorC << #dialogs >> 'Find selector:') initialAnswer: selector. selector isEmpty ifTrue: [^self]. selector := '*' , selector , '*'. matchingMethods := (self interestingMethods select: [:each | selector match: each selector]) asSortedCollection. matchingMethods isEmpty and: [Dialog confirm: (#NoSelectorFound << #dialogs >> 'No selectors found.<n>Search again?') expandMacros]] whileTrue. matchingMethods isEmpty ifTrue: [^self]. chosenMethod := matchingMethods detect: [:each | each selector asString = selector] ifNone: [matchingMethods detect: [:each | each selector asString = selector asLowercase] ifNone: [matchingMethods size == 1 ifTrue: [matchingMethods first] ifFalse: [Dialog choose: (#MatchingMethodsC << #dialogs >> 'Matching methods:') fromList: (matchingMethods collect: [:each | each simpleReverseDisplayString]) values: matchingMethods lines: 20 cancel: [^self]]]]. self selectProtocol: chosenMethod protocol; selectMethod: chosenMethod
selectorDoubleClicked "Not sure yet about the proper action here."
sendAndDive "Send the message and dive into the result." | selector result | selector := self selectedMethod selector. selector numArgs ~= 0 ifTrue: [^self]. result := self doItReceiver perform: selector. self container diveInto: (DerivedAttribute label: ((#x1sCSent2s << #dialogs >> '<1s>: sent <2s>') expandMacrosWith: Time now printString with: selector printString) value: result)
sendIt ^self doItReceiver perform: self selectedMethod selector
</methods> <methods> Tools.Trippy.BehaviorInspector <category>private-menus</category>
augmentMenu: aMenu forMethod: aMethodDefinition | selector selectors | selector := aMethodDefinition selector. selectors := aMethodDefinition method allSymbolLiterals. selectors remove: selector ifAbsent: []. selectors := selectors asSortedCollection. #(senders implementors localSenders localImplementors) with: #(browseAllSenders: browseAllImplementors: browseLocalSenders: browseLocalImplementors:) do: [:menuKey :browseSelector | (aMenu atNameKey: menuKey) submenu: (self buildSelectorSubmenuFor: selector with: selectors performing: browseSelector)]. (aMenu atNameKey: #referencedClasses) submenu: (self buildReferencesSubmenuFor: aMethodDefinition); value: nil
augmentMenuBar: aMenu "This is a chance to add our own items to the main window menu bar. Add the Inheritance dropdown to it." | visibilitySubmenu | super augmentMenuBar: aMenu. visibilitySubmenu := MenuItem labeled: (#Inheritance << #menus >> '&Inheritance'). visibilitySubmenu submenu: [self buildInheritanceSubmenu]. aMenu addItem: visibilitySubmenu atPosition: 10.005
buildInheritanceSubmenu | menu nonMetaStop | menu := Menu new. nonMetaStop := inheritanceStop instanceBehavior. self nonMetaClassObject withAllSuperclasses reverseDo: [:each | | item | item := MenuItem labeled: each name. each == nonMetaStop ifTrue: [item beOn]. item value: [self inheritanceStop: each]. menu addItem: item]. ^menu
buildMethodListMenu | menu | menu := self class methodListMenu. self singleMethodIsSelected ifTrue: [self augmentMenu: menu forMethod: self selectedMethod] ifFalse: [self disableCrossReferenceItemsIn: menu]. menu augmentFrom: self class to: BehaviorInspector menuName: #methodList for: self. ^menu
buildProtocolListMenu | menu | menu := self class protocolListMenu. menu augmentFrom: self class to: BehaviorInspector menuName: #protocolList for: self. ^menu
buildReferencesSubmenuFor: aMethodDefinition | menu item classes | menu := Menu new. classes := self classesReferencedFrom: aMethodDefinition. classes isEmpty ifTrue: [item := MenuItem labeled: (#none << #dialogs >> '(none)'). item disable. menu addItem: item. ^menu]. (classes copyFrom: 1 to: (classes size min: MaxSelectorSubMenuEntries)) do: [:each | item := MenuItem labeled: (each name asString contractTo: MaxMenuEntryWidth). item value: [self browseReferencedClass: each]. menu addItem: item]. classes size > MaxSelectorSubMenuEntries ifTrue: [item := MenuItem labeled: (#MoreClassesDot << #menus >> 'more classes...'). item labelText: (Text string: item rawLabel asString emphasis: #(#bold)). item value: [self browseReferencedClass: nil]. menu addLine; addItem: item]. ^menu
buildSelectorSubmenuFor: aSelector with: selectorCollection performing: browseSelector | menu item | menu := Menu new. item := MenuItem labeled: (aSelector contractTo: MaxMenuEntryWidth). item value: [self perform: browseSelector with: aSelector]. menu addItem: item; addLine. selectorCollection isEmpty ifFalse: [menu addLine. (selectorCollection copyFrom: 1 to: (selectorCollection size min: MaxSelectorSubMenuEntries)) do: [:each | item := MenuItem labeled: (each contractTo: MaxMenuEntryWidth). item value: [self perform: browseSelector with: each]. menu addItem: item]. selectorCollection size > MaxSelectorSubMenuEntries ifTrue: [item := MenuItem labeled: (#MoreSelectorsDot << #menus >> 'more selectors...'). item labelText: (Text string: item rawLabel asString emphasis: #(#bold)). item value: [self perform: browseSelector with: nil]. menu addLine; addItem: item]]. ^menu
disableCrossReferenceItemsIn: aMenu #(senders implementors localSenders localImplementors referencedClasses) do: [:menuKey | (aMenu atNameKey: menuKey) disable]
methodListMenu ^[self buildMethodListMenu]
protocolListMenu ^[self buildProtocolListMenu]
</methods> <methods> Tools.Trippy.BehaviorInspector <category>private-method list</category>
browseAllImplementors: aSymbol | methodCollector | methodCollector := MethodCollector new. methodCollector browseSelect: (methodCollector implementorsOf: (self pickOneSelector: aSymbol ifCancelled: [^self]))
browseAllSenders: aSymbol | methodCollector | methodCollector := MethodCollector new. methodCollector browseSelect: (methodCollector referencesTo: (self pickOneSelector: aSymbol ifCancelled: [^self]))
browseLocalImplementors: aSymbol | methodCollector | methodCollector := MethodCollector new. methodCollector browseSelect: (methodCollector searchClassHierarchy: self classObject) & (methodCollector implementorsOf: (self pickOneSelector: aSymbol ifCancelled: [^self]))
browseLocalSenders: aSymbol | methodCollector | methodCollector := MethodCollector new. methodCollector browseSelect: (methodCollector searchClassHierarchy: self classObject) & (methodCollector referencesTo: (self pickOneSelector: aSymbol ifCancelled: [^self]))
browseReferencedClass: aClass | realClass classes | realClass := aClass notNil ifTrue: [aClass] ifFalse: [classes := self classesReferencedFrom: self selectedMethod. Dialog choose: (#BrowseWhichClass << #dialogs >> 'Browse which class?') fromList: classes values: classes lines: 20 cancel: [^self] for: self mainWindow]. SmalltalkWorkbench browseClass: realClass
canRemoveMethods ^self methodListHolder selectionIndexes size > 0
chooseSelector: aSymbol from: aMethodDefinition | messages | messages := aMethodDefinition method allSymbolLiterals asSortedCollection. ^Dialog choose: aSymbol expandMacros fromList: messages values: messages lines: 20 cancel: []
classesReferencedFrom: aMethodDefinition | classes | classes := Set new. aMethodDefinition method allLiterals do: [:each | (each isVariableBinding and: [each value isBehavior]) ifTrue: [classes add: each value]]. ^classes asSortedCollection: [:a :b | a name < b name]
computeMethodList | protocols includeUnclassified methods classOrder theClass | protocols := self protocolListHolder selections. protocols isEmpty ifTrue: [^self listAllMethods]. (protocols includes: self unclassifiedProtocol) ifTrue: [protocols := protocols copyWithout: self unclassifiedProtocol. includeUnclassified := true] ifFalse: [includeUnclassified := false]. methods := OrderedCollection new. classOrder := self interestingClasses asArray. theClass := self classObject. self interestingClasses do: [:eachClass | | selectors | selectors := eachClass organization listAtCategoriesNamed: protocols. includeUnclassified ifTrue: [selectors addAll: (eachClass selectors reject: [:some | eachClass organization includesElement: some])]. methods addAll: (selectors collect: [:eachSelector | | defClass | defClass := self definitionClassOf: eachSelector from: eachClass for: theClass. defClass class: theClass implementor: eachClass selector: eachSelector])]. methods := methods asSortedCollection: [:a :b | a selector = b selector ifFalse: [a selector <= b selector] ifTrue: [(classOrder indexOf: a implementingClass) <= (classOrder indexOf: b implementingClass)]]. ^methods asList
listAllMethods | methods classOrder theClass | methods := OrderedCollection new. classOrder := self interestingClasses asArray. theClass := self classObject. self interestingClasses do: [:eachClass | methods addAll: (eachClass selectors collect: [:eachSelector | | defClass | defClass := self definitionClassOf: eachSelector from: eachClass for: theClass. defClass class: theClass implementor: eachClass selector: eachSelector])]. methods := methods asSortedCollection: [:a :b | a selector = b selector ifFalse: [a selector <= b selector] ifTrue: [(classOrder indexOf: a implementingClass) <= (classOrder indexOf: b implementingClass)]]. ^methods asList
makeMethodSelectionVisible | selectedIndex | selectedIndex := self methodListHolder selectionIndexes detect: [:any | true] ifNone: [^self]. (self widgetAt: #methodList) makeVisible: selectedIndex
pickOneSelector: aSymbolOrNil ifCancelled: aBlock | selector | selector := aSymbolOrNil isNil ifTrue: [self chooseSelector: (#BrowseAllImplementors << #dialogs >> 'View all implementors<n>of which selector?') from: self selectedMethod] ifFalse: [aSymbolOrNil]. selector isNil ifTrue: [^aBlock value]. ^selector
removeMethods | removableMethods thisClass | thisClass := self classObject. removableMethods := self methodListHolder selections select: [:some | some implementingClass == thisClass]. removableMethods size = 0 ifTrue: [^self]. (Dialog confirm: (removableMethods size = 1 ifTrue: [(#ReallyRemoveThisMethod << #dialogs >> 'Really remove this method?')] ifFalse: [(#ReallyRemoveTheseMethods << #dialogs >> 'Really remove these methods?')])) ifFalse: [^self]. removableMethods do: [:each | thisClass removeSelector: each selector]. self updateMethodList
selectedMethod ^self methodListHolder selections asArray first
selectMethod: aMethodDefinition self methodListHolder selections: (Set with: aMethodDefinition). self makeMethodSelectionVisible
selectSelector: aSymbol | definition | definition := self methodListHolder list detect: [:some | some selector = aSymbol] ifNone: [nil]. self methodListHolder selections: (Set with: definition). self makeMethodSelectionVisible
singleMethodIsSelected ^self methodListHolder selectionIndexes size = 1
singleUnaryMethodIsSelected ^self singleMethodIsSelected and: [self selectedMethod selector numArgs = 0]
</methods> <methods> Tools.Trippy.BehaviorInspector <category>private-protocol list</category>
addProtocol | newProtocol selections selection | self changeRequest ifFalse: [^self]. newProtocol := Dialog request: (#EnterNewProtocolName << #dialogs >> 'Enter new protocol name') initialAnswer: (#protocolName << #dialogs >> 'protocol name'). newProtocol isEmpty ifTrue: [^self]. newProtocol := newProtocol asSymbol. selections := self protocolListHolder selections. selection := selections size = 1 ifTrue: [selections asArray first] ifFalse: [nil]. self classObject organization addCategory: newProtocol before: selection. SourceFileManager default logChange: ('<1p> organization addCategory: <2p> before: <3p>' expandMacrosWith: self classObject with: newProtocol with: selection). self classObject reorganize. self updateProtocolList; selectProtocol: newProtocol
canRemoveProtocol ^self protocolListHolder selectionIndexes size > 0
canRenameProtocol ^self protocolListHolder selectionIndexes size = 1
computeProtocolList "Make sure to include a protocol for selectors not included in any protocols as it may happen occasionally." | protocols sortedProtocols | protocols := Set new. self interestingClasses do: [:each | protocols addAll: each organization categories. each organization elements size < each selectors size ifTrue: [protocols add: self unclassifiedProtocol]]. sortedProtocols := (#{Refactory.Browser.SelectorProtocolNavigatorPart} ifDefinedDo: [:class | class protocolOrder] elseDo: [nil]) ifNil: [protocols asSortedCollection] ifNotNil: [:order | protocols asSortedCollection: [:a :b | order is: a before: b]]. ^sortedProtocols asList
makeProtocolSelectionVisible | selectedIndex | selectedIndex := self protocolListHolder selectionIndexes detect: [:any | true] ifNone: [^self]. (self widgetAt: #protocolList) makeVisible: selectedIndex
removeProtocol | target ownProtocols selectors | self changeRequest ifFalse: [ ^false ]. target := self classObject. ownProtocols := Set new. selectors := Set new. self protocolListHolder selections do: [:protocol | (target organization categories includes: protocol) ifTrue: [ownProtocols add: protocol. selectors addAll: (target organization listAtCategoryNamed: protocol)]]. ownProtocols isEmpty ifTrue: [^self]. selectors isEmpty ifFalse: [(Dialog confirm: (#ConfirmRemoveingMethodsInProtocols << #dialogs >> 'Are you certain that you want to<n>remove all methods in these protocols?') expandMacros) ifFalse: [^false]]. selectors do: [:each | target removeSelector: each]. ownProtocols do: [ :protocol | target organization removeCategory: protocol. SourceFileManager default logChange: ('<1p> organization removeCategory: <2p>' expandMacrosWith: target with: protocol)]. target reorganize. self updateProtocolList
renameProtocol | oldName newName target | self changeRequest ifFalse: [^self]. target := self classObject. oldName := self protocolListHolder selections asArray first. newName := Dialog request: (#EnterNewProtocolName << #dialogs >> 'Enter new protocol name') initialAnswer: oldName. newName isEmpty ifTrue: [^self]. newName := newName asSymbol. (target renameCategory: oldName to: newName) ifTrue: [SourceFileManager default logChange: ('<1p> organization renameCategory: <2p> to: <3p>' expandMacrosWith: target with: oldName with: newName). self updateProtocolList; selectProtocol: newName]
selectProtocol: aSymbol self protocolListHolder selections: (Set with: aSymbol). self makeProtocolSelectionVisible
unclassifiedProtocol "Answer the name of a protocol to use for selectors not included into other protocols." ^#'as yet unclassified'
</methods> <methods> Tools.Trippy.BehaviorInspector <category>private-text</category>
acceptClassDefinition: aText from: aController Compiler new evaluate: aText string in: nil allowReceiver: false receiver: nil environment: self classObject environment notifying: aController ifFail: [^false]. SourceFileManager default logChange: aText string. ^true
acceptMethodDefinition: aText from: aController | protocols protocol selector methods | protocols := self protocolListHolder selections. protocols size = 0 ifTrue: [methods := self methodListHolder selections. protocol := methods isEmpty ifTrue: [Dialog choose: (#ChooseProtocolForMethod << #dialogs >> 'Put this method into which protocol?') fromList: self protocolListHolder list values: self protocolListHolder list lines: 10 cancel: [^false]] ifFalse: [methods first protocol]]. protocols size = 1 ifTrue: [protocol := protocols asArray first]. protocols size > 1 ifTrue: [protocol := Dialog choose: (#ChooseProtocolForMethod << #dialogs >> 'Put this method into which protocol?') fromList: protocols asSortedCollection values: protocols asSortedCollection lines: 10 cancel: [^false]]. selector := self classObject compile: aText classified: protocol notifying: aController. selector isNil ifTrue: [^false] ifFalse: [self updateMethodList; selectSelector: selector. ^true]
acceptText self textAcceptAllowed: (self controllerAt: #text)
computeMethodSourceText | textStream | textStream := TextStream on: (String new: 100). self methodListHolder selections do: [:each | textStream nextPutAllText: each formattedSourceCode] separatedBy: [textStream cr; cr]. ^textStream contents
computeText ^self methodListHolder selections isEmpty ifTrue: [self protocolListHolder selections isEmpty ifTrue: [self nonMetaClassObject definition] ifFalse: [self classObject sourceCodeTemplate]] ifFalse: [self computeMethodSourceText]
doItReceiver ^self objectIsClass ifTrue: [self isAtInstanceSide ifTrue: [nil] ifFalse: [self object]] ifFalse: [self isAtInstanceSide ifTrue: [self object] ifFalse: [self object class]]
formatSelection | editor | editor := self controllerAt: #text. self textIsClassDefinition ifTrue: [editor formatAllAsExpression] ifFalse: [editor formatAllAsMethod]
textAcceptAllowed: aController "Compile here rather in #textAccepted: so that errors prevent the controller text from being stored in the model." ^self textIsClassDefinition ifTrue: [self acceptClassDefinition: aController text from: aController] ifFalse: [self acceptMethodDefinition: aController text from: aController]
textAccepted: aController ^self
textIsClassDefinition ^self protocolListHolder selectionIndexes isEmpty and: [self methodListHolder selectionIndexes isEmpty]
</methods> <methods> Tools.Trippy.BehaviorInspector class <category>accessing</category>
tabLabel ^(#_Methods << #dialogs >> '&Methods')
</methods> <methods> Tools.Trippy.Part <category>initialize-release</category>
object: anObject object := anObject
</methods> <methods> Tools.Trippy.Part <category>accessing</category>
asVariableName "Answer a string that can be used as a variable name of this part when it is copied to a context where a variable name is needed; for example, dropped into a workspace to become a workspace local. By default, the name is based on the class of the value, for example aString." | className | className := self value class name copyWithout: Character space. ^(className first isVowel ifTrue: ['an'] ifFalse: ['a']), className
displayIcon ^[| objectClass | objectClass := Inspector classOfObject: self value. (objectClass class canUnderstand: #toolListIcon) ifTrue: [objectClass toolListIcon] ifFalse: [ToolListIcons inaccessibleToolIcon]] on: Error do: [:ex | ToolListIcons inaccessibleToolIcon]
displayText ^self displayString asText
key self subclassResponsibility
partName "Answer a string that identifies the current part in the owner. For example, for a named variable this would be its name, for an indexed variable its index." self subclassResponsibility
text ^Inspector safePrintStringOf: self value
value self subclassResponsibility
</methods> <methods> Tools.Trippy.Part <category>testing</category>
hasValue "Answer whether this part can meaningfully respond to the #value message answering an object which is the part's value. Some parts do not have to have value and only have #text that they show in the inspector's text view. For example, a bytecode disassembly of a compiled method is a TextAttribute that has no value that could be meaningfully copied elsewhere." ^true
isNamedVariable ^false
isProtected "Protected parts are parts assignment to which, even if physically possible (as reported by #isReadOnly) is potentially dangerous and should be done with extreme caution, after explicitly warning the user." ^false
isReadOnly "Answer whether it is legal to send the #value: message to this part. Sending #value: to a read-only part may result in an exception." ^false
isRemovable ^true
</methods> <methods> Tools.Trippy.Part <category>comparing</category>
= aPart ^self class == aPart class and: [self sameTypeEquals: aPart]
hash ^self class hash bitXor: self specificHash
sameTypeEquals: aPart "Each subclass should compare itself to aPart exploiting the fact that they types are known to the be same." ^self subclassResponsibility
specificHash "Each subclass should return a hash value for its elements, but need not worry about including the class's hash value." ^self subclassResponsibility
</methods> <methods> Tools.Trippy.Part <category>printing</category>
displayLabel ^(LabelAndIcon new) text: self displayText; icon: self displayIcon
</methods> <methods> Tools.Trippy.KeyedElement <category>accessing</category>
asVariableName ^key isString ifTrue: [key] ifFalse: [key isSymbol ifTrue: [key asString] ifFalse: [key isInteger ifTrue: ['at', key printString] ifFalse: [(Inspector safeDisplayStringOf: key) copyWithout: Character space]]]
displayString ^Inspector safeDisplayStringOf: key
key ^key
partName ^key printString
value ^object at: key
value: anObject ^object at: key put: anObject
</methods> <methods> Tools.Trippy.KeyedElement <category>initialize-release</category>
key: anObject key := anObject
</methods> <methods> Tools.Trippy.KeyedElement <category>comparing</category>
sameTypeEquals: aPart ^key = aPart key
specificHash ^key hash
</methods> <methods> Tools.Trippy.KeyedElement class <category>instance creation</category>
of: anObject at: anObject2 ^self new object: anObject; key: anObject2
</methods> <methods> Tools.Trippy.VisualComponentProxy <category>initialize-release</category>
actualComponent: aVisualComponent actualComponent := aVisualComponent
</methods> <methods> Tools.Trippy.VisualComponentProxy <category>proxying</category>
displayOn: aGraphicsContext ^[actualComponent displayOn: aGraphicsContext] on: Error do: [:ex | aGraphicsContext displayString: (#ErrorDisplayingTheObject << #dialogs >> 'Error displaying the object') asString at: 40@40. ex return]
preferredBounds ^[actualComponent preferredBounds] on: Error do: [:ex | ex return: (0@0 extent: 0@0)]
</methods> <methods> Tools.Trippy.VisualComponentProxy class <category>instance creation</category>
on: aVisualComponent ^self new actualComponent: aVisualComponent
</methods> <methods> Tools.Trippy.OwnerNavigator <category>aspects</category>
fieldListHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^fieldListHolder isNil ifTrue: [fieldListHolder := SelectionInList new] ifFalse: [fieldListHolder]
</methods> <methods> Tools.Trippy.OwnerNavigator <category>accessing</category>
vicinity ^vicinity
</methods> <methods> Tools.Trippy.OwnerNavigator <category>initialize-release</category>
bePartsNavigator vicinity := #self
initialize: aVisit shell: aShell inspector: anInspector super initialize: aVisit shell: aShell inspector: anInspector. vicinity := #owner. ownerInspector := aVisit ownerInspector. self fieldListHolder list: ownerInspector fieldListHolder list. self fieldListHolder selectionIndexHolder onChangeSend: #fieldSelected to: self. self fieldListHolder selection: aVisit ownerPart
installedWith: aBuilder (aBuilder componentAt: #fieldList) widget makeVisible: self fieldListHolder selectionIndex
postBuildWith: aBuilder self reinstallInspector
</methods> <methods> Tools.Trippy.OwnerNavigator <category>notification</category>
fieldDoubleClicked shell exploreFocus
fieldSelected | selection newObject | selection := self fieldListHolder selection. (selection isNil or: [selection hasValue not]) ifTrue: [^self]. newObject := selection value. visit := visit owner visitOfPart: selection ifNone: [PartVisit part: selection owner: visit owner inspector: ownerInspector]. self replaceInspectorWithOneOn: newObject. self refreshInspectorClasses
</methods> <methods> Tools.Trippy.UndoAction <category>accessing</category>
explanation "Answer a string that will be appended to 'Undo' to form a nicer undo menu item label." self subclassResponsibility
parts ^savedValues collect: [:each | each part]
savedValues ^savedValues
undoIn: aPage self subclassResponsibility
values ^savedValues collect: [:each | each value]
</methods> <methods> Tools.Trippy.UndoAction <category>initialize-release</category>
savedValues: partCollection savedValues := partCollection collect: [:each | PartSnapshot on: each]
</methods> <methods> Tools.Trippy.RemovalUndo <category>accessing</category>
explanation ^(#Removal << #dialogs >> 'Removal')
undoIn: aPage aPage undoRemoval: self
</methods> <methods> Tools.Trippy.InstVarRemovalUndo <category>accessing</category>
definingClasses ^definingClasses
definingClasses: aCollection aCollection size ~= savedValues size ifTrue: [self error: (#InvalidDefiningClasses << #dialogs >> 'invalid defining class collection')]. definingClasses := aCollection
</methods> <methods> Tools.Trippy.NamedVariable <category>accessing</category>
asVariableName ^name
displayIcon self isProtected ifFalse: [^super displayIcon]. ^VisualRow with: ToolListIcons protectedShield with: super displayIcon
displayString ^name asString
index ^index
key ^name
name ^name
partName ^name
value ^Inspector instVarOfObject: object at: index
value: anObject ^object instVarAt: index put: anObject
</methods> <methods> Tools.Trippy.NamedVariable <category>testing</category>
isNamedVariable ^true
isProtected ^protected
</methods> <methods> Tools.Trippy.NamedVariable <category>initialize-release</category>
beProtected protected := true
index: anInteger class: aClass (anInteger between: 1 and: aClass instSize) ifFalse: [self error: (#instVarIdexNotInTheClass << #dialogs >> 'instance variable index not in the class')]. index := anInteger. name := aClass instVarNameForIndex: index. class := aClass. protected := false.
name: aString class: aClass name := aString. class := aClass. protected := false. index := aClass instVarIndexFor: name. index isZero ifTrue: [self error: (#variableNotInTheClass << #dialogs >> 'variable not in the class')]
refreshIndex index := class instVarIndexFor: name. index isZero ifTrue: [self error: (#variableNotInTheClass << #dialogs >> 'variable not in the class')]
</methods> <methods> Tools.Trippy.NamedVariable <category>comparing</category>
lessByIndexThan: aNamedVariable ^self index < aNamedVariable index
lessByNameThan: aNamedVariable ^self name < aNamedVariable name
sameTypeEquals: aPart ^name = aPart name
specificHash ^name hash
</methods> <methods> Tools.Trippy.NamedVariable class <category>instance creation</category>
of: anObject index: anInteger ^(self new) object: anObject; index: anInteger class: (Inspector classOfObject: anObject)
of: anObject named: aString ^(self new) object: anObject; name: aString class: (Inspector classOfObject: anObject)
</methods> <methods> Tools.Trippy.PartSnapshot <category>accessing</category>
asVariableName ^part asVariableName
displayString ^part displayString
key ^part key
part ^part
partName ^part partName
restore part value: value
text ^part text
value ^value
</methods> <methods> Tools.Trippy.PartSnapshot <category>initialize-release</category>
initialize: aPart part := aPart. value := aPart value
part: aPart value: anObject part := aPart. value := anObject
</methods> <methods> Tools.Trippy.PartSnapshot class <category>instance creation</category>
on: aPart ^self new initialize: aPart
</methods> <methods> Tools.Trippy.DragController <category>private</category>
currentViewIndex "The answered index may lie outside the valid range of view items." ^view elementIndexFor: view controller sensor cursorPoint
doDrop: aDragContext self subclassResponsibility
dropEffect: aDragContext "This is a hack to make the cursor give a hint of whether multiple objects are copied or not. We always copy the dragged objects." ^(self isMultiObjectDrag: aDragContext) ifTrue: [#dropEffectCopy] ifFalse: [#dropEffectMove]
isMultiObjectDrag: aDragContext ^aDragContext data clientData size > 1
isObjectDrag: aDragContext ^aDragContext key == #inspectorObject
restoreViewState viewState notNil ifTrue: [view targetIndex: (viewState at: 1); hasFocus: (viewState at: 2)]
saveViewState viewState := Array with: view targetIndex with: view hasFocus
showDropFeedbackFor: aDragContext self subclassResponsibility.
</methods> <methods> Tools.Trippy.DragController <category>tracking</category>
dragEntry: aDragContext ^(self isObjectDrag: aDragContext) ifTrue: [self saveViewState. view hasFocus: true. self dropEffect: aDragContext] ifFalse: [#dropEffectNone]
dragExit: aDragContext (self isObjectDrag: aDragContext) ifTrue: [self restoreViewState]. ^#dropEffectNone
dragOver: aDragContext (self isObjectDrag: aDragContext) ifTrue: [^self showDropFeedbackFor: aDragContext]. ^#dropEffectNone
drop: aDragContext (self isObjectDrag: aDragContext) ifTrue: [self restoreViewState; doDrop: aDragContext. ^#dropEffectCopy]. ^#dropEffectNone
</methods> <methods> Tools.Trippy.DragController <category>initialize-release</category>
initializePage: anInspectorPage view: aView page := anInspectorPage. view := aView
</methods> <methods> Tools.Trippy.DragController class <category>instance creation</category>
for: aPage view: aView ^self new initializePage: aPage view: aView
</methods> <methods> Tools.Trippy.ReplaceOnlyDragController <category>private</category>
currentPart ^page fieldListHolder list at: (1 max: (view replacementIndexFor: view controller sensor cursorPoint))
doDrop: aDragContext | parts thisPart | parts := aDragContext data clientData. thisPart := self currentPart. thisPart isReadOnly ifTrue: [^self]. aDragContext sourceData contextApplication == page ifTrue: [page dropFromSame: parts at: thisPart] ifFalse: [page drop: parts at: thisPart]
showDropFeedbackFor: aDragContext view showReplaceDropFeedbackIn: aDragContext allowScrolling: true. ^self currentPart isReadOnly ifTrue: [#dropEffectNone] ifFalse: [self dropEffect: aDragContext]
</methods> <methods> Tools.Trippy.OverriddenMethodDefinition <category>printing</category>
simpleReverseDisplayString ^super simpleReverseDisplayString asText emphasizeAllWith: #italic
</methods> <methods> Tools.Trippy.SelfPart <category>accessing</category>
displayIcon (Inspector isImmutableObject: object) ifFalse: [^super displayIcon]. ^VisualRow with: ToolListIcons padlock with: super displayIcon
displayString ^'self'
displayText ^super displayText emphasizeAllWith: #bold
key ^#self
partName ^'self'
value ^object
</methods> <methods> Tools.Trippy.SelfPart <category>comparing</category>
sameTypeEquals: aPart ^true
specificHash ^18
</methods> <methods> Tools.Trippy.SelfPart <category>testing</category>
isReadOnly ^true
</methods> <methods> Tools.Trippy.SelfPart class <category>instance creation</category>
object: anObject ^self new object: anObject
</methods> <methods> Tools.Trippy.PartVisit <category>initialize-release</category>
part: aPart inspector: anInspector object := aPart. ownerInspector := anInspector
</methods> <methods> Tools.Trippy.PartVisit <category>accessing</category>
object ^object value
ownerInspector ^ownerInspector
ownerPart ^object
</methods> <methods> Tools.Trippy.PartVisit <category>printing</category>
displayString | result | result := WriteStream on: (String new: 20). self ownerPart notNil ifTrue: [result nextPutAll: self ownerPart partName. result nextPutAll: ': ']. Inspector safeBasicPrint: self object on: result. ^result contents
printOn: aStream aStream nextPut: $<; print: self class; nextPutAll: ' object: '; print: self object; nextPutAll: ' part: '; print: self ownerPart; nextPut: $>
</methods> <methods> Tools.Trippy.PartVisit <category>privileged</category>
enumerateOwnersToIgnore: aBlock super enumerateOwnersToIgnore: aBlock. ownerInspector enumerateOwnersToIgnore: aBlock
</methods> <methods> Tools.Trippy.PartVisit class <category>instance creation</category>
part: aPart owner: aVisit inspector: anInspector ^self new object: nil owner: aVisit; part: aPart inspector: anInspector; yourself
</methods> <methods> Tools.Trippy.TextAttribute <category>initialize-release</category>
label: aString text: aText label := aString. text := aText
label: aString textBlock: aBlock label := aString. textBlock := aBlock
</methods> <methods> Tools.Trippy.TextAttribute <category>accessing</category>
asVariableName ^label
displayIcon ^ToolListIcons gear
displayString ^label asString
displayText ^super displayText emphasizeAllWith: #italic
key ^label
label ^label
partName ^label asString
text ^textBlock isNil ifTrue: [text] ifFalse: [[textBlock value] on: Error do: [:ex | ((#ErrorRetrievingTextC1s << #dialogs >> '[Error retrieving text: <1s>]') expandMacrosWith: ex description)]]
value ^self text
</methods> <methods> Tools.Trippy.TextAttribute <category>testing</category>
hasValue ^true
isReadOnly ^true
isRemovable ^false
</methods> <methods> Tools.Trippy.TextAttribute <category>comparing</category>
sameTypeEquals: aPart ^label = aPart label
specificHash ^label hash
</methods> <methods> Tools.Trippy.TextAttribute class <category>instance creation</category>
label: aString text: aText ^self new label: aString text: aText
label: aString textBlock: aBlock ^self new label: aString textBlock: aBlock
</methods> <methods> Tools.Trippy.Hierarchy <category>accessing</category>
childrenOf: anObject | result | result := [childrenBlock value: anObject] on: Error do: [:ex | ex return]. ^result isNil ifTrue: [Array new] ifFalse: [result]
id ^id
label ^label
parentOf: anObject ^[parentBlock value: anObject] on: Error do: [:ex | ex return]
root ^root
rootOf: anObject | this parent | self hasRoot ifTrue: [^root]. this := anObject. [parent := self parentOf: this. parent notNil] whileTrue: [this := parent]. ^this
</methods> <methods> Tools.Trippy.Hierarchy <category>initialize-release</category>
initialize: aSymbol label: aString parentBlock: aBlock childrenBlock: aBlock2 id := aSymbol. label := aString. parentBlock := aBlock. childrenBlock := aBlock2
initialize: aSymbol label: aString root: anObject childrenBlock: aBlock id := aSymbol. label := aString. root := anObject. childrenBlock := aBlock
</methods> <methods> Tools.Trippy.Hierarchy <category>testing</category>
hasRoot ^parentBlock isNil
</methods> <methods> Tools.Trippy.Hierarchy class <category>instance creation</category>
id: aSymbol label: aString parentBlock: aBlock childrenBlock: aBlock2 ^self new initialize: aSymbol label: aString parentBlock: aBlock childrenBlock: aBlock2
id: aSymbol label: aString root: anObject childrenBlock: aBlock ^self new initialize: aSymbol label: aString root: anObject childrenBlock: aBlock
</methods> <methods> Tools.Trippy.PageDriver <category>notifications</category>
fieldSelectionChanged page textHolder value: page computeText
</methods> <methods> Tools.Trippy.PageDriver <category>private</category>
hookup page fieldListHolder selectionIndexHolder onChangeSend: #fieldSelectionChanged to: self
</methods> <methods> Tools.Trippy.PageDriver <category>initialize-release</category>
initializePage: anInspectorPage page := anInspectorPage. self hookup
</methods> <methods> Tools.Trippy.PageDriver <category>accessing</category>
refresh page fieldListHolder list: (page partsAtAll: (1 to: page partCount)) asList
</methods> <methods> Tools.Trippy.PageDriver class <category>instance creation</category>
for: anInspectorPage ^self new initializePage: anInspectorPage
</methods> <methods> Tools.Trippy.SegmentedPageDriver <category>private</category>
computeFieldList | segments fields | segments := page segmentListHolder selections asSortedCollection. segments isEmpty ifTrue: [^Array new]. fields := OrderedCollection new: segmentSize * segments size. segments do: [:each | fields addAll: (page partsAtAll: each range)]. ^fields asList
computeSegmentList "Answer a sequence consisting of everything to show in the segement list." | segments totalSize | segments := OrderedCollection new. totalSize := page partCount. 1 to: totalSize by: segmentSize do: [:base | | end | end := base + segmentSize - 1 min: totalSize. segments add: (ObjectSegment new from: base part: (page partAt: base) to: end part: (page partAt: end))]. ^segments
hookup super hookup. page segmentListHolder selectionIndexHolder onChangeSend: #segmentSelectionChanged to: self
</methods> <methods> Tools.Trippy.SegmentedPageDriver <category>accessing</category>
refresh page segmentListHolder list: self computeSegmentList; selectionIndexes: (Set with: 1)
</methods> <methods> Tools.Trippy.SegmentedPageDriver <category>notifications</category>
segmentSelectionChanged page fieldListHolder list: self computeFieldList
</methods> <methods> Tools.Trippy.SegmentedPageDriver <category>initialize-release</category>
initializePage: anInspectorPage "Pick a reasonable segment size. The reasonable size is typically the default page limit size. However, for a very large object this may lead to the list of segments that is too long. In that case, we pick something that will lead lists of about the same length." | defaultSize | defaultSize := PartListAbstractInspector pageSizeLimit. segmentSize := anInspectorPage partCount // defaultSize > defaultSize ifTrue: [anInspectorPage partCount sqrtRounded // defaultSize * defaultSize] ifFalse: [defaultSize]. super initializePage: anInspectorPage
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>properties</category>
dragControllerClass self subclassResponsibility
driverClass ^self isSegmented ifTrue: [SegmentedPageDriver] ifFalse: [PageDriver]
isSegmented ^self partCount > self class pageSizeLimit
specName ^self isSegmented ifTrue: [#segmentedSpec] ifFalse: [#unsegmentedSpec]
undoLimit "How many undo levels a page allows." ^10
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>private</category>
checkProtectionOf: partCollection ifCancelled: aBlock | protected | protected := partCollection select: [:each | each isProtected]. protected isEmpty not ifTrue: [(Dialog confirm: (#ConfirmSaveIntoProtectedSlot << #dialogs >> 'Changing the value of a protected part may have catastrophic consequences. Are you sure you want to continue?')) ifFalse: [^aBlock value]].
computeMultiSelectionText | stream | stream := TextStream on: (String new: 200). self selections do: [:each | stream nextPutAllText: each displayString copy asText allBold; nextPutAll: ': '; nextPutAll: each text. stream cr]. ^stream contents
computeNoSelectionText ^String new
computeSingleSelectionText ^self selection text
computeText self hasMultiSelection ifTrue: [^self computeMultiSelectionText]. self hasSingleSelection ifTrue: [^self computeSingleSelectionText]. ^self computeNoSelectionText
createInsertionUndo: partCollection before: anIndex self subclassResponsibility
createRemovalUndo ^RemovalUndo new savedValues: self selections
createReplacementUndo: partCollection ^ReplacementUndo new savedValues: partCollection
createReplacementUndoOf: aPart ^ReplacementUndo new savedValues: (Array with: aPart)
doItContext "Answer the context in which a text selection can be evaluated." ^nil
doItReceiver "Answer the object that should be informed of the result of evaluating a text selection." ^object
enumerateOwnersToIgnore: aBlock super enumerateOwnersToIgnore: aBlock. fieldListHolder list do: aBlock
evaluateText: aText from: aController ifFail: failBlock "The user wishes to evaluate expressions in the value part of an inspector. Do so in the context of the inspector's variables. Evaluate failBlock if the evaluation does not work." ^Cursor execute showWhile: [self doItReceiver class evaluatorClass new evaluate: aText in: nil allowReceiver: true receiver: self doItReceiver environment: self doItReceiver class environment notifying: aController ifFail: failBlock]
pickSingleObjectIn: partCollection ifCancelled: aBlock | labels objects objectsCopy | partCollection size = 1 ifTrue: [^partCollection first value]. labels := OrderedCollection new. objects := OrderedCollection new. partCollection do: [:part | labels add: ('<1s>: <2s>' expandMacrosWith: part displayString with: part value displayString). objects add: part value]. objectsCopy := objects copy. labels add: ((#All1pAsAnArray << #dialogs >> 'All <1p> as an Array') expandMacrosWith: partCollection size). objects add: objectsCopy asArray. labels add: ((#All1pAsAnOC << #dialogs >> 'All <1p> as an OrderedCollection') expandMacrosWith: partCollection size). objects add: objectsCopy asOrderedCollection. labels add: ((#All1pAsASet << #dialogs >> 'All <1p> as a Set') expandMacrosWith: partCollection size). objects add: objectsCopy asSet. ^Dialog choose: (#UseWhichOfTheseObjectsQ << #dialogs >> 'Use which of these objects?') fromList: labels values: objects lines: 8 cancel: aBlock
refresh | originalSelections | originalSelections := self selections. driver := self driverClass for: self. driver refresh. self selectAll: originalSelections
rememberUndo: anUndoAction undoHistory addLast: anUndoAction. undoHistory size > self undoLimit ifTrue: [undoHistory removeFirst]
replaceSelectionsWith: newValue | selections | selections := self selections reject: [:some | some isReadOnly]. selections isEmpty ifTrue: [^self]. self checkProtectionOf: selections ifCancelled: [^self]. self rememberUndo: (self createReplacementUndo: selections). selections do: [:each | each value: newValue. self container partValueChanged: each]. (self widgetAt: #fieldList) invalidate. self textHolder value: self computeText
textAcceptAllowed: aController (self hasSelection and: [(self selections contains: [:some | some isReadOnly]) not]) ifFalse: [aController view flash. ^false]. self checkProtectionOf: self selections ifCancelled: [aController view flash. ^false]. ^true
textAccepted: aController | newValue | newValue := self evaluateText: aController text from: aController ifFail: [^false]. self replaceSelectionsWith: newValue. ^true
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>aspects</category>
fieldListHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^fieldListHolder isNil ifTrue: [fieldListHolder := MultiSelectionInList new] ifFalse: [fieldListHolder]
segmentListHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^segmentListHolder isNil ifTrue: [segmentListHolder := MultiSelectionInList new] ifFalse: [segmentListHolder]
textHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^textHolder isNil ifTrue: [textHolder := String new asValue] ifFalse: [textHolder]
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>actions-editing</category>
copySelection Clipboard default put: self selections
paste | parts | parts := Clipboard default get. parts isEmpty ifFalse: [self hasSelection ifTrue: [self pasteIntoSelected: parts] ifFalse: [self pasteIntoSelf: parts]].
pasteIntoSelected: partCollection | value | value := self pickSingleObjectIn: partCollection ifCancelled: [^self]. self replaceSelectionsWith: value
pasteIntoSelf: aBundle Dialog warn: (#CannotAddElementsToObject << #dialogs >> 'Cannot add elements to this object.')
undo | undo | undoHistory notEmpty ifTrue: [undo := undoHistory removeLast. undo undoIn: self]
undoReplacement: aReplacementUndo aReplacementUndo savedValues do: [:each | each restore]. self refresh; selectAll: aReplacementUndo parts
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>accessing</category>
copyStateTo: aPage aPage notNil ifTrue: [aPage copyStateFromPartList: self]
select: aPart ^self fieldListHolder selections: (Set with: aPart)
selectAll: partCollection ^self fieldListHolder selections: partCollection asSet
selectedObjectOrInspectedObject | selection | ^self hasSingleSelection ifTrue: [selection := self selection. selection hasValue ifTrue: [selection value] ifFalse: [self object]] ifFalse: [self object]
selection self hasSingleSelection ifFalse: [self error: (#errSingleSelectionRequired << #dialogs >> 'single selection required')]. ^self fieldListHolder selections asArray first
selections "Simply '^self fieldListHolder selections' will not do because we want a sequence of selections with their order preserved, not a Set. This is actually MultiSelectionInList brain damage but oh well." | indices list | indices := self fieldListHolder selectionIndexes asSortedCollection. list := self fieldListHolder list. ^(indices collect: [:each | list at: each]) asArray
undoExplanation "Answer a string with an explanation of the possible undo action, or an empty string." ^self canUndo ifTrue: [undoHistory last explanation] ifFalse: [String new]
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>testing</category>
canAddPart ^true
canCopy "Copy is only meaningful if at least one of the selected parts has value." ^self selections contains: [:some | some hasValue]
canDive ^self hasSingleSelection and: [self selection hasValue]
canRemoveParts ^self hasSelection
canUndo ^undoHistory notEmpty
hasMultiSelection ^self fieldListHolder selectionIndexes size > 1
hasSelection "Answer whether at least one field is selected." ^self fieldListHolder selectionIndexes size > 0
hasSingleSelection "Answer whether these is exactly one field selected on the list." ^self fieldListHolder selectionIndexes size = 1
isInsertableBefore: aPartOrNil "Answer whether it is possible to insert elements before the given part (or at the end of part list if the argument is nil). Most pages allow insertions. Those that don't, such as the basic page, should redefine this." ^true
isPartList ^true
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>decomposing</category>
partAt: anInteger "Answer the part of an object at the given index. The index must be in the 1..partCount range." self subclassResponsibility
partCount "Answer the number of parts of the object inspected by the receiver." self subclassResponsibility
partsAtAll: aCollection "Subclasses are encouraged to override this to recognize the special case of the full range of indices (1..partCount) being requested if there is performance gain in building the complete list all at once." ^aCollection collect: [:eachIndex | self partAt: eachIndex]
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>actions-drag/drop</category>
doDrag: aController | data selections | (data := DragDropData new) contextWindow: builder window; contextWidget: aController; contextApplication: self. selections := self selections select: [:part | part hasValue]. selections isEmpty ifTrue: [^self]. data key: #inspectorObject; clientData: selections. (DragDropManager withDropSource: DropSource new withData: data) doDragDrop
dragEntry: aDragContext dragController := self dragControllerClass for: self view: (self builder componentAt: #fieldList) widget. ^dragController dragEntry: aDragContext
dragExit: aDragContext | result | result := dragController notNil ifTrue: [dragController dragExit: aDragContext] ifFalse: [#dropEffectNone]. dragController := nil. ^result
dragOver: aDragContext ^dragController notNil ifTrue: [dragController dragOver: aDragContext] ifFalse: [#dropEffectNone]
drop: aDragContext | result | result := dragController notNil ifTrue: [dragController drop: aDragContext] ifFalse: [#dropEffectNone]. dragController := nil. ^result
drop: partCollection at: aPart self checkProtectionOf: (Array with: aPart) ifCancelled: [^self]. self rememberUndo: (self createReplacementUndoOf: aPart). aPart value: (self pickSingleObjectIn: partCollection ifCancelled: [^self]). self select: aPart
drop: partCollection before: aPart "Inserting a bunch of objects between elements does not do anything by default."
dropFromSame: partCollection at: aPart "By default, there is no difference between dropping elements from the same object or from a different one." self drop: partCollection at: aPart
dropFromSame: partCollection before: aPart "By default, there is no difference between dropping elements from the same object or from a different one." self drop: partCollection before: aPart
wantToDrag: aController ^true
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>menu management</category>
addAddAndRemoveItemsTo: aMenu "Add appropriate things to the Edit dropdown menu of the shell inspector menu bar. " aMenu addItem: ((MenuItem labeled: (#AddDot << #menus >> '&Add...')) nameKey: #editAdd; value: [self add]; enabled: [self canAddPart]); addItem: ((MenuItem labeled: (#_Remove << #menus >> '&Remove')) nameKey: #editRemove; value: [self removeSelected]; enabled: [self canRemoveParts])
adjustMenuBarEnablement: aMenu "Now that this class has introduced the concept of selection, some menu items need adjustment to take selection into account." #(objectBrowse objectSpawn objectInspectOwners) do: [:each | (aMenu atNameKey: each) enabled: [self hasSelection not or: [self canDive]]]
augmentEditMenu: aMenu "Subclasses may redefine this to have extra items on the edit menu."
augmentMenuBar: aMenu "The top-level window gives us a chance to modify its menu bar." | editItem editMenu | super augmentMenuBar: aMenu. self adjustMenuBarEnablement: aMenu. editItem := MenuItem labeled: #_Edit << #menus >> '&Edit'. editItem nameKey: #editMenu. editMenu := self class baseEditSubmenu. (editMenu atNameKey: #editUndo) enabled: [self canUndo]. (editMenu atNameKey: #editFlushUndoHistory) enabled: [self canUndo]. (editMenu atNameKey: #editCopy) enabled: [self canCopy]. self makeSelfPerformerOf: editMenu; augmentEditMenu: editMenu. editItem submenu: editMenu. aMenu addItem: editItem atPosition: 10.002
buildFieldListMenu "Build the popup menu for the field list. Besides the usual things, it should include items for actions published by the currently selected object, if there is one." | menu | menu := self class fieldListMenu. (menu atNameKey: #dive) enabled: [self canDive]. (menu atNameKey: #spawn) enabled: [self canDive]. (menu atNameKey: #paste) enabled: [Clipboard default notEmpty]. (menu atNameKey: #back) enabled: [self container canGoBack]. (self hasSingleSelection and: [self selection hasValue]) ifTrue: [self addObject: self selection value actionsTo: menu]. menu augmentFrom: self class to: PartListAbstractInspector menuName: #fieldList for: self. ^menu
fieldListMenu ^[self buildFieldListMenu]
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>actions</category>
back self container back
changeRequest | textEditor choice | textEditor := (builder componentAt: #text) widget controller. (textEditor accepted or: [self hasSelection not]) ifTrue: [^true]. choice := Dialog choose: (#AcceptUnsavedChanges << #dialogs >> 'Accept unsaved changes?') labels: (Array with: (#Yes << #dialogs >> 'Yes') with: (#No << #dialogs >> 'No') with: (#Cancel << #dialogs >> 'Cancel')) values: #(yes no cancel) default: #yes. choice = #cancel ifTrue: [^false]. choice = #yes ifTrue: [textEditor accept]. ^true
dive (self hasSingleSelection and: [self selection hasValue]) ifTrue: [self container diveInto: self selection]
flushUndoHistory undoHistory := OrderedCollection new
spawn self hasSingleSelection ifTrue: [self selection value inspect] ifFalse: [self hasMultiSelection ifTrue: [(self selections collect: [:each | each value]) inspect] ifFalse: [self object inspect]]
</methods> <methods> Tools.Trippy.PartListAbstractInspector <category>initialize-release</category>
copyStateFromPartList: anInspector self selectAll: anInspector selections
initialize: anObject undoHistory := OrderedCollection new. super initialize: anObject. self selections isEmpty and: [self partCount > 0 ifTrue: [self select: (self partAt: 1)]]
installedWith: aBuilder super installedWith: aBuilder. self refresh
postBuildWith: aBuilder ((aBuilder componentAt: #text) widget controller) initializeMenuForCode; autoAccept: false
</methods> <methods> Tools.Trippy.PartListAbstractInspector class <category>accessing</category>
pageSizeLimit "The maximum number of fields an inspector shows in an unsegmented view. If the number of fields is equal to or exceeds the value returned by this method, the segmented view is used." ^200
</methods> <methods> Tools.Trippy.BasicInspector <category>properties</category>
dragControllerClass ^ReplaceOnlyDragController
</methods> <methods> Tools.Trippy.BasicInspector <category>private</category>
augmentEditMenu: aMenu "Add appropriate things to the Edit dropdown menu of the shell inspector menu bar. " aMenu addLine. self addAddAndRemoveItemsTo: aMenu
buildFieldListMenu | menu | menu := super buildFieldListMenu. menu addLine. self addAddAndRemoveItemsTo: menu. ^menu
classDefining: aString for: aClass "The instance variable might be defined by either the argument class or one of its superclasses." ^aClass withAllSuperclasses detect: [:some | some instVarNames includes: aString]
confirmInstVarRemoval: stringCollection | message | message := (String new: 100) writeStream. stringCollection size = 1 ifTrue: [message nextPutAll: (#RemoveInstanceVariable << #dialogs >> 'Remove instance variable ') asString] ifFalse: [message nextPutAll: (#ConfirmRemoveInstVar << #dialogs >> 'Remove the following instance variables:') asString; cr]. stringCollection do: [:each | message nextPut: $"; nextPutAll: each; nextPut: $"] separatedBy: [message nextPutAll: ', ']. message nextPutAll: '?'. ^Dialog confirm: message contents
createRemovalUndo: partCollection | classes | classes := partCollection collect: [:each | self classDefining: each name for: self objectClass]. ^InstVarRemovalUndo new savedValues: partCollection; definingClasses: classes; yourself
derivedFields ^(self objectClass canUnderstand: #inspectorExtraAttributes) ifTrue: [self object inspectorExtraAttributes] ifFalse: [Array new]
isValidInstVarName: aString ^aString isEmpty not and: [aString first isLetter and: [(aString contains: [:some | (some isLetter or: [some isDigit]) not]) not]]
namedFields | protected | protected := self protectedVariableNames. ^((1 to: self objectClass instSize) collect: [:i | | part | part := NamedVariable of: object index: i. (protected includes: part name) ifTrue: [part beProtected]. part]) sorted: [:a :b | a perform: sortSelector with: b]
partWithKey: aString ^fixedFields detect: [:some | some key = aString]
promptForValidInstVarName | name | name := String new. [name := (Dialog request: #AddInstanceVariableNamedC << #dialogs >> 'Add instance variable named:' initialAnswer: name) trimBlanks. name isEmpty ifTrue: [^nil]. (self isValidInstVarName: name) ifFalse: [(Dialog confirm: #InvalidVariableName << #dialogs >> 'Invalid variable name. Try again?') ifFalse: [^nil]] ifTrue: [(self objectClass allInstVarNames includes: name) ifTrue: [(Dialog confirm: #InstVarAlreadyExistsRetry << #dialogs >> 'An instance variable by this name already exists. Try again?') ifFalse: [^nil]] ifFalse: [^name]]] repeat
protectedVariableNames "Answer a collection with names of all variables declared as protected by the class of the inspected object and its superclasses." ^self objectClass withAllSuperclasses inject: Set new into: [:all :each | all addAll: each protectedInstVarNames; yourself]
refresh fixedFields := (Array with: self selfAttribute), self derivedFields, self namedFields. super refresh
removeInstVarName: aString from: aClass "The instance variable might be defined by either the argument class or one of its superclasses." (self classDefining: aString for: aClass) removeInstVarName: aString
selfAttribute ^SelfPart object: object
</methods> <methods> Tools.Trippy.BasicInspector <category>testing</category>
canDive ^self hasSingleSelection and: [self selection hasValue]
canRemoveParts ^(self selections contains: [:some | some isNamedVariable not]) not
</methods> <methods> Tools.Trippy.BasicInspector <category>decomposing</category>
partAt: anInteger "The order of the parts is: derived fields, named ivars, indexed ivars." anInteger <= fixedFields size ifTrue: [^fixedFields at: anInteger]. ^IndexedVariable of: object at: anInteger - fixedFields size
partCount ^fixedFields size + (Inspector basicSizeOfObject: object)
</methods> <methods> Tools.Trippy.BasicInspector <category>actions</category>
add | name newPart | name := self promptForValidInstVarName. name isNil ifTrue: [^self]. (self objectClass allInstVarNames includes: name) ifTrue: [Dialog warn: #InstVarAlreadyExists << #dialogs >> 'An instance variable by this name already exists.'. ^self]. self objectClass addInstVarName: name. self refresh. newPart := self partWithKey: name. self rememberUndo: (InsertionUndo new savedValues: (Array with: newPart)); select: newPart
objectClass ^Inspector classOfObject: self object
removeSelected | toRemove namesToRemove | toRemove := self selections select: [:each | each isNamedVariable]. namesToRemove := toRemove collect: [:each | each name]. toRemove isEmpty ifTrue: [^self]. (self confirmInstVarRemoval: namesToRemove) ifTrue: [self rememberUndo: (self createRemovalUndo: toRemove). namesToRemove do: [:each | self removeInstVarName: each from: self objectClass]. self refresh]
undoInsertion: anInsertionUndo "Undo adding instance variables." anInsertionUndo savedValues do: [:each | self removeInstVarName: each key from: self objectClass]. self refresh
undoRemoval: aRemovalUndo "Put instance variables back into their classes and restore their values in this instance. The tricky parts are: - instance variables should be restored to the right classes - parts saved in the undo action should be told to refresh their cached variable index because the order of the variables might have changed." aRemovalUndo definingClasses with: aRemovalUndo savedValues do: [:class :partSnapshot | class addInstVarName: partSnapshot part name]. aRemovalUndo savedValues do: [:each | each part refreshIndex; value: each value]. self refresh; selectAll: aRemovalUndo parts
</methods> <methods> Tools.Trippy.BasicInspector <category>initialize-release</category>
initialize super initialize. sortSelector := #lessByNameThan:
</methods> <methods> Tools.Trippy.BasicInspector <category>sorting</category>
sortChoices ^Array with: (#sortFieldsByName << #inspector >> 'Name') -> #lessByNameThan: with: (#sortFieldsByIndex << #inspector >> 'Index') -> #lessByIndexThan:
sortSelector: aSymbol "Set the selector that is used to sort named instance variables, refresh the list." sortSelector := aSymbol. self refresh
sortTypeSubmenu | menu item | menu := Menu new. self sortChoices do: [:each | item := MenuItem labeled: each key. item value: [self sortSelector: each value]. item indication: each value == sortSelector. menu addItem: item]. ^menu
</methods> <methods> Tools.Trippy.BasicInspector class <category>accessing</category>
tabLabel "Answer a String to use as the label of the tab of this page." ^(#_Basic << #dialogs >> '&Basic')
</methods> <methods> Tools.Trippy.PreviewingInspector <category>accessing</category>
preview ^VisualComponentProxy on: ((self object isKindOf: ScheduledWindow) ifTrue: [self object component] ifFalse: [self object])
</methods> <methods> Tools.Trippy.PreviewingInspector class <category>accessing</category>
tabLabel ^(#_Preview << #dialogs >> '&Preview')
</methods> <methods> Tools.Trippy.ReplacementUndo <category>accessing</category>
explanation ^(savedValues size = 1 ifTrue: [(#AssignmentTo1s << #dialogs >> 'Assignment to <1s>') expandMacrosWith: (Inspector safeDisplayStringOf: savedValues first partName)] ifFalse: [(#AssignmentTo1sFields << #dialogs >> 'Assignment to <1p> Fields') expandMacrosWith: savedValues size])
undoIn: aPage aPage undoReplacement: self
</methods> <methods> Tools.Trippy.DerivedAttribute <category>initialize-release</category>
initialize: aString value: anObject label := aString. value := anObject
initialize: aString valueBlock: aBlock label := aString. valueBlock := aBlock
</methods> <methods> Tools.Trippy.DerivedAttribute <category>accessing</category>
asVariableName ^label
displayString ^label asString
displayText ^super displayText emphasizeAllWith: #italic
key ^label
label ^label
partName ^label asString
value ^self isComputed ifTrue: [valueBlock value] ifFalse: [value]
valueIn: anObject ^self value
valueIn: anObject put: anObject2
</methods> <methods> Tools.Trippy.DerivedAttribute <category>testing</category>
isComputed ^valueBlock notNil
isReadOnly ^true
isRemovable ^false
</methods> <methods> Tools.Trippy.DerivedAttribute <category>comparing</category>
sameTypeEquals: aPart ^label = aPart label
specificHash ^label hash
</methods> <methods> Tools.Trippy.DerivedAttribute class <category>instance creation</category>
label: aString value: anObject ^self new initialize: aString value: anObject
label: aString valueBlock: aBlock ^self new initialize: aString valueBlock: aBlock
</methods> <methods> Tools.Trippy.SetInspector <category>private</category>
augmentEditMenu: aMenu "Add appropriate things to the Edit dropdown menu of the shell inspector menu bar. " aMenu addLine. self addAddAndRemoveItemsTo: aMenu
buildFieldListMenu | menu | menu := super buildFieldListMenu. menu addLine. self addAddAndRemoveItemsTo: menu. ^menu
createInsertionUndo: aCollection before: ignoredPart | actuallyAdded | actuallyAdded := OrderedCollection new. aCollection do: [:value | (object includes: value) ifFalse: [actuallyAdded add: value]]. ^InsertionUndo new newKeys: actuallyAdded
enumerateOwnersToIgnore: aBlock super enumerateOwnersToIgnore: aBlock. linearized do: aBlock
refresh "Arrange the elements in the increasing order of their displayStrings. Cannot use #collect: to create the pairs collections because #collect: coalesces equal identity set elements." | pairs | pairs := OrderedCollection new: object size. object do: [:each | pairs add: (Inspector safeDisplayStringOf: each) -> each]. pairs := pairs asSortedCollection: [:a :b | a key <= b key]. linearized := pairs collect: [:each | SetElement of: object element: each value]. super refresh
replaceAllSelections: partCollection with: newValue | newPart | (Dialog confirm: (#ReplaceAllSelectedWithNewValue << #dialogs >> 'Remove all these set elements replacing them with the single new value?')) ifFalse: [^self]. newPart := SetElement of: object element: newValue. self rememberUndo: (UndoActionGroup with: (InsertionUndo new newKeys: (Array with: newValue)) with: self createRemovalUndo). partCollection do: [:each | object remove: each element]. object add: newValue. self refresh; select: newPart
replaceSelectionsWith: newValue | selections | selections := self selections. selections := selections reject: [:some | some isReadOnly]. selections isEmpty ifTrue: [^self]. selections size = 1 ifTrue: [self replaceSingleSelection: selections first with: newValue] ifFalse: [self replaceAllSelections: selections with: newValue]
replaceSingleSelection: aPart with: newValue self rememberUndo: (self createReplacementUndo: (Array with: aPart)). aPart value: newValue. self refresh; select: aPart
</methods> <methods> Tools.Trippy.SetInspector <category>actions</category>
add | expression newValue | expression := Dialog request: (#AddNewElementColon << #dialogs >> 'Add new element:'). expression isEmpty ifTrue: [^self]. newValue := Compiler evaluate: expression. (object includes: newValue) ifFalse: [self rememberUndo: (InsertionUndo new newKeys: (Array with: newValue))]. object add: newValue. self refresh; select: (SetElement new element: newValue)
drop: partCollection at: aPart "Dropping onto an element removes that element and replaces it with the one dropped." | replacement | replacement := self pickSingleObjectIn: partCollection ifCancelled: [^self]. self rememberUndo: (ReplacementUndo new savedValues: (Array with: aPart)). object remove: aPart element; add: replacement. aPart element: replacement. self refresh; select: aPart
drop: partCollection before: aPart "Dropping things adds to a set; where the objects were dropped does not matter." | added | added := OrderedCollection new: partCollection size. partCollection do: [:each | | element | element := each value. object add: element. added add: (SetElement of: object element: element)]. self refresh; selectAll: added
dropFromSame: aBundle at: anIndex "Dropping an element onto another element within a set does not mean anything."
dropFromSame: aBundle before: anIndex "Dragging an element of a set to another location does not mean anything."
pasteIntoSelf: snapCollection | added | added := snapCollection collect: [:each | each value]. self rememberUndo: (self createInsertionUndo: added before: 0). object addAll: added. self refresh; selectAll: (snapCollection collect: [:each | each part])
removeSelected self rememberUndo: self createRemovalUndo. object removeAll: (self selections collect: [:each | each element]). self refresh
undoInsertion: anInsertionUndo object removeAll: anInsertionUndo newKeys. self refresh
undoRemoval: aRemovalUndo aRemovalUndo savedValues do: [:each | object add: each value]. self refresh; selectAll: aRemovalUndo parts
undoReplacement: aReplacementUndo | reinstated | reinstated := OrderedCollection new. aReplacementUndo savedValues do: [:each | | oldElement | object remove: each part value. object add: (oldElement := each value). reinstated add: (SetElement of: object element: oldElement)]. self refresh; selectAll: reinstated
</methods> <methods> Tools.Trippy.SetInspector <category>properties</category>
dragControllerClass ^InsertReplaceDragController
</methods> <methods> Tools.Trippy.SetInspector <category>accessing</category>
partAt: anInteger ^linearized at: anInteger
partCount ^linearized size
</methods> <methods> Tools.Trippy.SetInspector class <category>accessing</category>
tabLabel ^(#_Elements << #dialogs >> '&Elements')
</methods> <methods> Tools.Trippy.SetElement <category>accessing</category>
displayString ^Inspector safeDisplayStringOf: element
element ^element
key ^element
partName ^(#element << #dialogs >> 'element') asString
value ^element
value: anObject object remove: element; add: anObject. element := anObject
</methods> <methods> Tools.Trippy.SetElement <category>initialize-release</category>
element: anObject element := anObject
</methods> <methods> Tools.Trippy.SetElement <category>comparing</category>
sameTypeEquals: aPart ^element = aPart element
specificHash ^element hash
</methods> <methods> Tools.Trippy.SetElement class <category>instance creation</category>
of: aSet element: anObject ^self new object: aSet; element: anObject
</methods> <methods> Tools.Trippy.DictionaryInspector <category>private</category>
augmentEditMenu: aMenu "Add appropriate things to the Edit dropdown menu of the shell inspector menu bar. " aMenu addLine. self addAddAndRemoveItemsTo: aMenu
buildFieldListMenu | menu | menu := super buildFieldListMenu. menu addLine. self addAddAndRemoveItemsTo: menu. ^menu
enumerateOwnersToIgnore: aBlock super enumerateOwnersToIgnore: aBlock. linearizedParts do: aBlock
partWithKey: anObject ^linearizedParts detect: [:some | some key == anObject]
refresh "Keys in a dictionary are unordered, but for presentation arrange them in the increasing order of their displayStrings. Do not use #collect: to collect pairs, because #collect: coalesces equal elements, which we need to avoid." | pairs | pairs := OrderedCollection new: object size. object keys do: [:each | pairs add: (Inspector safeDisplayStringOf: each) -> each]. pairs := pairs asSortedCollection: [:a :b | a key <= b key]. linearizedParts := pairs collect: [:each | KeyedElement of: object at: each value]. super refresh
requestNewKey "Answer a new key to add to the dictionary. nil is a 'no answer' value since it is not a valid dictionary key." | expression | expression := Dialog request: (#AddNewKeyC << #dialogs >> 'Add new key:') . expression isEmpty ifTrue: [^nil]. ^Compiler evaluate: expression
</methods> <methods> Tools.Trippy.DictionaryInspector <category>initialize-release</category>
initialize super initialize. self valueOrKeyHolder value: #value; onChangeSend: #valueOrKeySelectionChanged to: self
</methods> <methods> Tools.Trippy.DictionaryInspector <category>aspects</category>
valueOrKeyHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^valueOrKeyHolder isNil ifTrue: [valueOrKeyHolder := nil asValue] ifFalse: [valueOrKeyHolder]
</methods> <methods> Tools.Trippy.DictionaryInspector <category>properties</category>
dragControllerClass ^InsertReplaceDragController
</methods> <methods> Tools.Trippy.DictionaryInspector <category>actions</category>
add | newKey newPart | newKey := self requestNewKey. newKey isNil ifTrue: [^self]. object at: newKey put: nil. self refresh. newPart := self partWithKey: newKey. self rememberUndo: (InsertionUndo new savedValues: (Array with: newPart)); select: newPart
dive self container diveInto: self selection
drop: partCollection before: aPart self pasteIntoSelf: partCollection
dropFromSame: aBundle before: keyObject "Moving items within a dictionary does not mean much so we ignore it."
pasteIntoSelf: partCollection | additions | additions := OrderedCollection new. partCollection do: [:each | object at: each key put: each value. additions add: (KeyedElement of: object at: each key)]. self rememberUndo: (InsertionUndo new savedValues: additions). self refresh; selectAll: additions
removeSelected "Remove the selected elements." self rememberUndo: self createRemovalUndo. self selections do: [:each | object removeKey: each key]. self refresh
undoInsertion: anInsertionUndo anInsertionUndo savedValues do: [:each | object removeKey: each key ifAbsent: []]. self refresh
undoRemoval: aRemovalUndo aRemovalUndo savedValues do: [:each | object at: each part key put: each value]. self refresh; selectAll: aRemovalUndo parts
valueOrKeySelectionChanged self textHolder value: self computeText
</methods> <methods> Tools.Trippy.DictionaryInspector <category>decomposing</category>
partAt: anIndex ^linearizedParts at: anIndex
partCount ^linearizedParts size
</methods> <methods> Tools.Trippy.DictionaryInspector <category>accessing</category>
selection | selection | selection := super selection. ^self valueOrKeyHolder value = #value ifTrue: [selection] ifFalse: [DerivedAttribute label: ((#key1s << #dialogs >> 'key <1s>') expandMacrosWith: selection key displayString) value: selection key]
selections | selections | selections := super selections. ^self valueOrKeyHolder value = #value ifTrue: [selections] ifFalse: [selections collect: [:each | DerivedAttribute label: ((#key1s << #dialogs >> 'key <1s>') expandMacrosWith: each key displayString) value: each key]]
</methods> <methods> Tools.Trippy.DictionaryInspector class <category>accessing</category>
tabLabel ^(#_Elements << #dialogs >> '&Elements')
</methods> <methods> Tools.Trippy.PoolDictionaryInspector <category>private</category>
addPoolItemsTo: aMenu aMenu addItem: ((MenuItem labeled: (#References << #menus >> 'Re&ferences')) nameKey: #poolReferences; value: [self browseReferences]; enabled: [self hasSingleSelection]). object == Undeclared ifTrue: [aMenu addItem: ((MenuItem labeled: (#PurgeUnusedBindings << #menus >> 'Purge &Unused Bindings')) nameKey: #poolPurgeUnused; value: [self purgeUnusedBindings])]
augmentEditMenu: aMenu aMenu addLine. self addPoolItemsTo: aMenu
buildFieldListMenu | menu | menu := super buildFieldListMenu. menu addLine. self addPoolItemsTo: menu. ^menu
requestNewKey "Answer a new key to add to the dictionary. nil is a 'no answer' value since it is not a valid dictionary key. Keys of pools should be valid variable names. " | newKey | newKey := Dialog request: (#AddNewVariableColon << #dialogs >> 'Add new variable:') . newKey isEmpty ifTrue: [^nil]. ^SystemUtils validateName: newKey
</methods> <methods> Tools.Trippy.PoolDictionaryInspector <category>actions</category>
browseReferences "Browse references to the selected binding. If the inspected object is Undeclared then restrict the set to just references to the binding, excluding references to the binding's key, etc." | mc binding list | mc := MethodCollector new. binding := object bindingFor: self selection key. list := mc referencesTo: binding. object == Undeclared ifTrue: [list := list & (mc methodsSelect: [:cm | | found | found := false. [:exit| cm withAllBlockMethodsDo: [:m| (m literals anySatisfy: [:ea | (ea isVariableBinding and: [ea binding == binding]) or: [ea isBindingReference and: [ea bindingOrNil == binding]]]) ifTrue: [found := true. exit value]]] valueWithExit. found])]. mc browseSelect: list
pasteIntoSelf: partCollection "Unlike the superclass, I cannot use just anything as the variable name." | additions | additions := OrderedCollection new. partCollection do: [:each | | name | name := each asVariableName asSymbol. object at: name put: each value. additions add: (KeyedElement of: object at: name)]. self rememberUndo: (InsertionUndo new savedValues: additions). self refresh; selectAll: additions
purgeUnusedBindings Cursor execute showWhile: [object purgeUnusedBindings]. self refresh
</methods> <methods> Tools.Trippy.SequenceInspector <category>private</category>
augmentEditMenu: aMenu "Add appropriate things to the Edit dropdown menu of the shell inspector menu bar. " aMenu addLine. self addAddAndRemoveItemsTo: aMenu
buildFieldListMenu | menu | menu := super buildFieldListMenu. menu addLine. self addAddAndRemoveItemsTo: menu. ^menu
createAppendInsertionUndo "Create an undo object that undoes appening of one element at the end." ^InsertionUndo new newKeys: (object size + 1 to: object size + 1)
createInsertionUndo: indexCollection before: aPartOrNil ^InsertionUndo new newKeys: indexCollection
keyAtIndex: anIndex ^anIndex
partWithKey: anInteger ^KeyedElement new key: anInteger
privateAdd: anObject "Add the argument to the object being inspected. Subclasses may override this if the notion of adding they support is different. For example, an Array inspector page would have to mutate the array to increase its size. Answer an index (key, in page terminology) of object just added. That index is used for selecting it." object addLast: anObject. ^object size
privateInsertAll: aCollection beforeIndex: anIndex "Insert elements of the argument collection into the object being inspected. Subclasses may override this if the notion of insertion they support is different. Answer indices (keys, in page terminology) of objects just added." aCollection reverseDo: [:each | object add: each beforeIndex: anIndex]. ^anIndex to: anIndex + aCollection size - 1
privateMoveAllAtIndices: aCollection beforeIndex: anIndex "Reposition elements at indices listed in aCollection so that they are all located at indices {anIndex, anIndex+1, ...}. The size of the resulting collection is the same as that of the original." | scratch mobile insertionPoint | scratch := object copy. aCollection asSortedCollection reverseDo: [:each | scratch removeAtIndex: each]. mobile := aCollection collect: [:each | object at: each]. insertionPoint := aCollection inject: anIndex into: [:result :index | index < anIndex ifTrue: [result - 1] ifFalse: [result]]. mobile reverseDo: [:each | scratch add: each beforeIndex: insertionPoint]. object replaceFrom: 1 to: object size with: scratch startingAt: 1. ^insertionPoint to: insertionPoint + aCollection size - 1
privateRemoveAtIndices: anIntegerCollection "Remove elements of the object being inspected with indices listed in the argument array." anIntegerCollection asSortedCollection reverseDo: [:anIndex | object removeAtIndex: anIndex]
selectIndices: indexCollection self selectAll: (indexCollection collect: [:each | KeyedElement of: object at: each])
</methods> <methods> Tools.Trippy.SequenceInspector <category>properties</category>
dragControllerClass ^InsertReplaceDragController
</methods> <methods> Tools.Trippy.SequenceInspector <category>actions</category>
add | expression newValue newKey | expression := Dialog request: (#AddNewElementColon << #dialogs >> 'Add new element:'). expression isEmpty ifTrue: [^self]. newValue := Compiler evaluate: expression. self rememberUndo: self createAppendInsertionUndo. newKey := self privateAdd: newValue. self refresh; select: (self partWithKey: newKey)
drop: partCollection before: aPart "Parts dropped from another object should be inserted." | toInsert newIndices insertionIndex | toInsert := partCollection collect: [:each | each value]. insertionIndex := aPart isNil ifTrue: [self partCount + 1] ifFalse: [aPart key]. newIndices := self privateInsertAll: toInsert beforeIndex: insertionIndex. self rememberUndo: (self createInsertionUndo: newIndices before: aPart). self refresh; selectIndices: newIndices
dropFromSame: partCollection before: aPart "A drop from same object reorders the collection." | toMove newRange | "won't handle undo for now" toMove := partCollection collect: [:each | each key]. newRange := self privateMoveAllAtIndices: toMove beforeIndex: (aPart isNil ifTrue: [self partCount + 1] ifFalse: [aPart key]). self refresh; selectIndices: newRange
pasteIntoSelf: partCollection "A paste with no target selected ('self') means append." | toInsert inserted | toInsert := partCollection collect: [:each | each value]. inserted := self privateInsertAll: toInsert beforeIndex: self partCount + 1. self rememberUndo: (self createInsertionUndo: inserted before: nil). self refresh; selectIndices: inserted
removeSelected "Remove the selected elements." self rememberUndo: self createRemovalUndo. self privateRemoveAtIndices: (self selections collect: [:each | each key]). self refresh
replaceWith: newValue | selections | selections := self selections. selections isEmpty ifTrue: [^self]. self rememberUndo: self createReplacementUndo. selections do: [:each | each value: newValue]. self refresh; selectAll: selections
undoInsertion: anInsertionUndo self privateRemoveAtIndices: anInsertionUndo newKeys. self refresh
undoRemoval: aRemovalUndo aRemovalUndo savedValues do: [:each | self privateInsertAll: (Array with: each value) beforeIndex: each part key]. self refresh; selectAll: aRemovalUndo parts
</methods> <methods> Tools.Trippy.SequenceInspector <category>decomposing</category>
partAt: anIndex ^KeyedElement of: object at: anIndex
partCount ^object size
</methods> <methods> Tools.Trippy.SequenceInspector class <category>accessing</category>
tabLabel ^(#_Elements << #dialogs >> '&Elements')
</methods> <methods> Tools.Trippy.ArrayInspector <category>private</category>
privateAdd: anObject "Yes we can resize arrays in the inspector. It can be handy so why not?" | newObject | newObject := object copyWith: anObject. newObject become: object. ^object size
privateInsertAll: aCollection beforeIndex: anIndex "Insert elements of the argument collection into the array being inspected." | newObject | newObject := object class new: object size + aCollection size. newObject replaceFrom: 1 to: anIndex - 1 with: object startingAt: 1; replaceFrom: anIndex to: anIndex + aCollection size - 1 with: aCollection startingAt: 1; replaceFrom: anIndex + aCollection size to: newObject size with: object startingAt: anIndex. newObject become: object. ^anIndex to: anIndex + aCollection size - 1
privateMoveAllAtIndices: aCollection beforeIndex: anIndex "Reposition elements at indices listed in aCollection so that they are all located at indices {anIndex, anIndex+1, ...}. The size of the resulting collection is the same as that of the original." | static mobile insertionPoint newObject | static := object copy asOrderedCollection. aCollection asSortedCollection reverseDo: [:each | static removeAtIndex: each]. mobile := aCollection collect: [:each | object at: each]. insertionPoint := aCollection inject: anIndex into: [:result :index | index < anIndex ifTrue: [result - 1] ifFalse: [result]]. newObject := object class new: object size. newObject replaceFrom: 1 to: insertionPoint - 1 with: static startingAt: 1; replaceFrom: insertionPoint to: insertionPoint + mobile size - 1 with: mobile startingAt: 1; replaceFrom: insertionPoint + mobile size to: newObject size with: static startingAt: insertionPoint. newObject become: object. ^insertionPoint to: insertionPoint + aCollection size - 1
privateRemoveAtIndices: anIntegerCollection "Remove elements of the object being inspected with indices listed in the argument array." | newObject toRemove targetIndex | toRemove := anIntegerCollection asSet. newObject := object class new: object size - toRemove size. targetIndex := 1. 1 to: object size do: [:sourceIndex | (toRemove includes: sourceIndex) ifFalse: [newObject at: targetIndex put: (object at: sourceIndex). targetIndex := targetIndex + 1]]. newObject become: object
</methods> <methods> Tools.Trippy.ArrayInspector class <category>accessing</category>
tabLabel ^(#_Elements << #dialogs >> '&Elements')
</methods> <methods> Tools.Trippy.IndexedVariable <category>initialize-release</category>
index: anIndex index := anIndex
</methods> <methods> Tools.Trippy.IndexedVariable <category>accessing</category>
asVariableName ^'at', index printString
displayString ^Inspector safeDisplayStringOf: index
index ^index
key ^index
partName ^index printString
value ^object basicAt: index
value: anObject ^object basicAt: index put: anObject
</methods> <methods> Tools.Trippy.IndexedVariable <category>comparing</category>
sameTypeEquals: aPart ^index = aPart index
specificHash ^index hash
</methods> <methods> Tools.Trippy.IndexedVariable class <category>instance creation</category>
of: anObject at: anInteger ^self new object: anObject; index: anInteger
</methods> <methods> Tools.Trippy.TextEditorInspector <category>actions</category>
changeRequest | choice textEditor | textEditor := (self builder componentAt: #text) widget controller. textEditor accepted ifTrue: [^true]. choice := Dialog choose: (#AcceptUnsavedChanges << #dialogs >> 'Accept unsaved changes?') labels: (Array with: (#Yes << #dialogs >> 'Yes') with: (#No << #dialogs >> 'No') with: (#Cancel << #dialogs >> 'Cancel')) values: #(yes no cancel) default: #yes. choice = #cancel ifTrue: [^false]. choice = #yes ifTrue: [textEditor accept]. ^true
copyStateTo: anInspector "There is no state to talk of."
refresh self textHolder value: self object
textAccepted: aController | newObject | newObject := self coerceText: aController text. newObject become: self object. self refresh
</methods> <methods> Tools.Trippy.TextEditorInspector <category>private</category>
coerceText: aTextOrString "Answer the argument as a new instance of a class compatible with that of the current object. We currently assume that can only be one of String subclasses or Text." ^(self object isKindOf: Text) ifTrue: [aTextOrString asText copy] ifFalse: [self object class fromString: aTextOrString asString]
enumerateOwnersToIgnore: aBlock super enumerateOwnersToIgnore: aBlock. aBlock value: textHolder
nukeBogusReferencesIn: aWeakArray referentContext: aContext super nukeBogusReferencesIn: aWeakArray referentContext: aContext. [(aWeakArray indexOf: self textHolder replaceWith: aWeakArray tombstone startingAt: 1 stoppingAt: aWeakArray size) = 0] whileFalse
</methods> <methods> Tools.Trippy.TextEditorInspector <category>aspects</category>
textHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^textHolder isNil ifTrue: [textHolder := String new asValue] ifFalse: [textHolder]
</methods> <methods> Tools.Trippy.TextEditorInspector <category>initialize-release</category>
postBuildWith: aBuilder super postBuildWith: aBuilder. (aBuilder componentAt: #text) widget controller autoAccept: false
</methods> <methods> Tools.Trippy.TextEditorInspector class <category>accessing</category>
tabLabel ^(#Text << #labels >> 'Text')
</methods> <methods> Tools.Trippy.InspectorShell <category>testing</category>
canDive ^self hasCurrentInspector and: [self inspector canDive]
canExploreParts ^installedNavigator vicinity ~~ #parts and: [self inspector isPartList]
canExploreSiblings ^self visit hasOwner and: [installedNavigator vicinity ~~ #owner]
canFocus ^installedNavigator vicinity ~~ #none
canGoBack ^current > 1
canGoForward ^current < trail size
clipboardNotEmpty ^Clipboard default notEmpty
hasCurrentInspector ^current > 0
notExploringVisited ^installedNavigator vicinity ~~ #visited
</methods> <methods> Tools.Trippy.InspectorShell <category>private-evaluation</category>
doItContext "Answer the context in which a text selection can be evaluated." ^nil
doItReceiver "Answer the object in which context the text selection is evaluated." ^self object
evaluatorEditor ^(builder componentAt: #evaluator) widget controller
</methods> <methods> Tools.Trippy.InspectorShell <category>aspects</category>
menuBarHolder ^menuBarHolder
textHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^textHolder isNil ifTrue: [textHolder := String new asValue] ifFalse: [textHolder]
</methods> <methods> Tools.Trippy.InspectorShell <category>actions</category>
back "Go back to the previously visited page, if any." self inspector changeRequest ifFalse: [^self]. current := 1 max: current - 1. self refresh
compareObjectToClipboard | clipboardObjects report | clipboardObjects := Clipboard default get. clipboardObjects isEmpty ifTrue: [^Dialog warn: (#TheClipboardIsEmpty << #dialogs >> 'The clipboard is empty.')]. report := clipboardObjects size = 1 ifTrue: [self compareObjectToOne: clipboardObjects first] ifFalse: [self compareObjectToMany: clipboardObjects ifCancelled: [^self]]. Dialog warn: report
dive "The inspector should take care of diving since it knows what it wants to dive into." self inspector dive
diveIntoClass "Dive into the class of the current object." self diveInto: (DerivedAttribute label: 'class' value: self object class)
emptyClipboard Clipboard default empty
forward "Go forward to the following visited page, if any." self inspector changeRequest ifFalse: [^self]. current := trail size min: current + 1. self refresh
goTo: anIndex "Switch to the page at the specific index on the visit history list." current := 1 max: (anIndex min: trail size). self refresh
helpAbout AboutVisualWorksDialog open
helpInspectingObjects SmalltalkWorkbench openHelpBook: 'Development with VisualWorks' topic: 'Inspecting Objects'
helpInspector SmalltalkWorkbench openHelpBook: 'VisualWorks Tools' topic: 'Inspector'
inspectClipboard | parts object | parts := Clipboard default get. parts size = 0 ifTrue: [^Dialog warn: (#TheClipboardIsEmpty << #dialogs >> 'The clipboard is empty.')]. object := parts size = 1 ifTrue: [parts first value] ifFalse: [parts collect: [:each | each value]]. object inspect
selectAll self inspector selectAll
toggleEvaluationPane evaluationPaneVisible := evaluationPaneVisible not. EvaluationPaneWasLastShown := evaluationPaneVisible. self setEvaluatorLayout. builder window refresh. evaluationPaneVisible ifTrue: [(builder componentAt: #evaluator) takeKeyboardFocus]
toggleToolbar self builder window toolbarVisible: self builder window toolbarVisible not
</methods> <methods> Tools.Trippy.InspectorShell <category>private</category>
addToTrail: aNavigator trail := trail copyFrom: 1 to: current. trail addLast: aNavigator. current := current + 1
compareObjectToMany: partCollection ifCancelled: aBlock | part | part := Dialog choose: (#InspectorClipboardHasMultipleObjects << #dialogs >> 'The clipboard contains multiple objects. Select one:') fromList: (partCollection collect: [:each | each value displayString]) values: partCollection lines: 10 cancel: aBlock for: self builder window. ^self compareObjectToOne: part
compareObjectToOne: partSnapshot | thisObject clipboardObject report | thisObject := self inspector selectedObjectOrInspectedObject. clipboardObject := partSnapshot value. report := TextStream on: (String new: 100). report nextPutAllText: 'Comparing object: '; nextPutAllText: thisObject basicPrintString asText allBold; cr; nextPutAllText: ' to clipboardObject: '; nextPutAllText: clipboardObject basicPrintString asText allBold; cr; cr; nextPutAllText: 'object == clipboardObject: '; nextPutAllText: (self formattedResultOf: [thisObject == clipboardObject]); cr; nextPutAllText: 'object = clipboardObject: '; nextPutAllText: (self formattedResultOf: [thisObject = clipboardObject]); cr; nextPutAllText: 'clipboardObject = object: '; nextPutAllText: (self formattedResultOf: [clipboardObject = thisObject]). ^report contents
diveIntoCollaborator: aCollaborator self diveInto: (aCollaborator asPartOf: self object)
dividerFraction ^evaluationPaneVisible ifTrue: [0.6] ifFalse: [1]
dividerOffset ^evaluationPaneVisible ifTrue: [-2] ifFalse: [0]
formattedResultOf: aBlock | result | result := aBlock on: Error do: [:ex | ^(#errorC1s << #dialogs >> '[error: <1s>]') expandMacrosWith: ex description]. ^result printString asText allBold
install: aNavigator | subBuilder | aNavigator builder: nil. installedNavigator := aNavigator. (self builder componentAt: #navigator) widget client: aNavigator spec: #windowSpec builder: (subBuilder := builder newSubBuilder). aNavigator installedWith: subBuilder
privateChangeRequest | choice | self inspector changeRequest ifFalse: [^false]. self evaluatorEditor accepted ifTrue: [^true]. choice := Dialog choose: (#CodeHasBeenChanged << #dialogs >> 'The code in the evaluation pane has been changed. Remember it for future use?') labels: (Array with: (#Yes << #dialogs >> 'Yes') with: (#No << #dialogs >> 'No') with: (#Cancel << #dialogs >> 'Cancel')) values: #(yes no cancel) default: #yes. choice = #cancel ifTrue: [^false]. choice = #yes ifTrue: [self evaluatorEditor accept]. ^true
refresh "Completely rebuild the UI." self install: (trail at: current); refreshMenuBar; refreshToolbar; refreshWindowLabel
refreshToolbar | toolbar | toolbar := builder componentAt: #toolbar. (toolbar componentAt: #back) isEnabled: self canGoBack. (toolbar componentAt: #forward) isEnabled: self canGoForward. (toolbar componentAt: #focus) isEnabled: self canFocus. (toolbar componentAt: #exploreSiblings) isEnabled: self canExploreSiblings. (toolbar componentAt: #exploreVisited) isEnabled: self notExploringVisited
refreshWindowLabel builder window label: self visit displayString
resetTrailFor: aVisit | result thisVisit | (trail includes: [:some | some visit == aVisit]) ifTrue: [^self]. result := OrderedCollection new. thisVisit := aVisit. [thisVisit notNil] whileTrue: [result add: (NullNavigator visit: thisVisit shell: self). thisVisit := thisVisit owner]. trail := result reverse. current := trail size
resetTrailForNew: aVisit | result thisVisit | trail last visit = aVisit owner ifTrue: [^self]. result := OrderedCollection new. thisVisit := aVisit owner. [thisVisit notNil] whileTrue: [result add: (NullNavigator visit: thisVisit shell: self). thisVisit := thisVisit owner]. trail := result reverse. current := trail size
setEvaluatorLayout | fraction offset | fraction := self dividerFraction. offset := self dividerOffset. (builder componentAt: #navigator) component layout bottomFraction: fraction; bottomOffset: offset. (builder componentAt: #splitter) component layout topFraction: fraction; topOffset: offset; bottomFraction: fraction; bottomOffset: offset negated. (builder componentAt: #evaluatorPane) component layout topFraction: fraction; topOffset: offset negated
</methods> <methods> Tools.Trippy.InspectorShell <category>privileged</category>
diveInto: aPart "Sent by the current inspector to dive into the part of the currently selected object. Because this affects the navigation environment, it is the shell's responsibility." | visit navigator | visit := self visit visitOfPart: aPart ifNone: [PartVisit part: aPart owner: self visit inspector: self inspector]. navigator := NullNavigator visit: visit shell: self. self resetTrailForNew: visit. self addToTrail: navigator. self refresh
doWithOwnersToIgnore: aBlock "See the comment to Inspector>>doWithOwnersToIgnore: for a detailed explanation. This class is the top component, therefore here we start trickling down enumerating junk owners on our way." self enumerateOwnersToIgnore: aBlock
enumerateOwnersToIgnore: aBlock aBlock value: self; value: builder window; value: builder window component; value: (self widgetAt: #evaluator). origin enumerateOwnersToIgnore: aBlock. trail do: [:each | each enumerateOwnersToIgnore: aBlock]
focusObjectChanged "Some pages may replace the object they have been initially opened on with another object. A hierarchy page does that when a new element of a hierarchy is selected. This message is then sent to the shell to notify it of the change." self refreshMenuBar; refreshToolbar; refreshWindowLabel
partValueChanged: aPart self visit forgetVisitOfPart: aPart
revisit: aVisit self resetTrailFor: aVisit. self refresh
</methods> <methods> Tools.Trippy.InspectorShell <category>initialize-release</category>
initialize super initialize. current := 0. evaluationPaneVisible := false. textHolder := SharedTextHolder. menuBarHolder := ValueHolder with: nil
inspect: anObject | navigator | origin := Visit object: anObject. navigator := NullNavigator visit: origin shell: self. trail := OrderedCollection with: navigator. current := 1. self refresh
postBuildWith: aBuilder evaluationPaneVisible := EvaluationPaneWasLastShown. self setEvaluatorLayout. self evaluatorEditor initializeMenuForCode; autoAccept: false
</methods> <methods> Tools.Trippy.InspectorShell <category>private-page switches</category>
exploreFocus | navigator | navigator := NullNavigator visit: self visit shell: self inspector: self inspector. trail at: current put: navigator. self refresh
exploreHierarchy: aHierarchy | navigator | navigator := HierarchyNavigator visit: self visit hierarchy: aHierarchy shell: self inspector: self inspector. self addToTrail: navigator. self refresh
exploreParts | selection visit navigator | self inspector isPartList ifFalse: [^self]. self inspector hasSingleSelection ifFalse: [self inspector select: (self inspector partAt: 1)]. selection := self inspector selection. selection hasValue ifFalse: [self inspector select: (self inspector partAt: 1). selection := self inspector selection]. visit := self visit visitOfPart: selection ifNone: [PartVisit part: selection owner: self visit inspector: self inspector]. navigator := OwnerNavigator visit: visit shell: self. navigator bePartsNavigator. self addToTrail: navigator. self refresh
exploreSiblings | navigator | navigator := OwnerNavigator visit: self visit shell: self inspector: self inspector. trail at: current put: navigator. self refresh
exploreVisited | navigator | navigator := VisitTreeNavigator new initialize: origin shell: self initialVisit: self visit inspector: self inspector. self install: navigator; refreshMenuBar; refreshToolbar; refreshWindowLabel
showVicinity: aSelector | navigator | navigator := self object perform: aSelector. navigator initialize: self visit shell: self inspector: self inspector. self addToTrail: navigator. self refresh
</methods> <methods> Tools.Trippy.InspectorShell <category>accessing</category>
changeRequest ^[self privateChangeRequest] on: Error do: [:ex | ex return: true]
inspector ^self navigator inspector
navigator ^installedNavigator
object ^self inspector object
visit ^self navigator visit
</methods> <methods> Tools.Trippy.InspectorShell <category>private-menus</category>
addCollaboratorItemsTo: aMenu | collaborators item | collaborators := Inspector cautiousSend: #inspectorCollaborators to: self object else: [^self]. collaborators do: [:each | item := MenuItem labeled: (#ToCollaborator << #menus >> 'To <1s>' expandMacrosWith: each label). item value: [self diveIntoCollaborator: each]. aMenu addItem: item]
addExploreItemsTo: aMenu | hierarchies | hierarchies := Inspector cautiousSend: #inspectorHierarchies to: self object else: [^self]. hierarchies isEmpty ifFalse: [aMenu addLine. hierarchies do: [:each | | item | item := MenuItem labeled: each label. item value: [self exploreHierarchy: each]. self navigator vicinity = each id ifTrue: [item beOn]. aMenu addItem: item]]
buildExploreSubmenu | aSubmenu | aSubmenu := self class baseExploreMenu. installedNavigator vicinity == #none ifTrue: [(aSubmenu atNameKey: #exploreFocus) beOn]. installedNavigator vicinity == #owner ifTrue: [(aSubmenu atNameKey: #exploreSiblings) beOn]. self visit hasOwner ifFalse: [(aSubmenu atNameKey: #exploreSiblings) disable]. installedNavigator vicinity == #self ifTrue: [(aSubmenu atNameKey: #exploreParts) beOn]. self inspector isPartList ifFalse: [(aSubmenu atNameKey: #exploreParts) disable]. installedNavigator vicinity == #visited ifTrue: [(aSubmenu atNameKey: #exploreVisited) beOn]. self addExploreItemsTo: aSubmenu. ^aSubmenu
buildGoSubmenu | menu | menu := self class baseGoSubmenu. (menu atNameKey: #goDive) enabled: [self canDive]. (menu atNameKey: #goBack) enabled: [self canGoBack]. (menu atNameKey: #goForward) enabled: [self canGoForward]. self addCollaboratorItemsTo: menu. ^menu
buildHistorySubmenu | menu item | menu := Menu new. trail keysAndValuesDo: [:index :navigator | | label | label := index < 10 ifTrue: ['&', index printString, '. ', navigator visit displayString] ifFalse: [navigator visit displayString]. item := MenuItem labeled: label. item value: [self goTo: index]. index = current ifTrue: [item beOn]. menu addItem: item]. ^menu
buildMenuBar | menu | menu := self class menuBar. self hasCurrentInspector ifTrue: [self inspector augmentMenuBar: menu]. (menu atNameKey: #go) submenu: self buildGoSubmenu. (menu atNameKey: #history) submenu: self buildHistorySubmenu. (menu atNameKey: #explore) submenu: self buildExploreSubmenu. (menu atNameKey: #toggleToolbar) indication: [self builder window toolbarVisible]. (menu atNameKey: #toggleEvaluationPane) indication: [evaluationPaneVisible]. [menu augmentFrom: self class to: InspectorShell menuName: #menuBar for: self] on: MenuAugmentationError do: [:ex | ex isResumable ifTrue: [ex resume]]. ^menu
refreshMenuBar menuBarHolder value: self buildMenuBar
</methods> <methods> Tools.Trippy.InspectorShell <category>user interface</category>
inspectorCollaborators ^Array with: (Collaborator label: (#Navigator << #labels >> 'Navigator') block: [self navigator]) with: (Collaborator label: (#Inspector << #labels >> 'Inspector') block: [self inspector])
</methods> <methods> Tools.Trippy.InspectorShell class <category>generated resources</category>
buildImageWithEnablement: baseString ^OpaqueImageWithEnablement figure: (ToolbarIconLibrary perform: (baseString, '20x20') asSymbol) shape: (ToolbarIconLibrary perform: (baseString, '20x20mask') asSymbol) inactiveMask: (ToolbarIconLibrary perform: (baseString, '20x20bw') asSymbol)
exploreParts "Cannot share these because enablement status is set in the images." ^self buildImageWithEnablement: 'exploreParts'
exploreSiblings "Cannot share these because enablement status is set in the images." ^self buildImageWithEnablement: 'exploreSiblings'
exploreVisited "Cannot share these because enablement status is set in the images." ^self buildImageWithEnablement: 'exploreVisited'
focus "Cannot share these because enablement status is set in the images." ^self buildImageWithEnablement: 'exploreOff'
next "Cannot share these because enablement status is set in the images." ^self buildImageWithEnablement: 'next'
previous "Cannot share these because enablement status is set in the images." ^self buildImageWithEnablement: 'previous'
</methods> <methods> Tools.Trippy.InspectorShell class <category>instance creation</category>
openOn: anObject self new open; inspect: anObject
</methods> <methods> Tools.Trippy.InspectorShell class <category>notifications</category>
instanceMethodsChanged Screen default allScheduledControllersDo: [:each | (each model isKindOf: self) ifTrue: [each model refreshMenuBar]]
</methods> <methods> Tools.Trippy.HierarchyNavigator <category>aspects</category>
hierarchyHolder "This method was generated by UIDefiner. Any edits made here may be lost whenever methods are automatically defined. The initialization provided below may have been preempted by an initialize method." ^hierarchyHolder isNil ifTrue: [hierarchyHolder := IndentedTreeSelectionInList new] ifFalse: [hierarchyHolder]
</methods> <methods> Tools.Trippy.HierarchyNavigator <category>accessing</category>
contractAll self hierarchyHolder selectionIndex: 1; deepCloseCurrent; deepOpenCurrentTo: 1
contractBranch self hierarchyHolder deepCloseCurrent
expandAll self hierarchyHolder selectionIndex: 1; deepOpenCurrent
expandBranch self hierarchyHolder deepOpenCurrent
vicinity ^hierarchy id
</methods> <methods> Tools.Trippy.HierarchyNavigator <category>private</category>
expandToObject | path this parent | path := OrderedCollection new. this := self object. [path add: this. (parent := hierarchy parentOf: this) notNil] whileTrue: [this := parent]. path reverse do: [:nextObject | hierarchyHolder open: nextObject]
initialHierarchySelection ^self object
nameOf: anObject | string | string := Inspector safeDisplayStringOf: anObject. ^anObject == self object ifTrue: [string asText allBold] ifFalse: [string]
</methods> <methods> Tools.Trippy.HierarchyNavigator <category>initialize-release</category>
initialize: aVisit hierarchy: aHierarchy shell: aShell inspector: anInspector super initialize: aVisit shell: aShell inspector: anInspector. originalVisit := aVisit. hierarchy := aHierarchy. root := aHierarchy rootOf: self object. hierarchyHolder := IndentedTreeSelectionInList listObjectHierarchy: #root childBlock: [:thing | #root == thing ifTrue: [Array with: root] ifFalse: [hierarchy childrenOf: thing]] childNameBlock: [:thing | self nameOf: thing]. hierarchyHolder expandedEmphasis: #(). self expandToObject
installedWith: aBuilder (aBuilder componentAt: #hierarchyList) widget makeVisible: self hierarchyHolder selectionIndex
postBuildWith: aBuilder "Some ugliness was needed to work around a problem with subcanvases being built inside other subcanvases on postBuildWith: event." self reinstallInspector. self hierarchyHolder selection: self initialHierarchySelection. hierarchyHolder selectionIndexHolder onChangeSend: #hierarchyElementSelected to: self
</methods> <methods> Tools.Trippy.HierarchyNavigator <category>notification</category>
hierarchyDoubleClicked shell exploreFocus
hierarchyElementSelected "A new member of the hierarchy is selected. Update the subordinate page to display the newly selected object, if there is indeed an object selected." | selection | selection := self hierarchyHolder selection. selection isNil ifTrue: [^self]. inspector object == selection ifTrue: [^self]. visit := originalVisit object == selection ifTrue: [originalVisit] ifFalse: [originalVisit visitOf: selection ifNone: [Visit object: selection owner: originalVisit]]. self replaceInspectorWithOneOn: self object
</methods> <methods> Tools.Trippy.HierarchyNavigator class <category>instance creation</category>
visit: aVisit hierarchy: aHierarchy shell: aShell inspector: anInspector ^self new initialize: aVisit hierarchy: aHierarchy shell: aShell inspector: anInspector
</methods> <methods> Tools.Trippy.VisitTreeNavigator <category>accessing</category>
object ^self visit object
vicinity ^#visited
visit ^self hierarchyHolder selection
</methods> <methods> Tools.Trippy.VisitTreeNavigator <category>notification</category>
hierarchyDoubleClicked shell revisit: self hierarchyHolder selection
</methods> <methods> Tools.Trippy.VisitTreeNavigator <category>initialize-release</category>
initialize: aVisit shell: anInspectorShell initialVisit: aVisit2 inspector: anInspector root := aVisit. visit := originalVisit := Visit object: aVisit object. shell := anInspectorShell. inspector := anInspector. startingVisit := aVisit2. hierarchyHolder := IndentedTreeSelectionInList listObjectHierarchy: #root childBlock: [:thing | #root == thing ifTrue: [Array with: root] ifFalse: [thing children]] childNameBlock: [:thing | thing displayString]. hierarchyHolder expandedEmphasis: #(); selection: startingVisit. self refreshInspectorClasses
postBuildWith: aBuilder self hierarchyHolder selectionIndex: 1; deepOpenCurrent. super postBuildWith: aBuilder.
</methods> <methods> Tools.Trippy.VisitTreeNavigator <category>private</category>
initialHierarchySelection ^startingVisit
</methods> <methods> Tools.Trippy.InsertionUndo <category>accessing</category>
explanation ^(#Addition << #dialogs >> 'Addition')
newKeys ^newKeys
undoIn: aPage aPage undoInsertion: self
</methods> <methods> Tools.Trippy.InsertionUndo <category>initialize-release</category>
newKeys: aCollection newKeys := aCollection
</methods> <methods> Tools.Trippy.InsertReplaceDragController <category>private</category>
doDrop: aDragContext | parts | parts := aDragContext data clientData. self insertUsing: [:part | aDragContext sourceData contextApplication == page ifTrue: [page dropFromSame: parts before: part] ifFalse: [page drop: parts before: part]] orReplaceUsing: [:part | aDragContext sourceData contextApplication == page ifTrue: [page dropFromSame: parts at: part] ifFalse: [page drop: parts at: part]]
insertUsing: insertionBlock orReplaceUsing: replacementBlock | index part | index := view insertionOrReplacementIndexFor: view controller sensor cursorPoint. ^index isInteger ifTrue: "over an element" [part := page fieldListHolder list at: index. replacementBlock value: part] ifFalse: "between elements" [ | listIndex | listIndex := index ceiling. part := listIndex > page fieldListHolder list size ifTrue: [nil] ifFalse: [page fieldListHolder list at: listIndex]. insertionBlock value: part]
showDropFeedbackFor: aDragContext view showInsertReplaceDropFeedbackIn: aDragContext allowScrolling: true. ^self insertUsing: [:part | (page isInsertableBefore: part) ifTrue: [self dropEffect: aDragContext] ifFalse: [#dropEffectNone]] orReplaceUsing: [:part | part isReadOnly ifFalse: [self dropEffect: aDragContext] ifTrue: [#dropEffectNone]]
</methods> <methods> Tools.Trippy.Action <category>accessing</category>
enablement ^enablementBlock value
isEnabled ^enablementBlock value
label ^label
perform ^actionBlock value
</methods> <methods> Tools.Trippy.Action <category>initialize-release</category>
label: aString actionBlock: aBlock self label: aString actionBlock: aBlock enablementBlock: [true]
label: aString actionBlock: aBlock enablementBlock: aBlock2 label := aString. actionBlock := aBlock. enablementBlock := aBlock2
</methods> <methods> Tools.Trippy.Action class <category>instance creation</category>
label: aString block: aBlock ^self new label: aString actionBlock: aBlock
label: aString block: aBlock enablement: aBlock2 ^self new label: aString actionBlock: aBlock enablementBlock: aBlock2
</methods> <methods> Tools.Trippy.UndoActionGroup <category>initialize-release</category>
initialize: actionCollection actions := actionCollection
</methods> <methods> Tools.Trippy.UndoActionGroup <category>accessing</category>
undoIn: anInspector actions do: [:each | each undoIn: anInspector]
</methods> <methods> Tools.Trippy.UndoActionGroup class <category>instance creation</category>
with: action1 with: action2 ^self new initialize: (Array with: action1 with: action2)
with: action1 with: action2 with: action3 ^self new initialize: (Array with: action1 with: action2 with: action3)
</methods> <methods> Tools.Trippy.Clipboard <category>private</category>
fromLocal: anObject ^anObject == zeroStandIn ifTrue: [0] ifFalse: [anObject]
toLocal: anObject "If a 0 is stored on the clipboard, it has to be replaced with a different object to distinguish it from dead values." ^0 == anObject ifTrue: [zeroStandIn] ifFalse: [anObject]
</methods> <methods> Tools.Trippy.Clipboard <category>initialize-release</category>
initialize zeroStandIn := '0' copy. "unique object to stand in for 0 value" self empty
</methods> <methods> Tools.Trippy.Clipboard <category>testing</category>
isEmpty ^values size = 0 or: [values detect: [:some | some ~~ 0] ifNone: [^true]. ^false]
notEmpty ^self isEmpty not
</methods> <methods> Tools.Trippy.Clipboard <category>accessing</category>
empty parts := Array new. values := Array new
get "Answer PartSnapshots of parts with not yet dead values." | result | result := OrderedCollection new: parts size. parts with: values do: [:part :value | 0 ~~ value ifTrue: [result add: (PartSnapshot new part: part value: (self fromLocal: value))]]. ^result
put: aPartCollection parts := aPartCollection select: [:each | each hasValue]. values := WeakArray new: parts size. parts keysAndValuesDo: [:index :part | values at: index put: (self toLocal: part value)]
</methods> <methods> Tools.Trippy.Clipboard class <category>accessing</category>
default Default isNil ifTrue: [Default := self new]. ^Default
</methods> <methods> Tools.Trippy.Clipboard class <category>instance creation</category>
new ^super new initialize
</methods> <methods> Tools.Trippy.Collaborator <category>initialize-release</category>
initialize: aString object: anObject label := aString. object := anObject
initialize: aString objectBlock: aBlock label := aString. objectBlock := aBlock
variableName: aString varName := aString
</methods> <methods> Tools.Trippy.Collaborator <category>accessing</category>
asPartOf: anObject ^self isVariable ifTrue: [NamedVariable of: anObject named: self variableName] ifFalse: [DerivedAttribute label: self label value: self object]
label ^label
object ^objectBlock isNil ifTrue: [object] ifFalse: [objectBlock value]
variableName ^varName
</methods> <methods> Tools.Trippy.Collaborator <category>testing</category>
isVariable "True if collaborator is one of the object's instance variables; false otherwise." ^varName notNil
</methods> <methods> Tools.Trippy.Collaborator class <category>instance creation</category>
label: aString block: aBlock ^self new initialize: aString objectBlock: aBlock
label: aString object: anObject ^self new initialize: aString object: anObject
label: aString variable: aString2 object: anObject ^(self new initialize: aString object: anObject) variableName: aString2
</methods> <methods> UI.ApplicationStandardSystemController class <category>user interface</category>
protectedInstVarNames ^self instVarNames
</methods> <methods> UI.ScheduledWindow <category>user interface</category>
componentHierarchyChildren ^Array with: component
inspectorActions ^Array with: (Tools.Trippy.Action label: (#Raise << #dialogs >> 'Raise') block: [self raise] enablement: [self isOpen]) with: (Tools.Trippy.Action label: (#Close << #dialogs >> 'Close') block: [self close] enablement: [self isOpen])
inspectorClasses ^Array with: Tools.Trippy.PreviewingInspector with: Tools.Trippy.BasicInspector
inspectorCollaborators ^Array with: (Tools.Trippy.Collaborator label: (#Model << #dialogs >> 'Model') variable: 'model' object: model) with: (Tools.Trippy.Collaborator label: (#Controller << #dialogs >> 'Controller') variable: 'controller' object: controller) with: (Tools.Trippy.Collaborator label: (#Component << #dialogs >> 'Component') variable: 'component' object: component)
inspectorHierarchies ^Array with: (Tools.Trippy.Hierarchy id: #componentHierarchy label: (#ComponentHierarchy << #dialogs >> 'Component Hierarchy') parentBlock: [:vc | vc componentHierarchyParent] childrenBlock: [:vc | vc componentHierarchyChildren])
</methods> <methods> Core.Fraction <category>printing</category>
inspectorExtraAttributes ^Array with: (Tools.Trippy.DerivedAttribute label: #asFloat << #dialogs >> 'asFloat' valueBlock: [self asFloat])
</methods> <methods> Core.Set <category>user interface</category>
inspectorClasses ^Array with: Tools.Trippy.SetInspector with: Tools.Trippy.BasicInspector
</methods> <methods> Core.ClassDescription class <category>user interface</category>
protectedInstVarNames ^self instVarNames
</methods> <methods> Core.ClassDescription <category>user interface</category>
inspectorExtraAttributes ^Array with: (Tools.Trippy.TextAttribute label: (#comment << #dialogs >> 'comment') textBlock: [self comment])
</methods> <methods> Core.Signal <category>user interface</category>
inspectorHierarchies ^Array with: (Tools.Trippy.Hierarchy id: #exception label: (#ExceptionHierarchy << #dialogs >> 'Exception Hierarchy') parentBlock: [:ex | ex isBehavior ifTrue: [ex == GenericException ifTrue: [nil] ifFalse: [ex superclass]] ifFalse: [ex parent]] childrenBlock: [:ex | (Signal allInstances select: [:some | some parent == self]), (ex isBehavior ifTrue: [ex subclasses] ifFalse: [#()])])
</methods> <methods> Core.Object <category>user interface</category>
inspect "Create and schedule an Inspector in which the user can examine the receiver's variables." Tools.Trippy.Inspector useSimpleInspector ifTrue: [self inspectorClass openOn: self] ifFalse: [Tools.Trippy.Inspector openOn: self]
inspectorActions "Answer a collection of Action instances listing the common actions a user might want to perform on an object. They are added to the inspector's Object menu." ^#()
inspectorClasses "Answer a sequence of inspector classes that can represent the receiver in an inspector. The first page in the array is the one used by default in a new inspector." ^Array with: Tools.Trippy.BasicInspector
inspectorCollaborators "Answer a collection of Collaborator instances listing the important other objects a person looking at this one might want to see. For example, collaborators of a view would be its model and the controller. Collaborators are added to the inspector's Go menu." ^#()
inspectorExtraAttributes "Subclasses may reimplement this to answer a sequence of DerivedAttribute or TextAttribute instances that should show up in the inspector in addition to named instance variables and indexed variables. See implementors for an example." ^#()
inspectorHierarchies "Answer a collection of instances of Hierarchy describing the hierarchies this object is a member of." ^#()
</methods> <methods> UI.View <category>user interface</category>
inspectorCollaborators ^Array with: (Tools.Trippy.Collaborator label: (#Model << #labels >> 'Model') variable: 'model' object: model) with: (Tools.Trippy.Collaborator label: (#Controller << #labels >> 'Controller') variable: 'controller' object: controller)
</methods> <methods> Kernel.Context <category>user interface</category>
inspectorExtraAttributes ^self method inspectorExtraAttributes
</methods> <methods> Kernel.GeneralNameSpace <category>user interface</category>
inspectorClasses ^Array with: Tools.Trippy.PoolDictionaryInspector with: Tools.Trippy.BasicInspector
</methods> <methods> Core.CharacterArray <category>user interface</category>
inspectorClasses ^Array with: Tools.Trippy.TextEditorInspector with: Tools.Trippy.ArrayInspector with: Tools.Trippy.BasicInspector
</methods> <methods> Core.KeyedCollection <category>user interface</category>
inspectorClasses ^self size > 10000 ifTrue: [Array with: Tools.Trippy.BasicInspector] ifFalse: [Array with: Tools.Trippy.DictionaryInspector with: Tools.Trippy.BasicInspector]
</methods> <methods> UI.SubCanvasSpec <category>user interface</category>
specHierarchyChildren "Try to get the spec we embed and return it as the children. This will not work for all possible uses of subcanvases since majorKey and minorKey are not required to be a class reference and a selector but it will make life easier at least in some cases." ^[Array with: (self majorKey value interfaceSpecFor: self minorKey)] on: Error do: [:ex | ex return: nil]
</methods> <methods> UI.SpecCollection <category>user interface</category>
specHierarchyChildren ^collection
</methods> <methods> Core.OrderedCollection <category>user interface</category>
inspectorClasses ^Array with: Tools.Trippy.SequenceInspector with: Tools.Trippy.BasicInspector
</methods> <methods> Kernel.CompiledMethod <category>user interface</category>
inspectorActions ^Array with: (Tools.Trippy.Action label: (#BrowseMethod << #dialogs >> 'Browse Method') block: [| array md | array := self who. md := MethodDefinition class: (array at: 1) selector: (array at: 2). MethodCollector new openListBrowserOn: (Array with: md) label: (#InspectedMethod << #dialogs >> 'Inspected Method') initialSelection: nil] enablement: [self who notNil])
</methods> <methods> Graphics.VisualComponent <category>user interface</category>
componentHierarchyChildren ^Array new
componentHierarchyParent ^nil
inspectorClasses "For VisualComponents, the preferred page is not the first one. See the redefined #preferredInspectorPageClass." ^Array with: Tools.Trippy.PreviewingInspector with: Tools.Trippy.BasicInspector
inspectorHierarchies ^Array with: (Tools.Trippy.Hierarchy id: #componentHierarchy label: (#ComponentHierarchy << #dialogs >> 'Component Hierarchy') parentBlock: [:vc | vc componentHierarchyParent] childrenBlock: [:vc | vc componentHierarchyChildren])
</methods> <methods> UI.ControlManager class <category>user interface</category>
protectedInstVarNames ^self instVarNames
</methods> <methods> Kernel.CompiledCode <category>user interface</category>
inspectorExtraAttributes ^Array with: (Tools.Trippy.TextAttribute label: (#bytecode << #dialogs >> 'bytecode') textBlock: [self symbolic]) with: (Tools.Trippy.TextAttribute label: (#decompiled << #dialogs >> 'decompiled') textBlock: [self decompiledSource]) with: (Tools.Trippy.TextAttribute label: (#source << #dialogs >> 'source') textBlock: [(self homeMethod getSourceForUserIfNone: [(#noSource << #dialogs >> 'no source')]) asText makeSelectorBoldIn: self mclass])
</methods> <methods> Core.Behavior <category>user interface</category>
inspectorCollaborators ^Array with: (Tools.Trippy.Collaborator label: (#AllInstances << #labels >> 'All Instances') block: [self allInstances])
inspectorHierarchies ^Array with: (Tools.Trippy.Hierarchy id: #class label: (#ClassHierarchy << #labels >> 'Class Hierarchy') parentBlock: [:class | class superclass] childrenBlock: [:class | class subclasses asSortedCollection: [:a :b | a name <= b name]])
protectedInstVarNames "Answer a collection of instance variable names that should be treated by the inspector as protected -- see the explanation in Part>>isProtected. Note that the inspector sends this message to all classes on the inheritance chain and collects all answered names. This method will typically be implemented on the class side, and would answer either a collection of variable names (strings) or be implemented as ^self instVarNames or ^self allInstVarNames." ^#()
</methods> <methods> Core.Integer <category>printing</category>
asShortSizeInBytes | baseOneKilobyte sizeUnits toGo leadingDigitIndex answer | sizeUnits := #('' 'B' 'K' 'M' 'G' 'T'). self < 0 ifTrue: [^'-', self negated asShortSizeInBytes]. self = 0 ifTrue: [^self printString, (sizeUnits at: 2)]. baseOneKilobyte := Array new: sizeUnits size. baseOneKilobyte at: 1 put: 0. toGo := self. 2 to: sizeUnits size do: [:each | baseOneKilobyte at: each put: (toGo bitAnd: 1023). toGo := toGo bitShift: -10 ]. toGo > 0 ifTrue: [baseOneKilobyte at: sizeUnits size put: toGo * 1024 + (baseOneKilobyte at: sizeUnits size)]. leadingDigitIndex := baseOneKilobyte findLast: [:one | one > 0]. leadingDigitIndex = 0 ifTrue: [leadingDigitIndex := baseOneKilobyte size]. answer := String new writeStream. (baseOneKilobyte at: leadingDigitIndex) printOn: answer. leadingDigitIndex > 2 ifTrue: [ answer nextPut: $.. ((baseOneKilobyte at: leadingDigitIndex - 1) * 100 // 1024) printOn: answer paddedWith: $0 to: 2 base: 10 ]. answer nextPutAll: (sizeUnits at: leadingDigitIndex). ^answer contents
</methods> <methods> Core.Integer <category>user interface</category>
inspectorExtraAttributes ^Array with: (Tools.Trippy.TextAttribute label: (#hexadecimal << #dialogs >> 'hexadecimal') text: (self printStringRadix: 16)) with: (Tools.Trippy.TextAttribute label: (#octal << #dialogs >> 'octal') text: (self printStringRadix: 8)) with: (Tools.Trippy.TextAttribute label: (#binary << #dialogs >> 'binary') text: self paddedBinaryPrintString)
paddedBinaryPrintString "Answer a string with the ''hacker's'' binary representation of the receiver-- broken into bytes and padded to a power-of-two number of bytes." | binaryDigits paddedSize paddedString binaryStream | binaryDigits := self abs printStringRadix: 2. paddedSize := 8. [paddedSize < binaryDigits size] whileTrue: [paddedSize := 2 * paddedSize]. paddedString := String new: paddedSize withAll: $0. paddedString replaceFrom: paddedSize - binaryDigits size + 1 to: paddedSize with: binaryDigits. binaryStream := (String new: 50) writeStream. self < 0 ifTrue: [binaryStream nextPutAll: '-']. 1 to: paddedSize by: 8 do: [:base | binaryStream nextPutAll: (paddedString copyFrom: base to: base + 7); space]. binaryStream skip: -1. ^binaryStream contents
</methods> <methods> Core.Symbol <category>user interface</category>
inspectorClasses "Removing the superclass' TextEditorInspector-- at least until I think well about what it could do to symbols." ^Array with: Tools.Trippy.BasicInspector with: Tools.Trippy.ArrayInspector
</methods> <methods> Core.GenericException class <category>user interface</category>
inspectorHierarchies ^Array with: (Tools.Trippy.Hierarchy id: #class label: (#ClassHierarchy << #dialogs >> 'Class Hierarchy') parentBlock: [:class | class superclass] childrenBlock: [:class | class subclasses]) with: (Tools.Trippy.Hierarchy id: #exception label: (#ExceptionHierarchy << #dialogs >> 'Exception Hierarchy') parentBlock: [:ex | ex isBehavior ifTrue: [ex == GenericException ifTrue: [nil] ifFalse: [ex superclass]] ifFalse: [ex parent]] childrenBlock: [:ex | (Signal allInstances select: [:some | some parent == self]), (ex isBehavior ifTrue: [ex subclasses] ifFalse: [#()])])
</methods> <methods> UI.FullSpec <category>user interface</category>
specHierarchyChildren ^Array with: window with: component
</methods> <methods> UI.Controller class <category>user interface</category>
protectedInstVarNames ^self instVarNames
</methods> <methods> UI.Controller <category>user interface</category>
inspectorCollaborators ^Array with: (Tools.Trippy.Collaborator label: (#Model << #labels >> 'Model') variable: 'model' object: model) with: (Tools.Trippy.Collaborator label: (#View << #labels >> 'View') variable: 'view' object: view)
</methods> <methods> Kernel.ObjectMemory <category>utilities</category>
inspectorExtraAttributes | stream | stream := String new writeStream. self spaceSummaryOn: stream. ^Array with: (Tools.Trippy.TextAttribute label: #statistics << #dialogs >> 'statistics' text: stream contents)
print: name used: used total: total threshold: threshold objects: objects on: aStream "name: used / total[ @ threshold][, objs]" aStream cr; nextPutAll: name; nextPutAll: ': '; nextPutAll: used asShortSizeInBytes; nextPutAll: ' / '; nextPutAll: total asShortSizeInBytes. threshold ifNotNil: [ aStream nextPutAll: ' @ '; nextPutAll: threshold asShortSizeInBytes ]. objects ifNotNil: [ aStream nextPutAll: ', '; nextPutAll: objects printString ]
spaceSummaryOn: aStream aStream cr; nextPutAll: (#SpaceHeader << #dialogs >> 'SPACE: used / total[ @ threshold][, objects]') expandMacros; cr. self print: 'EDEN' used: edenUsedBytes total: edenBytes threshold: edenUsedBytesScavengeThreshold objects: nil on: aStream; print: 'SURVIVOR' used: survUsedBytes total: survBytes threshold: survUsedBytesTenuringThreshold objects: nil on: aStream; print: 'LARGE' used: largeUsedBytes total: largeBytes threshold: largeBytes - largeFreeBytesTenuringThreshold objects: largeUsedObjects on: aStream; print: 'OLD' used: availableFreeOldSpaceBytes total: oldBytes threshold: oldBytes - availableFreeOldSpaceBytesLimit objects: oldOTEs on: aStream; print: 'PERM' used: permDataBytes total: permBytes threshold: nil objects: permOTEs on: aStream; print: 'FIXED' used: fixedUsedBytes total: fixedBytes threshold: nil objects: fixedUsedObjects on: aStream.
</methods> <methods> Core.ArrayedCollection <category>user interface</category>
inspectorClasses "For some arrayed collections there is no real difference between the array and basic views, but for some there is so let's provide both. If this proves to be confusing, we can do a finer-grained tuning in individual subclasses." ^Array with: Tools.Trippy.ArrayInspector with: Tools.Trippy.BasicInspector
</methods> <methods> Core.Dictionary <category>user interface</category>
inspectorClasses ^Array with: Tools.Trippy.DictionaryInspector with: Tools.Trippy.BasicInspector
</methods> <methods> Core.Metaclass class <category>user interface</category>
protectedInstVarNames ^self instVarNames
</methods> <methods> UI.UISpecification <category>user interface</category>
inspectorHierarchies ^Array with: (Tools.Trippy.Hierarchy id: #specHierarchy label: (#SpecHierarchy << #labels >> 'Spec Hierarchy') root: self childrenBlock: [:spec | spec specHierarchyChildren])
</methods> <methods> Graphics.VisualPart <category>user interface</category>
componentHierarchyParent ^container
inspectorActions ^Array with: (Tools.Trippy.Action label: (#Flash << #dialogs >> 'Flash') block: [self flash])
</methods> <methods> Graphics.CompositePart <category>user interface</category>
componentHierarchyChildren ^components
</methods> <methods> UI.ApplicationWindow <category>user interface</category>
inspectorCollaborators ^super inspectorCollaborators copyWith: (Tools.Trippy.Collaborator label: (#Application << #labels >> 'Application') variable: 'application' object: application)
</methods> <methods> Core.Character <category>user interface</category>
inspectorExtraAttributes | integerAttr name symbolicStream nameAttr | integerAttr := Tools.Trippy.DerivedAttribute label: (#asInteger << #dialogs >> 'asInteger') value: self asInteger. name := self class constantNameFor: self. name notNil ifTrue: [symbolicStream := String new writeStream. symbolicStream store: self class; space; nextPutAll: name. nameAttr := Tools.Trippy.TextAttribute label: (#symbolic << #dialogs >> 'symbolic') text: symbolicStream contents. ^Array with: integerAttr with: nameAttr]. ^Array with: integerAttr
</methods> <methods> Core.Class class <category>user interface</category>
protectedInstVarNames ^self instVarNames
</methods> <methods> Core.Class <category>user interface</category>
inspectorCollaborators ^super inspectorCollaborators copyWith: (Tools.Trippy.Collaborator label: (#NewInstance << #dialogs >> 'New Instance') block: [self new])
</methods> <methods> Graphics.Wrapper <category>user interface</category>
componentHierarchyChildren ^Array with: component
</methods> <methods> Kernel.BlockClosure <category>user interface</category>
inspectorExtraAttributes ^self method inspectorExtraAttributes
</methods> <methods> Tools.Trippy.NullNavigator class <category>interface specs</category>
windowSpec "UIPainter new openOnClass: self andSelector: #windowSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels) #bounds: #(#{Graphics.Rectangle} 512 384 712 584 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.TabControlSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 1 0 1 ) #name: #inspector #model: #inspectorHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #requestValueChangeSelector: #changeRequest ) #labels: #() ) ) ) )
</methods> <methods> Tools.Trippy.InspectorHolder class <category>interface specs</category>
windowSpec "UIPainter new openOnClass: self andSelector: #windowSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels) #bounds: #(#{Graphics.Rectangle} 412 284 612 484 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SubCanvasSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 1 0 1 ) #name: #inspector #flags: 0 ) ) ) )
</methods> <methods> Tools.Trippy.Inspector class <category>resources</category>
baseObjectSubmenu "Tools.MenuEditor new openOnClass: self andSelector: #baseObjectSubmenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Refresh #defaultString: '&Refresh' #catalogID: #menus ) #value: #refresh #shortcutKeyCharacter: #F5 #shortcutModifiers: 0 ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Browse #defaultString: '&Browse' #catalogID: #menus ) #nameKey: #objectBrowse #value: #browseClass #shortcutKeyCharacter: $B #shortcutModifiers: 3 ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Inspect #defaultString: '&Inspect' #catalogID: #menus ) #nameKey: #objectSpawn #value: #spawn ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #InspectOwners #defaultString: 'Inspect &Owners' #catalogID: #menus ) #nameKey: #objectInspectOwners #value: #inspectOwners ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #InspectReferencePaths #defaultString: 'Inspect Reference &Paths' #catalogID: #menus ) #nameKey: #objectReferencePath #value: #inspectReferencePath ) ) #(1 4 ) nil ) decodeAsLiteralArray
</methods> <methods> Tools.Trippy.BehaviorInspector class <category>resources</category>
methodListMenu "MenuEditor new openOnClass: self andSelector: #methodListMenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #SendIt #defaultString: 'Sen&d It' #catalogID: #menus) #nameKey: #methodsSendIt #value: #sendIt #enablementSelector: #singleUnaryMethodIsSelected ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #SendAndDive #defaultString: 'Send and Di&ve' #catalogID: #menus) #nameKey: #methodsSendAndDive #value: #sendAndDive #enablementSelector: #singleUnaryMethodIsSelected ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Senders #defaultString: '&Senders' #catalogID: #menus) #nameKey: #senders ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Implementors #defaultString: '&Implementors' #catalogID: #menus) #nameKey: #implementors ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #LocalSe_nders #defaultString: 'Local Se&nders' #catalogID: #menus) #nameKey: #localSenders ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #LocalI_mplementors #defaultString: 'Local I&mplementors' #catalogID: #menus) #nameKey: #localImplementors ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ReferencedClasses #defaultString: 'Referenced &Classes' #catalogID: #menus) #nameKey: #referencedClasses ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Remove #defaultString: '&Remove' #catalogID: #menus) #value: #removeMethods #enablementSelector: #canRemoveMethods ) ) #(2 5 1 ) nil ) decodeAsLiteralArray
protocolListMenu "Tools.MenuEditor new openOnClass: self andSelector: #protocolListMenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_NewDot #defaultString: '&New...' #catalogID: #menus) #value: #addProtocol ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Re_nameAsDot #defaultString: 'Re&name As...' #catalogID: #menus) #value: #renameProtocol #enablementSelector: #canRenameProtocol ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Remove #defaultString: '&Remove' #catalogID: #menus) #value: #removeProtocol #enablementSelector: #canRemoveProtocol ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_FindMethod #defaultString: '&Find Method...' #catalogID: #menus) #nameKey: #findMethod #value: #findMethod ) ) #(1 2 1 ) nil ) decodeAsLiteralArray
</methods> <methods> Tools.Trippy.BehaviorInspector class <category>interface specs</category>
windowSpec "Tools.UIPainter new openOnClass: self andSelector: #windowSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels) #bounds: #(#{Graphics.Rectangle} 512 384 936 710 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SequenceViewSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.4 -20 0.4 ) #name: #protocolList #model: #protocolListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #requestValueChangeSelector: #updateRequest ) #menu: #protocolListMenu #multipleSelections: true #useModifierKeys: true #selectionType: #highlight ) #(#{UI.SequenceViewSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.4 0 0 0 1 0 0.4 ) #name: #methodList #model: #methodListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #selectorDoubleClicked #requestValueChangeSelector: #updateRequest ) #menu: #methodListMenu #multipleSelections: true #useModifierKeys: true #selectionType: #highlight ) #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0.4 0 1 0 1 ) #name: #text #model: #textHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #valueChangeSelector: #textAccepted: #requestValueChangeSelector: #textAcceptAllowed: ) #isReadOnly: false #tabRequiresControl: true ) #(#{UI.RadioButtonSpec} #layout: #(#{UI.AlignmentOrigin} 0 0 0 0.4 0 1 ) #model: #sideHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #requestValueChangeSelector: #updateRequest ) #label: #(#{Kernel.UserMessage} #key: #instance #defaultString: 'instance' #catalogID: #labels) #select: #instance ) #(#{UI.RadioButtonSpec} #layout: #(#{UI.AlignmentOrigin} 0 0.2 0 0.4 0 1 ) #model: #sideHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #requestValueChangeSelector: #updateRequest ) #label: #(#{Kernel.UserMessage} #key: #class #defaultString: 'class' #catalogID: #labels) #select: #class ) ) ) )
</methods> <methods> Tools.Trippy.OwnerNavigator class <category>interface specs</category>
windowSpec "UIPainter new openOnClass: self andSelector: #windowSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels) #bounds: #(#{Graphics.Rectangle} 412 284 706 525 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SequenceViewSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.25 0 1 ) #name: #fieldList #model: #fieldListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #fieldDoubleClicked ) #useModifierKeys: true #selectionType: #highlight ) #(#{UI.TabControlSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.25 0 0 0 1 0 1 ) #name: #inspector #model: #inspectorHolder #labels: #() ) ) ) )
</methods> <methods> Tools.Trippy.PartListAbstractInspector class <category>resources</category>
baseEditSubmenu "Tools.MenuEditor new openOnClass: self andSelector: #baseEditSubmenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Undo #defaultString: '&Undo' #catalogID: #menus ) #nameKey: #editUndo #value: #undo #shortcutKeyCharacter: $Z #shortcutModifiers: 2 ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Forget #defaultString: '&Forget' #catalogID: #menus ) #nameKey: #editFlushUndoHistory #value: #flushUndoHistory ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Select_All #defaultString: 'Select &All' #catalogID: #menus ) #nameKey: #editSelectAll #value: #selectAll #shortcutKeyCharacter: $A #shortcutModifiers: 2 #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #selectAll ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Copy #defaultString: '&Copy' #catalogID: #menus ) #nameKey: #editCopy #value: #copySelection #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #copy ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Paste #defaultString: '&Paste' #catalogID: #menus ) #nameKey: #editPaste #value: #paste #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #paste ) ) ) #(2 1 2 ) nil ) decodeAsLiteralArray
fieldListMenu "MenuEditor new openOnClass: self andSelector: #fieldListMenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Inspect #defaultString: '&Inspect' #catalogID: #menus) #nameKey: #spawn #value: #spawn ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Dive #defaultString: '&Dive' #catalogID: #menus) #nameKey: #dive #value: #dive ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Back #defaultString: '&Back' #catalogID: #menus) #nameKey: #back #value: #back #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #previous ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Copy #defaultString: '&Copy' #catalogID: #menus) #nameKey: #copy #value: #copySelection #enablementSelector: #canCopy #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #copy ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Paste #defaultString: '&Paste' #catalogID: #menus) #nameKey: #paste #value: #paste #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #paste ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Refresh #defaultString: '&Refresh' #catalogID: #menus) #nameKey: #refresh #value: #refresh ) ) #(3 2 1 ) nil ) decodeAsLiteralArray
</methods> <methods> Tools.Trippy.PartListAbstractInspector class <category>interface specs</category>
segmentedSpec "Tools.UIPainter new openOnClass: self andSelector: #segmentedSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels ) #bounds: #(#{Graphics.Rectangle} 720 450 1027 785 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SequenceViewSpec} #properties: #(#{UI.PropertyListDictionary} #dragOkSelector #wantToDrag: #dragEnterSelector #dragEntry: #dragOverSelector #dragOver: #dragStartSelector #doDrag: #dropSelector #drop: #dragExitSelector #dragExit: ) #layout: #(#{Graphics.LayoutFrame} 0 0 0 0.4 0 0.4 0 1 ) #name: #fieldList #flags: 15 #model: #fieldListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #dive #requestValueChangeSelector: #changeRequest ) #menu: #fieldListMenu #multipleSelections: true #useModifierKeys: true #selectionType: #normalSelection ) #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.4 0 0 0 1 0 1 ) #name: #text #model: #textHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #valueChangeSelector: #textAccepted: #requestValueChangeSelector: #textAcceptAllowed: ) #tabRequiresControl: true ) #(#{UI.SequenceViewSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.4 0 0.4 ) #name: #segmentList #flags: 15 #model: #segmentListHolder #multipleSelections: true #useModifierKeys: true #selectionType: #highlight ) ) ) )
unsegmentedSpec "Tools.UIPainter new openOnClass: self andSelector: #unsegmentedSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels ) #bounds: #(#{Graphics.Rectangle} 720 450 1027 785 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SequenceViewSpec} #properties: #(#{UI.PropertyListDictionary} #dragOkSelector #wantToDrag: #dragEnterSelector #dragEntry: #dropSelector #drop: #dragStartSelector #doDrag: #dragOverSelector #dragOver: #dragExitSelector #dragExit: ) #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.4 0 1 ) #name: #fieldList #flags: 15 #model: #fieldListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #dive #requestValueChangeSelector: #changeRequest ) #menu: #fieldListMenu #multipleSelections: true #useModifierKeys: true #selectionType: #normalSelection ) #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.4 0 0 0 1 0 1 ) #name: #text #model: #textHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #valueChangeSelector: #textAccepted: #requestValueChangeSelector: #textAcceptAllowed: ) #tabRequiresControl: true ) ) ) )
</methods> <methods> Tools.Trippy.BasicInspector <category>sorting</category>
sortTypeSubmenuItem <itemInMenu: #(#fieldList) position: 30.1> ^(MenuItem labeled: #fieldSortBy << #inspector >> 'Sort by:') submenu: [self sortTypeSubmenu]
</methods> <methods> Tools.Trippy.PreviewingInspector class <category>interface specs</category>
segmentedSpec "Tools.UIPainter new openOnClass: self andSelector: #segmentedSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels ) #bounds: #(#{Graphics.Rectangle} 720 450 1027 785 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SequenceViewSpec} #properties: #(#{UI.PropertyListDictionary} #dragOkSelector #wantToDrag: #dragEnterSelector #dragEntry: #dragOverSelector #dragOver: #dragStartSelector #doDrag: #dropSelector #drop: #dragExitSelector #dragExit: ) #layout: #(#{Graphics.LayoutFrame} 0 0 0 0.6 0 0.4 0 1 ) #name: #fieldList #flags: 15 #model: #fieldListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #dive #requestValueChangeSelector: #changeRequest ) #menu: #fieldListMenu #multipleSelections: true #useModifierKeys: true #selectionType: #normalSelection ) #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.4 0 0 0 1 0 1 ) #name: #text #model: #textHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #valueChangeSelector: #textAccepted: #requestValueChangeSelector: #textAcceptAllowed: ) #tabRequiresControl: true ) #(#{UI.SequenceViewSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0.4 0 0.4 0 0.6 ) #name: #segmentList #flags: 15 #model: #segmentListHolder #multipleSelections: true #useModifierKeys: true #selectionType: #highlight ) #(#{UI.ArbitraryComponentSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.4 0 0.4 ) #name: #preview #flags: 11 #component: #preview ) ) ) )
unsegmentedSpec "Tools.UIPainter new openOnClass: self andSelector: #unsegmentedSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels ) #bounds: #(#{Graphics.Rectangle} 720 450 1027 785 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SequenceViewSpec} #properties: #(#{UI.PropertyListDictionary} #dragOkSelector #wantToDrag: #dragEnterSelector #dragEntry: #dropSelector #drop: #dragStartSelector #doDrag: #dragOverSelector #dragOver: #dragExitSelector #dragExit: ) #layout: #(#{Graphics.LayoutFrame} 0 0 0 0.4 0 0.4 0 1 ) #name: #fieldList #flags: 15 #model: #fieldListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #dive #requestValueChangeSelector: #changeRequest ) #menu: #fieldListMenu #multipleSelections: true #useModifierKeys: true #selectionType: #normalSelection ) #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.4 0 0 0 1 0 1 ) #name: #text #model: #textHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #valueChangeSelector: #textAccepted: #requestValueChangeSelector: #textAcceptAllowed: ) #tabRequiresControl: true ) #(#{UI.ArbitraryComponentSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.4 0 0.4 ) #name: #preview #flags: 11 #component: #preview ) ) ) )
</methods> <methods> Tools.Trippy.DictionaryInspector class <category>interface specs</category>
segmentedSpec "Tools.UIPainter new openOnClass: self andSelector: #segmentedSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels ) #bounds: #(#{Graphics.Rectangle} 720 450 1027 785 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SequenceViewSpec} #properties: #(#{UI.PropertyListDictionary} #dragOkSelector #wantToDrag: #dragEnterSelector #dragEntry: #dragOverSelector #dragOver: #dragStartSelector #doDrag: #dropSelector #drop: #dragExitSelector #dragExit: ) #layout: #(#{Graphics.LayoutFrame} 0 0 0 0.4 0 0.4 0 1 ) #name: #fieldList #flags: 15 #model: #fieldListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #dive #requestValueChangeSelector: #changeRequest ) #menu: #fieldListMenu #multipleSelections: true #useModifierKeys: true #selectionType: #normalSelection ) #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.4 0 0 0 1 -20 1 ) #name: #text #model: #textHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #valueChangeSelector: #textAccepted: #requestValueChangeSelector: #textAcceptAllowed: ) #tabRequiresControl: true ) #(#{UI.SequenceViewSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.4 0 0.4 ) #name: #segmentList #flags: 15 #model: #segmentListHolder #multipleSelections: true #useModifierKeys: true #selectionType: #highlight ) #(#{UI.RadioButtonSpec} #layout: #(#{UI.AlignmentOrigin} 0 0.4 0 1 0 1 ) #model: #valueOrKeyHolder #label: #(#{Kernel.UserMessage} #key: #ValueAtKey #defaultString: 'Value at Key' #catalogID: #labels ) #select: #value ) #(#{UI.RadioButtonSpec} #layout: #(#{UI.AlignmentOrigin} 4 0.7 0 1 0 1 ) #model: #valueOrKeyHolder #label: #(#{Kernel.UserMessage} #key: #Key #defaultString: 'Key' #catalogID: #labels ) #select: #key ) ) ) )
unsegmentedSpec "Tools.UIPainter new openOnClass: self andSelector: #unsegmentedSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels ) #bounds: #(#{Graphics.Rectangle} 720 450 1027 785 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SequenceViewSpec} #properties: #(#{UI.PropertyListDictionary} #dragOkSelector #wantToDrag: #dragEnterSelector #dragEntry: #dragOverSelector #dragOver: #dragStartSelector #doDrag: #dropSelector #drop: #dragExitSelector #dragExit: ) #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.4 0 1 ) #name: #fieldList #flags: 15 #model: #fieldListHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #dive #requestValueChangeSelector: #changeRequest ) #menu: #fieldListMenu #multipleSelections: true #useModifierKeys: true #selectionType: #normalSelection ) #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.4 0 0 0 1 -20 1 ) #name: #text #model: #textHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #valueChangeSelector: #textAccepted: #requestValueChangeSelector: #textAcceptAllowed: ) #tabRequiresControl: true ) #(#{UI.RadioButtonSpec} #layout: #(#{UI.AlignmentOrigin} 0 0.4 0 1 0 1 ) #model: #valueOrKeyHolder #label: #(#{Kernel.UserMessage} #key: #ValueAtKey #defaultString: 'Value at Key' #catalogID: #labels ) #select: #value ) #(#{UI.RadioButtonSpec} #layout: #(#{UI.AlignmentOrigin} 4 0.7 0 1 0 1 ) #model: #valueOrKeyHolder #label: #(#{Kernel.UserMessage} #key: #Key #defaultString: 'Key' #catalogID: #labels ) #select: #key ) ) ) )
</methods> <methods> Tools.Trippy.TextEditorInspector class <category>interface specs</category>
windowSpec "UIPainter new openOnClass: self andSelector: #windowSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels) #bounds: #(#{Graphics.Rectangle} 512 384 712 584 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 1 0 1 ) #name: #text #model: #textHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #valueChangeSelector: #textAccepted: ) #tabRequiresControl: true ) ) ) )
</methods> <methods> Tools.Trippy.InspectorShell class <category>interface specs</category>
evaluatorSpec "UIPainter new openOnClass: self andSelector: #evaluatorSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels) #bounds: #(#{Graphics.Rectangle} 412 284 612 484 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.TextEditorSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 1 0 1 ) #name: #evaluator #model: #textHolder ) ) ) )
windowSpec "UIPainter new openOnClass: self andSelector: #windowSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #Inspector #defaultString: 'Inspector' #catalogID: #labels) #min: #(#{Core.Point} 190 162 ) #bounds: #(#{Graphics.Rectangle} 512 368 1012 768 ) #flags: 4 #menu: #menuBarHolder #toolBar: #toolbar ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.SubCanvasSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 1 -1 0.6 ) #name: #navigator #flags: 0 ) #(#{UI.ResizingSplitterSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 -1 0.6 0 1 2 0.6 ) #name: #splitter #horizontal: true #minAboveSize: 50 #minBelowSize: 25 #aboveWidgets: 'navigator' #belowWidgets: 'evaluatorPane' ) #(#{UI.SubCanvasSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 2 0.6 0 1 0 1 ) #name: #evaluatorPane #flags: 0 #minorKey: #evaluatorSpec ) ) ) )
</methods> <methods> Tools.Trippy.InspectorShell class <category>resources</category>
baseExploreMenu "MenuEditor new openOnClass: self andSelector: #baseExploreMenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Focus #defaultString: '&Focus' #catalogID: #menus) #nameKey: #exploreFocus #value: #exploreFocus #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #exploreOff ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Siblings #defaultString: '&Siblings' #catalogID: #menus) #nameKey: #exploreSiblings #value: #exploreSiblings #shortcutKeyCharacter: #Up #shortcutModifiers: 8 #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #exploreSiblings ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Parts #defaultString: '&Parts' #catalogID: #menus) #nameKey: #exploreParts #value: #exploreParts #shortcutKeyCharacter: #Down #shortcutModifiers: 8 #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #exploreParts ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Visited #defaultString: '&Visited' #catalogID: #menus) #nameKey: #exploreVisited #value: #exploreVisited #labelImage: #(#{UI.ResourceRetriever} #{Tools.ToolbarIconLibrary} #exploreVisited ) ) ) #(1 3 ) nil ) decodeAsLiteralArray
baseGoSubmenu "MenuEditor new openOnClass: self andSelector: #baseGoSubmenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Dive #defaultString: '&Dive' #catalogID: #menus) #nameKey: #goDive #value: #dive ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Back #defaultString: '&Back' #catalogID: #menus) #nameKey: #goBack #value: #back #shortcutKeyCharacter: #Left #shortcutModifiers: 8 #labelImage: #(#{UI.ResourceRetriever} #{Tools.Trippy.InspectorShell} #previous ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Forward #defaultString: '&Forward' #catalogID: #menus) #nameKey: #goForward #value: #forward #shortcutKeyCharacter: #Right #shortcutModifiers: 8 #labelImage: #(#{UI.ResourceRetriever} #{Tools.Trippy.InspectorShell} #next ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ToClass #defaultString: 'To &Class' #catalogID: #menus) #nameKey: #goDiveIntoClass #value: #diveIntoClass ) ) #(1 2 1 ) nil ) decodeAsLiteralArray
menuBar "Tools.MenuEditor new openOnClass: self andSelector: #menuBar" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Go #defaultString: '&Go' #catalogID: #menus ) #nameKey: #go ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_History #defaultString: '&History' #catalogID: #menus ) #nameKey: #history ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #E_xplore #defaultString: 'E&xplore' #catalogID: #menus ) #nameKey: #explore ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Tools #defaultString: '&Tools' #catalogID: #menus ) #nameKey: #window #submenu: #(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_CompareToClipboard #defaultString: '&Compare to Clipboard...' #catalogID: #menus ) #nameKey: #compareObjectToClipboard #value: #compareObjectToClipboard #enablementSelector: #clipboardNotEmpty #shortcutKeyCharacter: #F6 #shortcutModifiers: 0 ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_InspectClipboard #defaultString: '&Inspect Clipboard' #catalogID: #menus ) #nameKey: #inspectClipboard #value: #inspectClipboard #enablementSelector: #clipboardNotEmpty ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_EmptyClipboard #defaultString: '&Empty Clipboard' #catalogID: #menus ) #nameKey: #emptyClipboard #value: #emptyClipboard #enablementSelector: #clipboardNotEmpty ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Toolbar #defaultString: '&Toolbar' #catalogID: #menus ) #nameKey: #toggleToolbar #value: #toggleToolbar #indication: true ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Evaluation_Pane #defaultString: 'Evaluation &Pane' #catalogID: #menus ) #nameKey: #toggleEvaluationPane #value: #toggleEvaluationPane #shortcutKeyCharacter: #F2 #shortcutModifiers: 0 ) ) #(3 2 ) nil ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Help #defaultString: '&Help' #catalogID: #menus ) #nameKey: #help #submenu: #(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Inspector #defaultString: '&Inspector' #catalogID: #menus ) #value: #helpInspector #shortcutKeyCharacter: #F1 #shortcutModifiers: 0 #labelImage: #(#{UI.ResourceRetriever} #{ToolbarIconLibrary} #help ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Inspecting_Objects #defaultString: 'Inspecting &Objects' #catalogID: #menus ) #value: #helpInspectingObjects ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_AboutVisualWorksDot #defaultString: '&About VisualWorks...' #catalogID: #menus ) #value: #helpAbout ) ) #(2 1 ) nil ) ) ) #(5 ) nil ) decodeAsLiteralArray
toolbar "MenuEditor new openOnClass: self andSelector: #toolbar" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Back #defaultString: 'Back' #catalogID: #menus) #nameKey: #back #value: #back #labelImage: #(#{UI.ResourceRetriever} #{Tools.Trippy.InspectorShell} #previous ) #helpText: #(#{Kernel.UserMessage} #key: #Back #defaultString: 'Back' #catalogID: #menus) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Forward #defaultString: 'Forward' #catalogID: #menus) #nameKey: #forward #value: #forward #labelImage: #(#{UI.ResourceRetriever} #{Tools.Trippy.InspectorShell} #next ) #helpText: #(#{Kernel.UserMessage} #key: #Forward #defaultString: 'Forward' #catalogID: #menus) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Focus #defaultString: 'Focus' #catalogID: #menus) #nameKey: #focus #value: #exploreFocus #labelImage: #(#{UI.ResourceRetriever} #{Tools.Trippy.InspectorShell} #focus ) #helpText: #(#{Kernel.UserMessage} #key: #Focus #defaultString: 'Focus' #catalogID: #menus) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ExploreSiblings #defaultString: 'Explore Siblings' #catalogID: #menus) #nameKey: #exploreSiblings #value: #exploreSiblings #labelImage: #(#{UI.ResourceRetriever} #{Tools.Trippy.InspectorShell} #exploreSiblings ) #helpText: #(#{Kernel.UserMessage} #key: #ExploreSiblings #defaultString: 'Explore Siblings' #catalogID: #menus) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ExploreParts #defaultString: 'Explore Parts' #catalogID: #menus) #nameKey: #exploreParts #value: #exploreParts #labelImage: #(#{UI.ResourceRetriever} #{Tools.Trippy.InspectorShell} #exploreParts ) #helpText: #(#{Kernel.UserMessage} #key: #ExploreParts #defaultString: 'Explore Parts' #catalogID: #menus) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ExploreVisited #defaultString: 'Explore Visited' #catalogID: #menus) #nameKey: #exploreVisited #value: #exploreVisited #labelImage: #(#{UI.ResourceRetriever} #{Tools.Trippy.InspectorShell} #exploreVisited ) #helpText: #(#{Kernel.UserMessage} #key: #ExploreVisited #defaultString: 'Explore Visited' #catalogID: #menus) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #All #defaultString: 'All' #catalogID: #menus) #value: #selectAll #labelImage: #(#{UI.ResourceRetriever} #{ToolbarIconLibrary} #selectAll ) #helpText: #(#{Kernel.UserMessage} #key: #SelectAllFields #defaultString: 'Select All Fields' #catalogID: #menus) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #Eval #defaultString: 'Eval' #catalogID: #menus) #value: #toggleEvaluationPane #labelImage: #(#{UI.ResourceRetriever} #{ToolbarIconLibrary} #toggleEvalPane ) #helpText: #(#{Kernel.UserMessage} #key: #ToggleEvaluationPane #defaultString: 'Toggle Evaluation Pane' #catalogID: #menus) ) ) #(2 4 2 ) nil ) decodeAsLiteralArray
</methods> <methods> Tools.Trippy.HierarchyNavigator class <category>resources</category>
hierarchyMenu "MenuEditor new openOnClass: self andSelector: #hierarchyMenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ContractBranch #defaultString: '&Contract Branch' #catalogID: #menus) #value: #contractBranch ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ExpandBranch #defaultString: '&Expand Branch' #catalogID: #menus) #value: #expandBranch ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ContractAll #defaultString: '&Contract All' #catalogID: #menus) #value: #contractAll ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ExpandAll #defaultString: '&Expand All' #catalogID: #menus) #value: #expandAll ) ) #(2 2 ) nil ) decodeAsLiteralArray
</methods> <methods> Tools.Trippy.HierarchyNavigator class <category>interface specs</category>
windowSpec "UIPainter new openOnClass: self andSelector: #windowSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #UnlabeledCanvas #defaultString: 'Unlabeled Canvas' #catalogID: #labels) #bounds: #(#{Graphics.Rectangle} 359 217 666 552 ) ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.HierarchicalViewSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 1 0 0.35 ) #name: #hierarchyList #flags: 15 #model: #hierarchyHolder #callbacksSpec: #(#{UI.UIEventCallbackSubSpec} #doubleClickSelector: #hierarchyDoubleClicked ) #menu: #hierarchyMenu #useModifierKeys: true #selectionType: #highlight ) #(#{UI.TabControlSpec} #layout: #(#{Graphics.LayoutFrame} 0 0 0 0.35 0 1 0 1 ) #name: #inspector #model: #inspectorHolder #labels: #() ) ) ) )
</methods> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>Object</name> <environment>Core</environment> <super></super> <private>false</private> none <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>UISpecification</name> <environment>UI</environment> <super>Core.Object</super> <private>false</private> none properties <imports></imports> <category>UIBuilder-Specifications</category> <attributes> <package>UIBuilder-Specifications</package> </attributes> </class> <class> <name>SubCanvasSpec</name> <environment>UI</environment> <super>UI.NamedSpec</super> <private>false</private> none majorKey minorKey clientKey <imports></imports> <category>UIBuilder-Specifications</category> <attributes> <package>UIBuilder-Specifications</package> </attributes> </class> <class> <name>CompiledCode</name> <environment>Kernel</environment> <super>Core.Object</super> <private>false</private> objects bytes <imports> private Kernel.OpcodePool.* </imports> <category>Kernel-Methods</category> <attributes> <package>Kernel-Methods</package> </attributes> </class> <class> <name>OrderedCollection</name> <environment>Core</environment> <super>Core.SequenceableCollection</super> <private>false</private> objects firstIndex lastIndex <imports></imports> <category>Collections-Sequenceable</category> <attributes> <package>Collections-Sequenceable</package> </attributes> </class> <class> <name>Magnitude</name> <environment>Core</environment> <super>Core.Object</super> <private>false</private> none <imports></imports> <category>Magnitude-General</category> <attributes> <package>Magnitude-General</package> </attributes> </class> <class> <name>Character</name> <environment>Core</environment> <super>Core.Magnitude</super> <private>false</private> immediate <imports></imports> <category>Magnitude-General</category> <attributes> <package>Magnitude-General</package> </attributes> </class> <class> <name>VisualComponent</name> <environment>Graphics</environment> <super>Core.Object</super> <private>false</private> none <imports></imports> <category>Graphics-Visual Objects</category> <attributes> <package>Graphics-Visual Objects</package> </attributes> </class> <class> <name>VisualPart</name> <environment>Graphics</environment> <super>Graphics.VisualComponent</super> <private>false</private> none container eventHandlers properties <imports></imports> <category>Graphics-Visual Objects</category> <attributes> <package>Graphics-Visual Objects</package> </attributes> </class> <class> <name>View</name> <environment>UI</environment> <super>Graphics.DependentPart</super> <private>false</private> none controller <imports></imports> <category>Interface-Framework</category> <attributes> <package>Interface-Framework</package> </attributes> </class> <class> <name>Behavior</name> <environment>Core</environment> <super>Core.Object</super> <private>false</private> none superclass methodDict format subclasses <imports></imports> <category>Kernel-Classes</category> <attributes> <package>Kernel-Classes</package> </attributes> </class> <class> <name>ClassDescription</name> <environment>Core</environment> <super>Core.Behavior</super> <private>false</private> none instanceVariables organization <imports></imports> <category>Kernel-Classes</category> <attributes> <package>Kernel-Classes</package> </attributes> </class> <class> <name>Class</name> <environment>Core</environment> <super>Core.ClassDescription</super> <private>false</private> none name classPool environment <imports></imports> <category>Kernel-Classes</category> <attributes> <package>Kernel-Classes</package> </attributes> </class> <class> <name>Set</name> <environment>Core</environment> <super>Core.Collection</super> <private>false</private> objects tally <imports></imports> <category>Collections-Unordered</category> <attributes> <package>Collections-Unordered</package> </attributes> </class> <class> <name>Dictionary</name> <environment>Core</environment> <super>Core.Set</super> <private>false</private> objects <imports></imports> <category>Collections-Unordered</category> <attributes> <package>Collections-Unordered</package> </attributes> </class> <class> <name>Integer</name> <environment>Core</environment> <super>Core.Number</super> <private>false</private> none <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>Signal</name> <environment>Core</environment> <super>Core.Object</super> <private>false</private> none parent mayProceed notifierString nameClass nameMessage exceptionClass <imports></imports> <category>Kernel-Exception Handling</category> <attributes> <package>Kernel-Exception Handling</package> </attributes> </class> <class> <name>CompiledMethod</name> <environment>Kernel</environment> <super>Kernel.CompiledMainBlock</super> <private>false</private> objects mclass sourceCode <imports> private Kernel.OpcodePool.* </imports> <category>Kernel-Methods</category> <attributes> <package>Kernel-Methods</package> </attributes> </class> <class> <name>CompositePart</name> <environment>Graphics</environment> <super>Graphics.VisualPart</super> <private>false</private> none components preferredBounds <imports></imports> <category>Graphics-Visual Objects</category> <attributes> <package>Graphics-Visual Objects</package> </attributes> </class> <class> <name>ArrayedCollection</name> <environment>Core</environment> <super>Core.SequenceableCollection</super> <private>false</private> none <imports></imports> <category>Collections-Abstract</category> <attributes> <package>Collections-Abstract</package> </attributes> </class> <class> <name>CharacterArray</name> <environment>Core</environment> <super>Core.ArrayedCollection</super> <private>false</private> none <imports></imports> <category>Collections-Text</category> <attributes> <package>Collections-Text</package> </attributes> </class> <class> <name>Wrapper</name> <environment>Graphics</environment> <super>Graphics.VisualPart</super> <private>false</private> none component <imports></imports> <category>Graphics-Visual Objects</category> <attributes> <package>Graphics-Visual Objects</package> </attributes> </class> <class> <name>KeyedCollection</name> <environment>Core</environment> <super>Core.Collection</super> <private>false</private> none <imports></imports> <category>Collections-Abstract</category> <attributes> <package>Collections-Abstract</package> </attributes> </class> <class> <name>Context</name> <environment>Kernel</environment> <super>Kernel.InstructionStream</super> <private>false</private> none sender receiver stackp stack <imports> private Kernel.OpcodePool.* </imports> <category>Kernel-Methods</category> <attributes> <package>Kernel-Methods</package> </attributes> </class> <class> <name>BlockClosure</name> <environment>Kernel</environment> <super>Core.Object</super> <private>false</private> none method outerContext copiedValues <imports></imports> <category>Kernel-Methods</category> <attributes> <package>Kernel-Methods</package> </attributes> </class> <class> <name>ScheduledWindow</name> <environment>UI</environment> <super>Graphics.Window</super> <private>false</private> none label icon minimumSize maximumSize component lookPreferences paintPreferences edgeDecorationPolicy widgetPolicy controller model damageRepairPolicy masterWindow <imports></imports> <category>Interface-Framework</category> <attributes> <package>Interface-Framework</package> </attributes> </class> <class> <name>ApplicationWindow</name> <environment>UI</environment> <super>UI.ScheduledWindow</super> <private>false</private> none keyboardProcessor application sendWindowEvents receiveWindowEvents windowEventBlock activationNotification isEventDriven toolbarVisible dropTarget dragDropInProgress dragDropTracker <imports></imports> <category>UIBasics-Components</category> <attributes> <package>UIBasics-Components</package> </attributes> </class> <class> <name>Controller</name> <environment>UI</environment> <super>Core.Object</super> <private>false</private> none model view sensor <imports></imports> <category>Interface-Framework</category> <attributes> <package>Interface-Framework</package> </attributes> </class> <class> <name>Symbol</name> <environment>Core</environment> <super>Core.String</super> <private>false</private> none <imports></imports> <category>Collections-Text</category> <attributes> <package>Collections-Text</package> </attributes> </class> <class> <name>ObjectMemory</name> <environment>Kernel</environment> <super>Core.Object</super> <private>false</private> objects bytesPerOTE bytesPerOOP bytesPerRTE rtEntries rtUsedEntries edenBytes edenUsedBytes edenUsedBytesScavengeThreshold survBytes survUsedBytes survUsedBytesTenuringThreshold largeBytes largeUsedBytes largeFreeBytesTenuringThreshold largeUsedObjects bytesPerLTE threadedOTEntries threadedDataEntries threadedDataBytes allocFailures allocSplits allocMatches allocProbes incGCState incMarkedObjects incMarkedBytes incMarkedWeakObjects incMarkedWeakBytes incUnmarkedObjects incNilledObjects incNilledBytes incSweepAllocatedObjects incSweepAllocatedBytes incSweptObjects incReclaimedObjects incReclaimedBytes contiguousFreeOldBytes reservedContiguousFreeBytes availableFreeOldSpaceBytes availableFreeOldSpaceBytesLimit oldBytes oldOTEs oldDataBytes oldSegments numScavenges numIncGCs numGCs numDataCompactions stackBytes compCodeCacheBytes permBytes permOTEs permDataBytes oldRtEntries oldRtUsedEntries numGlobalGCs fixedSegments fixedBytes fixedUsedBytes fixedUsedObjects bytesPerFTE enumerationCallsPerMillisecond maximalFreeOldSpaceBytes dependents <imports></imports> <category>System-Support</category> <attributes> <package>System-Support</package> </attributes> </class> <class> <name>FullSpec</name> <environment>UI</environment> <super>UI.UISpecification</super> <private>false</private> none window component <imports></imports> <category>UIBuilder-Specifications</category> <attributes> <package>UIBuilder-Specifications</package> </attributes> </class> <class> <name>Fraction</name> <environment>Core</environment> <super>Core.Number</super> <private>false</private> none numerator denominator <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>ApplicationModel</name> <environment>UI</environment> <super>UI.Model</super> <private>false</private> none builder uiSession eventHandlers savedWindowInformation <imports></imports> <category>UIBuilder-Framework</category> <attributes> <package>UIBuilder-Framework</package> </attributes> </class> <class> <name>MethodDefinition</name> <environment>Tools</environment> <super>Tools.GeneralMethodDefinition</super> <private>false</private> none inheritingClass implementingClass selector extraText <imports></imports> <category>Tools-Programming</category> <attributes> <package>Tools-Programming</package> </attributes> </class> <class> <name>SpecCollection</name> <environment>UI</environment> <super>UI.UISpecification</super> <private>false</private> none collection <imports></imports> <category>UIBuilder-Specifications</category> <attributes> <package>UIBuilder-Specifications</package> </attributes> </class> <class> <name>GeneralNameSpace</name> <environment>Kernel</environment> <super>Core.KeyedCollection</super> <private>false</private> none organization bindings specificImports generalImports <imports></imports> <category>System-Name Spaces</category> <attributes> <package>System-Name Spaces</package> </attributes> </class>