// $Id: userattr.cpp 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ /* */ #include "camtypes.h" //#include "attrval.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "nodeattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "userattr.h" //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "blendatt.h" //#include "camfiltr.h" // Record handling classes for attributes - in camtypes.h [AUTOMATICALLY REMOVED] #include "rechattr.h" //#include "cxfrec.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "cxftags.h" //#include "cxfdefs.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "mario.h" // for _R(IDE_NOMORE_MEMORY) //#include "hotlink.h" // for _R(IDS_USERATTRIBUTE_ID) //#include "tmpltres.h" // for _R(IDS_CUSTOM) #include "gadget.h" // for the UI side #include "uielem.h" #include "visiattr.h" //#include "dialogop.h" // for slight bodge //#include "tmpltdlg.h" DECLARE_SOURCE("$Revision: 1282 $"); CC_IMPLEMENT_DYNCREATE(AttrUser, NodeAttribute) CC_IMPLEMENT_MEMDUMP(VisibleAttribute, UserInterface) CC_IMPLEMENT_MEMDUMP(VisibleUserAttribute, VisibleAttribute) // Give this file in memory dumps // Declare smart memory handling in Debug builds #define new CAM_DEBUG_NEW #undef ENSURE_NOT_NULL #define ENSURE_NOT_NULL(Pointer) ERROR2IF(Pointer == NULL, 0, "NULL Args") #define ENSURE_KIND(pInstance, Class) ERROR3IF(!pInstance->IS_KIND_OF(Class), #pInstance" is not kind of "#Class); /****************************************************************************************** FUNCTIONS FOR THE UserATTRIBUTE CLASS (Graham 18/8/96) **********************************************************************************************/ UserAttribute::UserAttribute() : m_pStyle(0) { // To ensure default constructed UserAttributes can be copied, alloc the strings. if (!Key.Alloc(0) || !LongKey.Alloc(0) || !Value.Alloc(0)) return; } /******************************************************************************************** > UserAttribute& UserAttribute::operator=(const UserAttribute& other) Author: Justin_Flude (Xara Group Ltd) Created: 26/9/99 Purpose: Assignment operator for UserAttributes. Errors: _R(IDE_NOMORE_MEMORY) Notes: *DOESN'T* COPY THE m_pStyle MEMBER! What the hell is that doing in this class, anyway?? SeeAlso: UserAttribute::SimpleCopy; AttrUser::CopyNodeContents ********************************************************************************************/ UserAttribute& UserAttribute::operator=(const UserAttribute& other) { if (Key.Alloc(other.Key.Length()) && LongKey.Alloc(other.LongKey.Length()) && Value.Alloc(other.Value.Length())) { Key = other.Key; LongKey = other.LongKey; Value = other.Value; } return *this; } /******************************************************************************************** > static BOOL UserAttribute::Init() Author: Graham_Walmsley (Xara Group Ltd) Created: 14/8/96 Returns: TRUE - initialised ok; FALSE if not. Purpose: There's no need for this function at the moment but I'll leave it in in case someone needs it in the future. This function usually registers Default Attributes (see commented out code below). There's never a need to register a Default User Attribute. Errors: None SeeAlso: AttributeManager ********************************************************************************************/ BOOL UserAttribute::Init() { UserAttribute *pAttr = new UserAttribute; if (pAttr == NULL) return FALSE; UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), pAttr); if (ID == ATTR_BAD_ID) return FALSE; ENSURE(ID == ATTR_USERATTRIBUTE, "Incorrect ID for attribute!"); return TRUE; } /******************************************************************************************** > void UserAttribute::Render(RenderRegion *pRegion) Author: Graham_Walmsley (Xara Group Ltd) Created: 14/8/96 Inputs: pRegion - the render region to render this attribute into. Purpose: Rendering a User Attribute does nothing. That's what this function does. SeeAlso: UserAttribute; RenderStack; AttributeValue; NodeAttribute; ValueAttribute::Restore; ValueAttribute::SimpleCopy; AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy ********************************************************************************************/ void UserAttribute::Render(RenderRegion *pRegion, BOOL Temp) { //Do nothing } /******************************************************************************************** > void UserAttribute::Restore(RenderRegion *pRegion, BOOL Temp) Author: Tim_Browse (Xara Group Ltd) Created: 03/02/94 Inputs: pRegion - the render region to restore the attribute into. Temp - TRUE if this is a temporary attribute, FALSE if it is permanent (e.g. it's in a document tree). Purpose: Again, restoring a User Attribute does nothing SeeAlso: UserAttribute; RenderStack; AttributeValue; NodeAttribute; ValueAttribute::Render; ValueAttribute::SimpleCopy; AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy ********************************************************************************************/ void UserAttribute::Restore(RenderRegion *pRegion, BOOL Temp) { // Do nothing } /******************************************************************************************** > void UserAttribute::SimpleCopy(AttributeValue* pValue) Author: Graham_Walmsley (Xara Group Ltd) Created: 16/8/96 Inputs: pValue - pointer to the AttributeValue to copy. Purpose: Copies both bits of the data from pValue SeeAlso: ValueAttribute; RenderStack; AttributeValue; NodeAttribute; ValueAttribute::Render; ValueAttribute::Restore; AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy ********************************************************************************************/ void UserAttribute::SimpleCopy(AttributeValue* pValue) { *this = *((UserAttribute*) pValue); } /******************************************************************************************** > NodeAttribute *UserAttribute::MakeNode() Author: Tim_Browse (Xara Group Ltd) Created: 11/04/94 Returns: Pointer to the new node, or NULL if out of memory. Purpose: Make a AttrUser node from this line width attribute. Errors: Out of memory SeeAlso: AttributeValue::MakeNode ********************************************************************************************/ NodeAttribute *UserAttribute::MakeNode() { // Create new attribute node AttrUser *pAttr = new AttrUser(); // Copy attribute value into the new node. pAttr->Value.SimpleCopy(this); // Return the new node return pAttr; } /******************************************************************************************** > BOOL UserAttribute::IsDifferent(AttributeUser *pAttr) Author: Graham_Walmsley (Xara Group Ltd) from Tim Created: 12/04/94 Purpose: See base class version. Errors: The two attributes are not of the same type. SeeAlso: AttributeValue::IsDifferent ********************************************************************************************/ BOOL UserAttribute::IsDifferent(AttributeValue *pAttr) { ENSURE_NOT_NULL(pAttr); ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), "Different attribute types in AttributeValue::IsDifferent()"); ENSURE_KIND(pAttr, UserAttribute); UserAttribute* const pUserAttrVal = (UserAttribute*)pAttr; // LongKey should always start with Key return pUserAttrVal->LongKey != LongKey || pUserAttrVal->Value != Value; } /******************************************************************************************** > BOOL UserAttribute::Blend(BlendAttrParam *pBlendParam) Author: Graham_Walmsley (Xara Group Ltd) from Markn Created: 15/8/96 Inputs: pBlendParam = ptr to param holding all data needed for the attr val to blend Outputs: if TRUE returned, pBlendParam->GetBlendedAttrVal() will get ptr to the blended attr val if FALSE returned, pBlendParam->GetBlendedAttrVal() will return NULL Returns: TRUE if successful, FALSE otherwaie Purpose: Blends this attr val with the attr val held in pBlendParam SeeAlso: - ********************************************************************************************/ BOOL UserAttribute::Blend(BlendAttrParam *pBlendParam) { // Check entry param ERROR3IF(pBlendParam == NULL,"NULL entry param"); if (pBlendParam == NULL) return FALSE; // Check that the pointer to the other User attr val is not NULL, and is a UserAttribute UserAttribute* pOtherUserAttr = (UserAttribute*) pBlendParam->GetOtherAttrVal(); ERROR3IF(pOtherUserAttr == NULL,"NULL other attr val"); ERROR3IF(!IS_A(pOtherUserAttr, UserAttribute),"other attr val not a user attr"); if (pOtherUserAttr == NULL || !IS_A(pOtherUserAttr, UserAttribute)) return FALSE; //Graham: Here's the change. If the Keys of the attributes are not the same, we must //not blend these attributes. if (Key != pOtherUserAttr->Key && LongKey != pOtherUserAttr->LongKey) { return FALSE; } // Get a new UserAttribute to hold the blended version, (return FALSE if this fails) UserAttribute* pBlendedUserAttr = new UserAttribute; if (pBlendedUserAttr == NULL) return FALSE; //Graham: For blending two User Attributes with the same Key, we simply //use the first User Attribute for the first half of the blend, and the //second User Attribute for the second half of the blend. StringBase* pStr; if (pBlendParam->GetBlendRatio() < 0.5) pStr = &Value; else pStr = &(pOtherUserAttr->Value); ERRORIF(!pBlendedUserAttr->Value.Alloc(pStr->Length()), _R(IDE_NOMORE_MEMORY), FALSE); pBlendedUserAttr->Value = *pStr; // Store the ptr to the new blended User width attr val pBlendParam->SetBlendedAttrVal(pBlendedUserAttr); return TRUE; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // // A T T R U S E R // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // const TCHAR AttrUser::s_KeyDelimiter = TEXT('\\'); const TCHAR s_KeyDelimiter = TEXT('\\'); /******************************************************************************************** > AttrUser::AttrUser (Node* ContextNode, AttachNodeDirection Direction, BOOL Locked, BOOL Mangled, BOOL Marked, BOOL Selected ): NodeAttribute(ContextNode, Direction, Locked, Mangled, Marked, Selected, TRUE) Author: Graham_Walmsley (Xara Group Ltd) (from Will) Created: 14/8/96 Inputs: - Outputs: - Returns: - Purpose: Creates a User Attribute Errors: - SeeAlso: - ********************************************************************************************/ AttrUser::AttrUser(Node* ContextNode, AttachNodeDirection Direction, BOOL Locked, BOOL Mangled, BOOL Marked, BOOL Selected) : NodeAttribute(ContextNode, Direction, Locked, Mangled, Marked, Selected) { // Empty. } /******************************************************************************************** > AttrUser::AttrUser() Author: Graham_Walmsley (Xara Group Ltd) Created: 21/8/96 Purpose: Default constructor for User Attribute class ********************************************************************************************/ AttrUser::AttrUser() { } /******************************************************************************************** > AttrUser::AttrUser( const StringBase& NewKey, const StringBase& NewSubKey, const StringBase& NewValue) Author: Graham_Walmsley (Xara Group Ltd) Created: 21/8/96 Inputs: Purpose: Constructs a User Attribute node given a Key, SubKey and Value ********************************************************************************************/ AttrUser::AttrUser( const StringBase& NewKey, const StringBase& NewSubKey, const StringBase& NewValue) { if (!Value.Key.Alloc(NewKey.Length())) return; Value.Key = NewKey; INT32 n = NewKey.Length(); if (!NewSubKey.IsEmpty()) n += 1 + NewSubKey.Length(); if (!Value.LongKey.Alloc(n)) return; Value.LongKey = NewKey; if (!NewSubKey.IsEmpty()) { Value.LongKey += s_KeyDelimiter; Value.LongKey += NewSubKey; } if (!Value.Value.Alloc(NewValue.Length())) return; Value.Value = NewValue; } /******************************************************************************************** > AttrUser::AttrUser(const StringBase& NewLongKey) Author: Colin_Barfoot (Xara Group Ltd) Created: 21/07/97 Purpose: Constructs an AttrUser (User attribute node) from a long key ********************************************************************************************/ AttrUser::AttrUser(const StringBase& NewLongKey, const StringBase& NewValue) { // Find the first bit of the long key INT32 DelimiterPosition = NewLongKey.FindNextChar(s_KeyDelimiter); if (DelimiterPosition < 0) { // couldn't find the end so the delimiter is beyond the end of the string DelimiterPosition = NewLongKey.Length(); } INT32 ShortKeyLength = DelimiterPosition; if (ShortKeyLength > 0) { // Added by Craig Hamilton 2/8/00. // This section of code deals with the situation where the length of Value.Key.Length is // less than ShortKeyLength. This was causing problems with the call to StringBase::Left // which would fail in this eventuality. To prevent this we just allocate Value.Key more // space. We did try another method involving the use of a String_256 being passed to // StringBase::Left and then asigning Value.Key to the String_256, but this caused a // Damage: after normal block error in the VC++ debug library. if(Value.Key.Length() < ShortKeyLength) { Value.Key.Alloc(ShortKeyLength); } // End Added. NewLongKey.Left(&Value.Key, ShortKeyLength); } else { TRACE( _T("AttrUser::AttrUser - no key\n")); } if (!Value.LongKey.Alloc(NewLongKey.Length())) return; Value.LongKey = NewLongKey; if (!Value.Value.Alloc(NewValue.Length())) return; Value.Value = NewValue; } /******************************************************************************************** > void AttrUser::Render( RenderRegion* pRender) Author: Graham_Walmsley (Xara Group Ltd) Created: 14/6/96 Purpose: We don't need to render a user attribute. So simply do nothing. ********************************************************************************************/ void AttrUser::Render(RenderRegion* pRender) { //Don't need to do anything to render a User Attribute. } /******************************************************************************************** > void AttrUser::Transform( TransformBase& Trans ) Author: Graham_Walmsley (Xara Group Ltd) Created: 14/8/96 Inputs: Trans - the transform object to apply to this attribute. Purpose: We don't need to transform a User Attribute - so this function does nothing SeeAlso: NodeRenderable::Transform ********************************************************************************************/ void AttrUser::Transform( TransformBase& Trans ) { //Transforming a User Attribute does nothing. } /*********************************************************************************************** > Node* AttrUser::SimpleCopy() Author: Will_Cowling (Xara Group Ltd) Created: 21/6/93 Inputs: - Outputs: Returns: A copy of the node, or NULL if memory runs out Purpose: This method returns a shallow copy of the node with all Node pointers NULL. The function is virtual, and must be defined for all derived classes. Errors: If memory runs out when trying to copy, then ERROR is called with an out of memory error and the function returns NULL. Scope: protected ***********************************************************************************************/ Node* AttrUser::SimpleCopy() { AttrUser* pNodeCopy = new AttrUser; ERRORIF(pNodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL); CopyNodeContents(pNodeCopy); return pNodeCopy; } /******************************************************************************************** > INT32 AttrUser::operator==(const NodeAttribute& Attrib) Author: Graham_Walmsley (Xara Group Ltd) , from Simon Created: 9/2/94 Inputs: Atrib: The attribute to compare, which must be an AttrUser Outputs: - Returns: - Purpose: A virtual comparison operator. See NodeAttribute::operator== for a description of why it's required. Graham says: with this class you actually need to compare two values (the Value and and the Key) not just one. Errors: An ENSURE failure will occur if Attrib does not have a AttrUser runtime class. SeeAlso: NodeAttribute::operator== ********************************************************************************************/ INT32 AttrUser::operator==(const NodeAttribute& Attrib) { ENSURE(Attrib.IsKindOf(CC_RUNTIME_CLASS(AttrUser)), "Trying to compare two objects with different types"); AttrUser& OtherUserNode = (AttrUser&) Attrib; return !(Value.IsDifferent(&OtherUserNode.Value)); } /******************************************************************************************** > virtual UINT32 AttrUser::GetAttrNameID(void) Author: Graham_Walmsley (Xara Group Ltd) from Simon Created: 22/2/94 Inputs: - Outputs: - Returns: Attribute description ID Purpose: Returns back a string resource ID describing the attribute Errors: - SeeAlso: - ********************************************************************************************/ UINT32 AttrUser::GetAttrNameID(void) { return (_R(IDS_USERATTRIBUTE_ID)); } /*********************************************************************************************** > ` void AttrUser::CopyNodeContents( AttrUser* NodeCopy) Author: Graham_Walmsley (Xara Group Ltd) from Simon Created: 28/4/93 Inputs: Outputs: A copy of this node Returns: - Purpose: This method copies the node's contents to the node pointed to by NodeCopy. Errors: An assertion failure will occur if NodeCopy is NULL Scope: protected ***********************************************************************************************/ void AttrUser::CopyNodeContents( AttrUser* NodeCopy) { NodeAttribute::CopyNodeContents(NodeCopy); NodeCopy->Value = Value; } /*********************************************************************************************** > void AttrUser::PolyCopyNodeContents(NodeRenderable* pNodeCopy) Author: Phil_Martin (Xara Group Ltd) Created: 18/12/2003 Outputs: - Purpose: Polymorphically copies the contents of this node to another Errors: An assertion failure will occur if NodeCopy is NULL Scope: protected ***********************************************************************************************/ void AttrUser::PolyCopyNodeContents(NodeRenderable* pNodeCopy) { ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node"); ENSURE(IS_A(pNodeCopy, AttrUser), "PolyCopyNodeContents given wrong dest node type"); if (IS_A(pNodeCopy, AttrUser)) CopyNodeContents((AttrUser*)pNodeCopy); } #ifdef _DEBUG /*********************************************************************************************** > void AttrUser::ShowDebugTreeDetails() const Author: Will_Cowling (Xara Group Ltd) Created: 21/6/93 Purpose: Displays debugging info of the tree ***********************************************************************************************/ void AttrUser::ShowDebugTreeDetails() const { // Display a bit of debugging info // For now, we will just call the base class version NodeAttribute::ShowDebugTreeDetails(); } #endif void AttrUser::GetDebugDetails(StringBase* Str) { #ifdef _DEBUG NodeAttribute::GetDebugDetails( Str ); *Str += TEXT("\r\nKey = "); *Str += Value.Key; *Str += TEXT("\r\nLongKey = "); *Str += Value.LongKey; *Str += TEXT("\r\nData= "); *Str += Value.Value; #endif } /******************************************************************************************** > virtual UINT32 AttrUser::GetNodeSize() const Author: Graham_Walmsley (Xara Group Ltd) from Simon Created: 6/10/93 Inputs: - Outputs: - Returns: The size of the node in bytes Purpose: For finding the size of the node SeeAlso: Node::GetSubtreeSize ********************************************************************************************/ UINT32 AttrUser::GetNodeSize() const { return sizeof(*this); } /******************************************************************************************** > virtual BOOL AttrUser::ShouldBeOptimized() Author: Colin_Barfoot (Xara Group Ltd) Created: 24/06/97 Purpose: When applying multiple template args / WizOp user attributes we want them to remain associated with the object they were applied to rather than migrating to groups, otherwise where there was once two questions for two objects in a group there would instead be one. The default AttrUser should always be optimized out. Returns: TRUE if the attribute should be optimized, normalized, etc. FALSE otherwise See Also: NodeRenderableInk::NormaliseAttributes() NodeRenderableInk::FindCommonAttributesToFactorOut() NodeRenderableInk::MakeAttributeComplete() ********************************************************************************************/ BOOL AttrUser::ShouldBeOptimized() { return Value.Key.IsEmpty() && Value.LongKey.IsEmpty() && Value.Value.IsEmpty(); } /******************************************************************************************** > virtual BOOL AttrUser::Blend(BlendAttrParam* pBlendParam) Author: Graham_Walmsley (Xara Group Ltd) from MarkN Created: 14/8/96 Inputs: pBlendParam = ptr to blend attribute param object holding all info needed Outputs: - Returns: TRUE if successful, FALSE otherwise Purpose: Blends one User attribute with another. SeeAlso: - ********************************************************************************************/ BOOL AttrUser::Blend(BlendAttrParam* pBlendParam) { // Get the User member to blend to the User member of the other NodeAttribute. // If it succeeds, ask the blended Value to make a NodeAttribute out of itself. ERROR3IF(pBlendParam == NULL,"NULL entry param"); if (Value.Blend(pBlendParam)) { // Get the blended attr val. After this call, the ptr is our reponsibility // so we have to delete it if it's no longer needed AttributeValue* pBlendedAttrVal = pBlendParam->GetBlendedAttrVal(); if (pBlendedAttrVal != NULL) { // We have a blended attr val, so ask it to make a NodeAttribute out of itself // and set the pBlendParam's blended NodeAttribute ptr to it NodeAttribute* pBlendedAttr = pBlendedAttrVal->MakeNode(); pBlendParam->SetBlendedAttr(pBlendedAttr); if (pBlendedAttr != NULL) { // We were able to make a blended NodeAttribute // so delete the blended attr val, and return TRUE delete pBlendedAttrVal; return TRUE; } else { // Couldn't make a blended NodeAttribute, so give the blended attr val back // and return FALSE pBlendParam->SetBlendedAttrVal(pBlendedAttrVal); } } } return FALSE; } /******************************************************************************************** > virtual BOOL AttrUser::WritePreChildrenWeb(BaseCamelotFilter* pFilter) Author: Mark_Neves (Xara Group Ltd) Created: 30/5/96 Inputs: pFilter = ptr to the filter Returns: TRUE if record is written, FALSE if not Purpose: Writes the line width record to the filter SeeAlso: - ********************************************************************************************/ BOOL AttrUser::WritePreChildrenWeb(BaseCamelotFilter* pFilter) { #ifdef DO_EXPORT ERROR2IF(pFilter == NULL,FALSE,"NULL filter param"); BOOL ok = TRUE; CamelotFileRecord Rec(pFilter,TAG_USERVALUE,TAG_USERVALUEATTRSIZE); ok = Rec.Init(); if (ok) ok = Rec.WriteUnicode((TCHAR*)Value.LongKey); if (ok) ok = Rec.WriteUnicode((TCHAR*)Value.Value); if (ok) ok = pFilter->Write(&Rec); return ok; #else return FALSE; #endif } //-------------------------------------------------------------- // See AttrUser::WritePreChildrenWeb(BaseCamelotFilter* pFilter) // BOOL AttrUser::WritePreChildrenNative(BaseCamelotFilter* pFilter) { #ifdef DO_EXPORT return WritePreChildrenWeb(pFilter); #else return FALSE; #endif } /******************************************************************************************** > BOOL AttrUser::ShouldBecomeCurrent() Author: Graham_Walmsley (Xara Group Ltd) Created: 14/6/96 Returns: TRUE if this attribute should become current. FALSE if the user must deliberately apply this attribute to an object every time he wants to use it. Purpose: The attribute manager calls this function before making an attribute current. There are some attributes - like this URL Hot Link attribute I'm about to put in - that the user probably won't want to become current. For example, if a user puts a HotLink on an object and happens to have the Give Other Objects Most Recent Attributes option on, all his new objects are going to have HotLinks. That's not good. So those attributes will override this function and return FALSE. ********************************************************************************************/ BOOL AttrUser::ShouldBecomeCurrent() { //No, don't pass this attribute on return FALSE; } /******************************************************************************************** > StringBase& AttrUser::GetWebAddress() Author: Graham_Walmsley (Xara Group Ltd) Created: 14/6/96 Returns: The URL of the Hot Link Purpose: This is only used for Web Address User Attributes. ********************************************************************************************/ StringBase& AttrUser::GetWebAddress() { return Value.Value; } /******************************************************************************************** > virtual AttributeIdentifier AttrUser::GetAttributeClassID() const Author: Colin_Barfoot (Xara Group Ltd) Created: 09/06/97 Purpose: Generates an AttributeIdentifier for this Attribute. Since the RuntimeClass is inadequate for dynamically generated Atrributes (read Nodes), we need to provide an ID that can be created dynamically too. This is what an AttributeIdentifier is supposed to be. In the case of an AttrUser it returns a pointer to a template handler. ********************************************************************************************/ AttributeIdentifier AttrUser::GetAttributeClassID() const { return Value.LongKey; } /******************************************************************************************** > VisibleAttribute* AttrUser::CreateVisibleAttribute() const Author: Colin_Barfoot (Xara Group Ltd) Created: 09/06/97 Purpose: Creates a VisibleAttribute representing this AttrUser that the user can edit. (this is all horribly wrong). Returns: A new VIsibleAttribute ********************************************************************************************/ VisibleAttribute* AttrUser::CreateVisibleAttribute() const { VisibleAttribute* pVisibleAttribute = NULL; // return this PORTNOTETRACE("other","AttrUser::CreateVisibleAttribute - do nothing"); #ifndef EXCLUDE_FROM_XARALX pVisibleAttribute = new VisibleUserAttribute(Value.LongKey, Value.Value); #endif return pVisibleAttribute; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // // V I S I B L E U S E R A T T R I B U T E // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // /******************************************************************************************** > VisibleUserAttribute::VisibleUserAttribute(const StringBase& Key, const StringBase& Value) Author: Colin_Barfoot (Xara Group Ltd) Created: 09/06/97 Purpose: Represents an AttrUser that the user can edit (this is all horribly wrong). ********************************************************************************************/ VisibleUserAttribute::VisibleUserAttribute(const StringBase& Key, const StringBase& Value) : m_LongKey(Key), m_Value(Value) { } void VisibleUserAttribute::SetLongKey(const StringBase& NewKey) { m_LongKey = NewKey; } const StringBase& VisibleUserAttribute::GetKey() { const StringBase& SourceString = (const StringBase&)m_LongKey; // Find the first bit of the long key INT32 EndDelimiterPosition = SourceString.FindNextChar(s_KeyDelimiter); if (EndDelimiterPosition < 0) { // couldn't find the end so the delimiter is beyond the end of the string EndDelimiterPosition = SourceString.Length(); } const UINT32 LengthToCopy = EndDelimiterPosition; if (LengthToCopy > 0) { SourceString.Left(&m_Key, LengthToCopy); } else { TRACE( _T("VisibleUserAttribute::GetKey - no key\n")); } return m_Key; } const StringBase& VisibleUserAttribute::GetLongKey() { return m_LongKey; } const StringBase& VisibleUserAttribute::GetValue() { return m_Value; } /******************************************************************************************** > virtual NodeAttribute* VisibleUserAttribute::CreateNewAttribute() Author: Colin_Barfoot (Xara Group Ltd) Created: 09/06/97 Purpose: Creates a new NodeAttribute from what the user entered. (this is all horribly wrong). ********************************************************************************************/ NodeAttribute* VisibleUserAttribute::CreateNewAttribute() { return new AttrUser(GetLongKey(), GetValue()); } /******************************************************************************************** > virtual StringBase& GetText(StringBase& Description) const Author: Colin_Barfoot (Xara Group Ltd) Created: 09/06/97 Purpose: Returns: Some user visible text describing this VisibleUserAttribute ********************************************************************************************/ StringBase& VisibleUserAttribute::GetText(StringBase& Description) const { PORTNOTETRACE("other","VisibleUserAttribute::GetText - do nothing"); #ifndef EXCLUDE_FROM_XARALX String_32 TruncatedKey((const StringBase&)m_LongKey); Description.MakeMsg(_R(IDS_APPLIED_CUSTOM), TruncatedKey); #endif return Description; } /******************************************************************************************** > BOOL VisibleUserAttribute::Display(DialogOp& Dialog) Author: Colin_Barfoot (Xara Group Ltd) Created: 09/06/97 Purpose: This allows the user to change this VisibleUserAttribute Notes: This function takes a DialopOp as its argument to determine where to put this object. Since this requires an internal knowledge of the DialogOp at the moment it is cast to a TemplateDialog which has the fields all ready. This is likely to change in the future. ********************************************************************************************/ BOOL VisibleUserAttribute::Display(DialogOp& Dialog) { PORTNOTETRACE("other","VisibleUserAttribute::Display - do nothing"); #ifndef EXCLUDE_FROM_XARALX ERROR3IF(!((&Dialog)->IS_KIND_OF(TemplateDialog)), "Dialog isn't kind of TemplateDialog"); TemplateDialog& BetterBeThisDialog = (TemplateDialog&)Dialog; BOOL Success = TRUE; Success = m_LongKey.Display(BetterBeThisDialog.GetKeyControl()); if (Success) { Success = m_Value.Display(BetterBeThisDialog.GetValueControl()); } return Success; #else return FALSE; #endif } /******************************************************************************************** > BOOL VisibleUserAttribute::Interact(DialogOp& Dialog) Author: Colin_Barfoot (Xara Group Ltd) Created: 09/06/97 Purpose: This allows the user to change this VisibleUserAttribute Notes: This function takes a DialopOp as its argument to determine where to put this object. Since this requires an internal knowledge of the DialogOp at the moment it is cast to a TemplateDialog which has the fields all ready. This is likely to change in the future. ********************************************************************************************/ BOOL VisibleUserAttribute::Interact(DialogOp& Dialog) { PORTNOTETRACE("other","VisibleUserAttribute::Interact - do nothing"); #ifndef EXCLUDE_FROM_XARALX if (!((&Dialog)->IS_KIND_OF(TemplateDialog))) { ERROR3("Dialog isn't kind of TemplateDialog"); return FALSE; } TemplateDialog& BetterBeThisDialog = (TemplateDialog&)Dialog; if (IsNew()) { BetterBeThisDialog.GetKeyControl().Enable(); } BetterBeThisDialog.GetValueControl().Enable(); return TRUE; #else return FALSE; #endif } /******************************************************************************************** > void VisibleUserAttribute::Hide() Author: Colin_Barfoot (Xara Group Ltd) Created: 09/06/97 Purpose: Hides this VisibleUserAttribute from the user. ********************************************************************************************/ void VisibleUserAttribute::Hide() { m_LongKey.Hide(); m_Value.Hide(); }