diff -r e12f82d3afb7 -r d5ab85ec27fd UIPainterView.st --- 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)"