UIPainterView.st
changeset 134 d5ab85ec27fd
parent 131 715b3dbba87d
child 137 335faeed1663
--- a/UIPainterView.st	Wed May 28 12:25:20 1997 +0200
+++ b/UIPainterView.st	Wed May 28 12:27:24 1997 +0200
@@ -403,7 +403,7 @@
     "delete the selection; copy the selection into the cut&paste-buffer
      and open a transaction
     "
-    |text specs coll|
+    |specs coll|
 
     coll := self minSetOfSuperViews:(self selection).
 
@@ -411,14 +411,11 @@
         listHolder disableNotificationsWhileEvaluating:[
             self select:nil.
             specs := coll collect:[:aView| self fullSpecFor:aView ].
-            text  := self transactionTextFor:coll.
 
-            undoHistory transaction:#cut text:text do:[
-                coll reverseDo:[:o||p|
-                    (p := self propertyOfView:o) notNil ifTrue:[
-                        self undoRemove:(p identifier)
-                    ].
-                    self remove:o
+            self withinTransaction:#cut objects:coll do:[
+                coll reverseDo:[:aView|
+                    self createUndoRemove:aView.
+                    self remove:aView
                 ]
             ].
             self setSelection:specs.
@@ -481,9 +478,11 @@
         ].
     ].
 
-    self transaction:#paste objects:newSel do:[:v|
-        self undoCreate:((self propertyOfView:v) identifier)
+    self withinTransaction:#paste objects:newSel do:[
+        undoHistory addUndoSelector:#undoCreate:
+                           withArgs:(newSel collect:[:v|(self propertyOfView:v) identifier])
     ].
+
     newSel size == 1 ifTrue:[
         newSel := newSel at:1
     ].
@@ -539,6 +538,10 @@
 !
 
 generateAspectMethodFor:aspect spec:protoSpec inClass:targetClass
+    |modelClass|
+
+    modelClass := protoSpec defaultModelClass.
+
     ^ ('!!' , targetClass name , ' methodsFor:''aspects''!!\\' ,
       aspect , '\' ,
       '    "automatically generated by UIPainter ..."\' ,
@@ -546,7 +549,7 @@
       '    |holder|\' ,
       '\' ,
       '    (holder := builder bindingAt:#' , aspect , ') isNil ifTrue:[\' ,
-      '        builder aspectAt:#' , aspect , ' put:(holder := ' , ' ValueHolder new' , ').\' ,
+      '        builder aspectAt:#' , aspect , ' put:(holder := ' , ' ' , modelClass name , ' new' , ').\' ,
       '    ].\' ,
       '    ^ holder\' ,
       '!! !!\\') withCRs
