@doc alias="usg" hierarchy="GMLDOM">
An element used for referencing a model unit.
(c) SAP AG 2003. All rights reserved.
#INCLUDE[svg:defs.inc]
#INCLUDE[defs.inc]
///////////////////////////////////////////////////////////////////////
// CLASS HEADER
// Notice: Usage is a special object that implements IInfosetEnumerator and that
// inherits Configurable that implements IInfoset.(mhoter)
Class Usage inherit BaseUsage;
implement dev:IInfosetEnumerator;
metadata title = '#TEXT[XTIT_USAGE]';
metadata descr = '#TEXT[XTOL_USAGE]';
metadata configurationType = null;
attach svg:Bipolar override {
geometry: {
resizeMode: #[SVG_KEEP_WIDTH],
rotateMode: #[SVG_ROTATE_FULL|SVG_FLIP_VBODY],
defWidth: 110,
defHeight: 80,
minWidth: 80,
minHeight: 60,
poleStart: 20,
poleEnd: 20,
padding: [0,10,0,10]
},
frameParts: [
{type:'rect', x:'@x1', y:'@y1', width:'@w', height:'@h', fill:'@fillColor', stroke:'currentColor', 'stroke-width':2}
],
bodyParts: [
{type:'text', action:'rename', text:'@name', x:0, y:-18, 'font-size':'90%', fill:'@textColor', stroke:'none', 'text-anchor':'middle'}
]
}
///////////////////////////////////////////////////////////////////////
// PROPERTIES
<@doc>Gets the Id of the target unit referenced by this element
readonly property target = '';
//readonly property isReusable = false;
property isPrimary = true;
///////////////////////////////////////////////////////////////////////
// METHODS
override method onInsertMe(parent, trans)
this.supercall();
$ENV.organizer.addUsage(this, this.unit);
this.setPrimaryUsage();
end
override method onRemoveMe(parent, trans)
this.supercall();
$ENV.organizer.delUsage(this, this.unit);
end
<@doc>
Gets the target unit referenced by this element
The target unit
method getTarget()
return $ENV.getUnit(this.target);
end
override method onCreate()
if (!this.name) {
var trg=this.getTarget();
if (trg) this.name = trg.name;
}
this.supercall();
end
override method onLoad()
this.setPrimaryUsage();
this.supercall();
end
<@doc>
Tests whether the usage is a reusable usage
Return ~true iff the usage is a reusable usage.
method isReusable()
//this.isReusable = $ENV.organizer.isReusable(this.target);
return $ENV.organizer.isReusable(this.target);
end
<@doc>
overrides the GmlObject!onClone method
A reusable usage should be cloned as a copy, which means that its target is also cloned.
This method should not be called directly as it does not handle all aspects of the clone operation as fixing
references, initialization of the cloned objects and after clone ooperations needed to complete this action.
Instead, to clone an object you should either call Model's @gml:Model!cloneElements method or ObjectSet->ObjectSet!clone method.
This parameter is an [OUT] parameter and passed byref: Map of the newly created objects used to fix object references.
This map should be populated with newly created objects for any depth of children created indirectly by this clone operation.
The ID used for this map should be of the old object from which the new one was cloned
Parent object of the newly cloned object
The newly cloned usage
/*
onClone:
if( #[FORCE_LINK])
primaryUsage && !isReusable : convert the current usage to reusable usage.
primaryUsage && isReusable : copy the current usage to the target location and asign copy.isPrimary=false
not primaryUsage(already a link) : disabled.
if(#[FORCE_COPY])
primaryUsage : make a copy of the primaryUsage and the target unit.
not PrimaryUsage : copy only the usage.
if(#[FORCE_FLAT])
copy just the usage.
*/
override method onClone(elementsMap, parent, force)
var isReusable=this.isReusable();
// make the clone;
var copy = this.supercall(elementsMap, parent);
// force flat copy;
if( force & #[FORCE_FLAT] ){
return copy;
}
if( force & #[FORCE_LINK] ){
if (!isReusable && this.isPrimary ){
this.makeReusable();
isReusable = true;
copy.setProperty('isPrimary',false);
}else if(isReusable && this.isPrimary ){
copy.setProperty('isPrimary',false);
}
return copy;
}
if( force & #[FORCE_COPY] ){
if (this.isPrimary){
fixReference(copy)
}
return copy;
}
// This is the default beaviour if not reusable then also copy the target unit.
if (!isReusable) {
return fixReference(copy);
}
return copy;
// fix the reference of the target usage.
function fixReference(copy) {
try {
var targetId = copy.target;
var target = $ENV.model.getUnit(targetId);
if (!target) throw new Error(-1, '#TEXT[XMSG_CLONE_FAILED] '+copy.Class.fullname+' usage');
var mapping ={};
// clone the the target unit of the source usage.
var copiedTarget = target.clone(mapping);
// update the target property, because the target property is of type
// string and therfore will not be fixed in the onFixCrossReference method.
copy.target = copiedTarget.id;
// fix Usage references
copy.onFixCrossUnitRef(mapping, copy.id);
return copy;
} catch(e) {
WRITE(e.description);
return null;
}
}
end
<@doc>
Tests whether the usage is in the parent unit of it's target unit.
return ~true iff the usage is a main usage
method isPrimaryUsage()
// return this.isPrimary;
return $ENV.organizer.isPrimaryUsage(this);
end
<@doc>
Sets primary usage property
return value of setProperty method
method setPrimaryUsage()
return this.isPrimary = $ENV.organizer.isPrimaryUsage(this);
end
<@doc scope="private">
Makes a usage to be reusable
method makeReusable()
if (this.isReusable()) return;
var target = this.getTarget();
$ENV.organizer.makeUnitReusable(target);
this.setProperty('isPrimary', false);
end
<@doc>
Check if the object or its children have translation implications - currently this means if it has links to Gml:Text objects
~true if it does have translation implications, ~false otherwise
override method hasTranslation(deep)
if (this.supercall(deep)) return(true); // check the objecy and all its strong proprties ... but the target unit is not a strong property...
//check child Unit
//this is done becuase child unit is not a strong property and not covered by the original method in TransObject
//but we check child units only if deep==true
if (deep) {
var unit = this.getTarget();
return(unit && unit.hasTranslation(deep));
}
return(false); //nothing found
end
<@doc>
Tell if the object or it's expected children can have properties that can be translated.
~true if strings are possible, ~false otherwise
override method canBeTranslated()
return(true); // false by default;
end
/////////////////////////////////////
// IINFOSETENUMERATOR METHODS - prototype implementation
<@doc>
Gets a flat list of infosets
Indicates whether to perform a deep search
Collection of @dev:IInfoset! elements
override method getInfosetList(deep)
// Plugs of a usage are implemented as IInfosets:
return this.getPlugs();
end
<@doc>
Gets a tree of infosets.
Tree provider of the infosets
override method getInfosetTree()
// TO BE IMPLEMENTED
return null;
end
///////////////////////////////////////////////////////////////////////
// EVENT LISTENERS
listen onShapeMenu for core.gml:Usage
menu.insert({button:'SEARCH_DOWNWARD'});
if(GETVAR('ReusableMode'))
menu.append({button:'MAKE_REUSABLE'});
end
listen onDrawingAction for core.gml:Usage
if (detail & #[SVG_ACTIVATE]) {
try
{
$ENV.context = object.target;
}
catch (e) {} // might happen for units that cannot be drilled into
}
end