<@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