@@ -566,9 +569,13 @@
     listHolder propertiesDo:[:aProp |
         |modelSelector menuSelector protoSpec thisCode|
 
+        protoSpec := aProp spec.
+        protoSpec isNil ifTrue:[
+            self halt.
+            protoSpec := aProp view specClass basicNew.
+        ].
         (modelSelector := aProp model) notNil ifTrue:[
             (cls implements:modelSelector asSymbol) ifFalse:[
-                protoSpec := aProp view specClass basicNew.
                 "/ kludge ..
                 (protoSpec isMemberOf:ActionButtonSpec) ifTrue:[
                     thisCode := (self generateActionMethodFor:modelSelector spec:protoSpec inClass:cls).
@@ -581,7 +588,6 @@
 
         (menuSelector := aProp menu) notNil ifTrue:[
             (cls implements:menuSelector asSymbol) ifFalse:[
-                protoSpec := aProp view specClass basicNew.
                 "/ kludge ..
                 thisCode := (self generateAspectMethodFor:menuSelector spec:protoSpec inClass:cls).
                 code := code , thisCode
@@ -590,7 +596,6 @@
 
         aProp spec aspectSelectors do:[:aSel|
             (cls implements:aSel asSymbol) ifFalse:[
-                protoSpec := aProp view specClass basicNew.
                 "/ kludge ..
                 thisCode := (self generateAspectMethodFor:aSel spec:protoSpec inClass:cls).
                 code := code , thisCode
@@ -624,6 +629,8 @@
 
     |code|
 
+    self resetModification.
+
     code := ''.
 
 "/    (Smalltalk classNamed:className asSymbol) isNil ifTrue:[
@@ -995,8 +1002,8 @@
         spec label:(props name)
     ].
 
-    undoHistory transaction:#create text:(props name) do:[
-        self undoCreate:(props identifier).
+    undoHistory withinTransaction:#create text:(props name) do:[
+        undoHistory addUndoSelector:#undoCreate: withArgs:(props identifier)
     ].
 !
 
@@ -1049,7 +1056,7 @@
         menu disableAll
     ].
     menu enabledAt:#paste put:canPaste.
-    menu enabledAt:#undo  put:(undoHistory notEmpty).
+    menu enabledAt:#undo  put:(undoHistory isEmpty not).
     menu startUp.
   ^ nil
 
@@ -1106,7 +1113,9 @@
 remove:anObject
     "remove anObject from the contents do redraw
     "
-    listHolder remove:anObject.
+    anObject notNil ifTrue:[
+        listHolder remove:anObject
+    ]
 !
 
 removeAll
@@ -1114,8 +1123,8 @@
     "
     listHolder disableNotificationsWhileEvaluating:[
         self select:nil.
-        listHolder  removeAll.
-        undoHistory reinitialize.
+        listHolder removeAll.
+        self removeUndoHistory.
     ]
 ! !
 
@@ -1390,7 +1399,7 @@
                     ]
                 ].
                 aSpec name:name.
-                self undoSpecModify:(props identifier).
+                self createUndoSpecModify:props.
 
                 aSpec needsRebuildForAttributes ifTrue:[
                     v := aSpec buildViewWithLayoutFor:builder in:aView superView.
@@ -1474,143 +1483,154 @@
     "opens a transaction and evaluates a block within the transaction; the
      argument to the block is a view from derived from something
     "
-    |text|
-
-    something notNil ifTrue:[
-        text := self transactionTextFor:something.
-
-        undoHistory transaction:aType text:text do:[
-            something isCollection ifTrue:[
-                something do:[:aView| aOneArgBlock value:aView ]
-            ] ifFalse:[
-                aOneArgBlock value:something
-            ]
-        ]
+    self withinTransaction:aType objects:something do:[
+        self forEach:something do:aOneArgBlock
     ]
 !
 
-transactionTextFor:anElementOrCollection
-    "returns text used by transaction or nil
+withinTransaction:aType objects:objects do:aNoneArgBlock
+    "evaluate a block with no arguments within a transaction
     "
-    |props size|
+    |text size prop|
+
+    objects isNil ifTrue:[ ^ self ].
+
+    size := objects size.
 
-    anElementOrCollection notNil ifTrue:[
-        anElementOrCollection isCollection ifTrue:[
-            size := anElementOrCollection size.
-            size == 0 ifTrue:[^ nil].
-            size ~~ 1 ifTrue:[^ size printString, ' elements'].
+    objects isCollection ifTrue:[
+        size == 0 ifTrue:[ ^ self ].
+        size == 1 ifTrue:[ prop := self propertyOfView:(objects first) ]
+    ] ifFalse:[
+        prop := self propertyOfView:objects
+    ].
 
-            props := self propertyOfView:(anElementOrCollection at:1).
-        ] ifFalse:[
-            props := self propertyOfView:anElementOrCollection
-        ].
-        props notNil ifTrue:[ ^ props name ]
+    prop notNil ifTrue:[
+        text := prop name
+    ] ifFalse:[
+        text := size printString, ' elements'
     ].
-    ^ nil
+
+    undoHistory withinTransaction:aType text:text do:[
+        aNoneArgBlock value
+    ]
 ! !
 
 !UIPainterView methodsFor:'undo actions'!
 
-undoCreate:aViewId
-    "undo method when creating or pasting an object
-    "
-    undoHistory addUndoBlock:[
-        self remove:(self findViewWithId:aViewId)
-    ]
-
-!
-
-undoLayout:aViewId
-    "undo method when changing the layout (position or dimension)
+createUndoLayout:aView
+    "create undo action before changing a views layout
     "
-    |view layout extent|
-
-    (view := self findViewWithId:aViewId) notNil ifTrue:[
-        (layout := view geometryLayout copy) isNil ifTrue:[
-            extent := view extent copy
-        ].
-        undoHistory addUndoBlock:[
-            (view := self findViewWithId:aViewId) notNil ifTrue:[
-                layout notNil ifTrue:[view geometryLayout:layout]
-                             ifFalse:[view extent:extent]
-            ]
-        ]
-    ].
-    view := nil
-!
-
-undoLayoutView:aView
-    "undo method for changing layout on a view
-    "
-    |prop|
+    |lyt args prop|
 
     undoHistory isTransactionOpen ifTrue:[
         prop := self propertyOfView:aView.
+
         prop notNil ifTrue:[
-            self undoLayout:(prop identifier)
+            args := Array new:3.
+            args at:1 put:(prop identifier).
+
+            (lyt := aView geometryLayout) notNil ifTrue:[
+                args at:2 put:#geometryLayout:
+            ] ifFalse:[
+                lyt extent.
+                args at:2 put:#extent:
+            ].
+            args at:3 put:(lyt copy).
+            undoHistory addUndoSelector:#undoLayout: withArgs:args.
         ]
     ]
 !
 
-undoRemove:aViewId
-    "undo method when removing an object
+createUndoRemove:aView
+    "create undo method before deleting views
     "
-    |frame prop spec parentId|
+    |frame prop pId spec|
+
+    (prop := self propertyOfView:aView) notNil ifTrue:[
+        spec  := self fullSpecFor:aView.
+        frame := aView superView.
 
-    frame := self findViewWithId:aViewId.
-    spec  := self fullSpecFor:frame.
-    frame := frame superView.
+        (self canPasteInto:frame) ifTrue:[
+            (frame := self propertyOfView:frame) notNil ifTrue:[
+                pId := frame identifier
+            ]
+        ].
+        undoHistory addUndoSelector:#undoRemove:
+                           withArgs:(Array with:spec with:(prop identifier) with:pId)
+    ]
+!
 
-    (self canPasteInto:frame) ifTrue:[
-        (prop := self propertyOfView:frame) notNil ifTrue:[
-            parentId := prop identifier
-        ]
-    ].
-    frame := nil.
-    prop  := nil.
+createUndoSpecModify:aProp
+    "undo method when changing the specification for an object
+    "
+    aProp notNil ifTrue:[
+        undoHistory addUndoSelector:#undoSpecModify:
+                           withArgs:(Array with:(aProp spec) with:(aProp identifier))
+    ]
+!
 
-    undoHistory addUndoBlock:[
-        |view|
+undoCreate:something
+    "undo method for creating or pasting an object
+    "
+    self forEach:something do:[:anId|self remove:(self findViewWithId:anId)].
+!
 
-        frame := self findViewWithId:parentId.
-        frame isNil ifTrue:[
-            frame := self
-        ].
-        view := self addSpec:spec builder:(UIBuilder new) in:frame.
-        view realize.
-        inputView raise.
+undoLayout:args
+    "undo method to set the old layout; see 'createUndoLayout:'
+    "
+    |view|
+
+    (view := self findViewWithId:(args at:1)) notNil ifTrue:[
+        view perform:(args at:2) with:(args at:3)
     ]
 !
 
-undoSpecModify:aViewId
-    "undo method when changing the specification for an object
+undoRemove:args
+    "undo method when removing an object; see 'createUndoRemove:'
+    "
+    |frame prop view|
+
+    (args at:3) notNil ifTrue:[
+        frame := self findViewWithId:(args at:3).
+    ].
+    frame isNil ifTrue:[
+        frame := self
+    ].
+    view := self addSpec:(args at:1) builder:(UIBuilder new) in:frame.
+    view realize.
+    inputView raise.
+
+    prop := self propertyOfView:view.
+    prop identifier:(args at:2).
+
+!
+
+undoSpecModify:args
+    "undo method when changing a spec; see 'createUndoSpecModify:'
     "
     |builder view spec v props|
 
-    (view := self findViewWithId:aViewId) notNil ifTrue:[
-        spec := self specFor:view.
-        view := nil.
+    props := self propertyOfIdentifier:(args at:2).
 
-        undoHistory addUndoBlock:[
-            props := self propertyOfIdentifier:aViewId.
-            props notNil ifTrue:[
-                view    := props view.
-                builder := UIBuilder new.
-                props spec:spec.
+    props notNil ifTrue:[
+        view    := props view.
+        spec    := args at:1.
+        builder := UIBuilder new.
+        props spec:spec.
 
-                spec needsRebuildForAttributes ifTrue:[
-                    v := spec buildViewWithLayoutFor:builder in:view superView.
-                    v realize.    
-                    view destroy.
-                    view become:v
-                ] ifFalse:[
-                    spec setAttributesIn:view with:builder.
-                    self elementChangedSize:view.
-                ].
-                listHolder propertyChanged:props.
-            ]
-        ]
-    ].
+        spec needsRebuildForAttributes ifTrue:[
+            v := spec buildViewWithLayoutFor:builder in:view superView.
+            v realize.    
+            view destroy.
+            view become:v
+        ] ifFalse:[
+            spec setAttributesIn:view with:builder.
+            self elementChangedSize:view.
+        ].
+        listHolder propertyChanged:props.
+    ] ifFalse:[
+        self halt
+    ]
 
 
 
@@ -1643,6 +1663,13 @@
     ^ identifier
 !
 
+identifier:anIdentifier
+    "set the unique identifier assigned to property; called after an restore of
+     a deleted instance
+    "
+    identifier := anIdentifier
+!
+
 spec
     "return the value of the instance variable 'spec' (automatically generated)"