InternalClipboard Class Reference

Camelot's internal clipboard document. More...

#include <clipint.h>

Inheritance diagram for InternalClipboard:

Document BaseDocument ListItem CCObject SimpleCCObject List of all members.

Public Types

enum  ID { CLIPBOARD, DRAGDROP }

Static Public Member Functions

static InternalClipboardInstance ()
static InternalClipboardOther ()
static void Swap ()
 Swaps the two internal clipboards, pInstance and pOther. Used to allow drag'n'drop operations to happen without disturbing the internal clipboard.
static ID GetCurrentID ()
static BOOL IsEmpty (BOOL AskExternalClipboard=TRUE)
 To determine if there is anything currently stored on the internal clipboard.
static void DescribeContents (String_64 *Result)
 To determine the description of the clipboard contents.
static DocRect GetObjectsBounds ()
 For finding the bounds of all objects in the clipboard.
static LayerGetInsertionLayer ()
 Returns a pointer to the clipboard's layer node which is the parent of all nodes which get added to the clipboard.
static RangeGetClipboardRange ()
static BOOL PrepareForCopy ()
 To ready the clipboard for a cut/copy operation (copy data TO the clipboard). This will interact with the external clipboard in order to claim the global clipboard, and readies the clipboard for use.
static BOOL CopyInProgress ()
 Allows external entities to determine if they were called during a clipboard copy operation.
static BOOL CopyObjects (Range &RangeToCopy, Operation *pOp=NULL)
 Copies a range of objects to the clipboard, all previous clipboard contents are deleted. If the copy fails the clipboard is emptied and FALSE returned. It can be called via CALL_WITH_FAIL.
static BOOL CopyComponentData (BaseDocument *pSrcDoc)
 This function should get called after CopyObjects has been called. It asks all objects to copy accross their component data to the clipboard. It can be called via CALL_WITH_FAIL.
static BOOL CopyCompleted ()
 Tells the InternalClipboard that you have finished copying data to it. This interacts with the external clipboard in order to make the new data available to the outside world.
static BOOL CopyText (TCHAR *pBuffer)
 Copies the text on to the clipboard (by converting it to a text object).
static BOOL PrepareForPaste (BOOL *pExternalSource=0)
 To ready the clipboard for a paste operation (copy data FROM the clipboard). This may interact with the external clipboard in order to provide the necessary data.
static BOOL PasteCompleted ()
 Tells the InternalClipboard that you have finished copying data from it. This provides interaction with the external clipboard.
static DocCoord GetOriginalCentrePoint ()
 Paste-in-place centres the objects when they are pasted at this point.
static void SetOriginalCentrePoint (DocCoord NewCentre)
 Paste-in-place centres the objects when they are pasted at this point. Reset the centre point but only do so when the centre point is unlocked.
static void Clear ()
 Deletes the contents of the internal clipboard.
static void AttrsHaveChanged ()
 This function should be called if the attributes of the Internal clipboard have changed in some way. eg. if a bitmap has been deleted. It destroys the cache of common attributes.
static BOOL Initialise ()
 This method creates the one and only instance of the InternalClipboard and then initialises it. Called by main3.cpp.
static void Deinit ()
 This method destroys the InternalClipboard It is called by main.cpp on shutdown (and now by CCamDocTemplate::CloseAllDocuments immediately prior to shutdown).

Protected Member Functions

 InternalClipboard (ID id, BOOL fHide=TRUE)
virtual ~InternalClipboard ()
 InternalClipboard destructor.
virtual BOOL Init (CCamDoc *pOilDoc)
 This method initialises the Internal clipboard. It is an internal method, called by Initialise() It calls down to Document::Init, then adds an insertion Layer node to the bottom of the basic doc tree.
virtual BOOL IsNotAClipboard () const
virtual BOOL IsAClipboard () const

Private Member Functions

BOOL OnNewClipboardObjects ()
 This fn will be called whenever data has successfuly been transfered to the InternalClipboard. i.e. After a Cut, Copy, or (paste from External Clipboard).
 CC_DECLARE_DYNAMIC (InternalClipboard)

Static Private Member Functions

static void DescribeContentsInternal (String_64 *Result)
 To determine the description of the clipboard contents.

Private Attributes

RangepClipboardRange
BOOL ClipOp
DocCoord dcCentre
ID m_id
BOOL OriginalCentreLock

Static Private Attributes

static InternalClipboardpInstance = 0
static InternalClipboardpOther = 0

Friends

class ExternalClipboard
class OpDeleteBitmap

Detailed Description

Camelot's internal clipboard document.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> (Connection to ExternalClipboard by Jason, OLE stuff by JustinF)
Date:
05/07/94 (19/4/95)
This is a cache, if you like, of the contents of the ExternalClipboard

When Camelot "owns" the external clipboard, the InternalClipboard contains the objects which will be pasted into other applications. (When external apps paste, they will request that Camelot exports the InternalClipboard in some external exchange format)

When Camelot doesn't own the external clipboard, the InternalClipboard will either be empty, or will be a cached copy of the external clipboard (if the user has pasted once into Camelot, while the clipboard remains unchanged, the internal clipboard will have the internal camelot tree representation of the clipboard cached - thus, pasting a .cdr file into camelot will only do the slow conversion once, and subsequent pastes will be 'native')

See also:
ExternalClipboard; Document

Definition at line 139 of file clipint.h.


Member Enumeration Documentation

enum InternalClipboard::ID
 

Enumerator:
CLIPBOARD 
DRAGDROP 

Definition at line 148 of file clipint.h.

00148 { CLIPBOARD, DRAGDROP };


Constructor & Destructor Documentation

InternalClipboard::InternalClipboard ID  id,
BOOL  fHide = TRUE
[protected]
 

InternalClipboard::~InternalClipboard  )  [protected, virtual]
 

InternalClipboard destructor.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/7/94

Definition at line 178 of file clipint.cpp.

00179 {
00180     delete pClipboardRange;
00181     pClipboardRange = 0;
00182 }


Member Function Documentation

void InternalClipboard::AttrsHaveChanged  )  [static]
 

This function should be called if the attributes of the Internal clipboard have changed in some way. eg. if a bitmap has been deleted. It destroys the cache of common attributes.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>

Definition at line 530 of file clipint.cpp.

00531 {
00532     if (pInstance && pInstance->pClipboardRange)
00533     {
00534         pInstance->pClipboardRange->AttrsHaveChanged();
00535     }
00536 }

InternalClipboard::CC_DECLARE_DYNAMIC InternalClipboard   )  [private]
 

void InternalClipboard::Clear  )  [static]
 

Deletes the contents of the internal clipboard.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/7/94

Definition at line 419 of file clipint.cpp.

00420 {
00421     Layer* Root = GetInsertionLayer();
00422     if (Root == NULL || Root->FindFirstChild() == NULL)
00423         return;     // The clipboard is empty already
00424 
00425     // The clipboard range is no longer valid
00426     if (pInstance->pClipboardRange) delete pInstance->pClipboardRange;
00427 
00428     // An empty range. We need to create this cos the operation could fail
00429     pInstance->pClipboardRange = new Range;
00430 
00431     // Delete all objects in clipboard
00432     Root->DeleteChildren(Root->FindFirstChild());
00433 
00434 
00435     // Ensure that the top level of the tree has bounding rect caches invalidated,
00436     // as we' ve just vaped the entire subtree below it
00437     Root->InvalidateBoundingRect();
00438 
00439   // We can't do this at the moment because by the time we're called it seems the component
00440   // copy is already under way, and so we're well screwed
00441 
00442     // Destroy and re-initialise the doc-components (to chuck away unneeded stuff)
00443 //  DestroyDocComponents(); 
00444 //  if (!InitDocComponents())
00445 //  {
00446 //      ERROR3("DocComponent initialisation failed in InternalClipboard::ClearClipboard");
00447 //  }
00448 
00449     // Instead, we are really only concerned about stacks of colours building up, so
00450     // we'll just delete any *unused* IndexedColours from the document's list. (Some colours
00451     // are kept in-use by the attribute manager and stuff...)
00452 
00453     // First, all named colours (styles)
00454     ColourList *ColList = pInstance->GetIndexedColours();
00455     IndexedColour *Ptr = (IndexedColour *) ColList->GetHead();
00456     IndexedColour *Next;
00457     while (Ptr != NULL)
00458     {
00459         Next = (IndexedColour *) ColList->GetNext((ListItem*)Ptr);
00460         if (!Ptr->IsInUse())
00461         {
00462             // Remove this colour from the list
00463             ColList->RemoveItem(Ptr);
00464 
00465             // Ensure this is not in use as a parent of other colours
00466             ColList->RemoveLinksToColour(Ptr);
00467 
00468             // And vape it
00469             delete Ptr;
00470         }
00471 
00472         Ptr = Next;
00473     }
00474 
00475     // Now all unnamed colours (locals)
00476     List *Locals = ColList->GetUnnamedColours();
00477     Ptr = (IndexedColour *) Locals->GetHead();
00478     while (Ptr != NULL)
00479     {
00480         Next = (IndexedColour *) Locals->GetNext(Ptr);
00481         if (!Ptr->IsInUse())
00482         {
00483             // Remove this colour from the list
00484             Locals->RemoveItem(Ptr);
00485 
00486             // And vape it (locals can't be parent colours, so no need to
00487             // RemoveLinksToColour() for them)
00488             delete Ptr;
00489         }
00490 
00491         Ptr = Next;
00492     }
00493 
00494     // Now do the same for this document's bitmap list
00495     BitmapList *pBmpList = pInstance->GetBitmapList();
00496     if (pBmpList)
00497     {
00498         ListItem* pItem = pBmpList->GetHead();
00499         ListItem* pNextItem;
00500         while (pItem)
00501         {
00502             pNextItem = pBmpList->GetNext(pItem);
00503 
00504             KernelBitmap* pBmpItem = (KernelBitmap*)pItem;
00505             // check if it is the default bitmap, if so then leave in the list
00506             if (!pBmpItem->IsDefaultBitmap())
00507             {           
00508                 pBmpList->RemoveItem(pBmpItem);
00509                 delete pBmpItem;
00510             }
00511 
00512             pItem = pNextItem;
00513         }
00514     }
00515 }

BOOL InternalClipboard::CopyCompleted void   )  [static]
 

Tells the InternalClipboard that you have finished copying data to it. This interacts with the external clipboard in order to make the new data available to the outside world.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/4/95
Returns:
TRUE if all went well FALSE if the copy failed in some way
Notes: Before starting to copy data to the clipboard you MUST call PrepareForCopy

See also:
InternalClipboard::PrepareForCopy; ExternalClipboard::CopyCompleted

Definition at line 864 of file clipint.cpp.

00865 {
00866     if (IsEmpty(FALSE))
00867     {
00868         ERROR3("That copy wasn't much fun - the clipboard's still empty!");
00869         return(FALSE);
00870     }
00871 
00872 PORTNOTE("extclipboard", "Removed use of External Clipboard")
00873 #ifndef EXCLUDE_FROM_XARALX
00874     ExternalClipboard *Clipboard = ExternalClipboard::GetExternalClipboard();
00875     if (Clipboard == NULL) return(FALSE);
00876 
00877     if (Clipboard->CopyCompleted())
00878     {
00879 #endif
00880         // Objects have successfully been moved to clipboard. Perform neccessary processing
00881         if (!pInstance->OnNewClipboardObjects()) InformError();
00882         return TRUE; 
00883 #ifndef EXCLUDE_FROM_XARALX
00884     }   
00885     else
00886     {
00887         return FALSE;
00888     }
00889 #endif
00890 }

BOOL InternalClipboard::CopyComponentData BaseDocument pSrcDoc  )  [static]
 

This function should get called after CopyObjects has been called. It asks all objects to copy accross their component data to the clipboard. It can be called via CALL_WITH_FAIL.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/7/94
Parameters:
pSrcDoc,: The source document [INPUTS]
Returns:
FALSE if the component data has not successfuly been copied accross. In this situation AbortComponentCopy gets called.

Definition at line 667 of file clipint.cpp.

00668 {
00669     if (IsEmpty(FALSE))
00670     {
00671         // The CopyObjects either was not called, or failed
00672         ERROR3("InternalClipboard::CopyComponentData called when clipboard is empty!");
00673         return(FALSE);
00674     }
00675     
00676     // Scan all clipboard nodes
00677     Node* Root = GetInsertionLayer();
00678     Node* Current = Root->FindFirstDepthFirst();
00679     while (Current != NULL)
00680     {
00681         // Ask the current node if it would copy it's data to the relevant DocComponents
00682         if (Current->IsKindOf(CC_RUNTIME_CLASS(NodeRenderable)))
00683         {
00684             if (!((NodeRenderable*) Current)->CopyComponentData(pSrcDoc, pInstance))
00685             {
00686                 // No luck
00687                 pInstance->AbortComponentCopy();    // Cancel all data which has been copied
00688                 Clear();        // Tidy up
00689                 return FALSE; 
00690             }
00691         }
00692 
00693         Current = Current->FindNextDepthFirst(Root); 
00694     }
00695 
00696     return TRUE; // Success
00697 }

BOOL InternalClipboard::CopyInProgress  )  [static]
 

Allows external entities to determine if they were called during a clipboard copy operation.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/4/95
Returns:
TRUE if we are currently busy copying

Definition at line 750 of file clipint.cpp.

00751 {
00752     return pInstance->ClipOp;
00753 }

BOOL InternalClipboard::CopyObjects Range RangeToCopy,
Operation pOp = NULL
[static]
 

Copies a range of objects to the clipboard, all previous clipboard contents are deleted. If the copy fails the clipboard is emptied and FALSE returned. It can be called via CALL_WITH_FAIL.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/7/94
Parameters:
RangeToCopy,: The objects to copy to the clipboard [INPUTS]
Returns:
FALSE if we could not copy
See also:
InternalClipboard::CopyComponentData()

Definition at line 560 of file clipint.cpp.

00561 {
00562      // Delete the current contents of the clipboard
00563     pInstance->ClipOp = TRUE;
00564     Clear();
00565     
00566     // All objects to be copied to the clipboard need to be made attribute complete or else
00567     // they may loose important attributes. This is especially true of objects within groups.
00568 
00569     if (!(RangeToCopy.MakeAttributeComplete(TRUE,FALSE,TRUE)))
00570         return(FALSE); // Failed
00571 
00572     BOOL Failed = FALSE;  // until we know better
00573 
00574     Node* Root = GetInsertionLayer(); 
00575     ENSURE(Root != NULL, "Root of clipboard is NULL"); 
00576 
00577     if (!Root->CopyComplexRange(RangeToCopy))
00578     {
00579         Failed = TRUE;
00580         Clear();    // Tidy up
00581         ERROR3("Failed to copy objects");
00582     }
00583 
00584 // Matt (+Karim, + MarkH + loads of other people I whined to) - 02/02/2001
00585 // Removed David McClarnon's fix for 'copy-inside on bevelled blends' as it causes the operation history to
00586 // reference the object in the clipboard - which is deleted when the clipboard is changed !!! -> AccessViolation-ahoy!
00587 /*
00588     // call post duplicate on all nodes
00589     Node * pChildNode = Root->FindFirstDepthFirst();
00590 
00591     while (pChildNode && pChildNode != Root)
00592     {
00593         if (pChildNode->IsAnObject())
00594         {
00595             if (pOp != NULL)
00596             {
00597                 if (pOp->IS_KIND_OF(UndoableOperation))
00598                 {
00599                     ((NodeRenderableInk *)pChildNode)->PostDuplicate((UndoableOperation *)pOp);
00600                 }
00601                 else
00602                 {
00603                     if (!pChildNode->IsABaseTextClass())
00604                         ((NodeRenderableInk *)pChildNode)->PostDuplicate(NULL);
00605                 }
00606             }
00607         }
00608 
00609         pChildNode = pChildNode->FindNextDepthFirst(Root);
00610     }
00611 */
00612     // We now need to optimise the attributes on all objects copied to the clipboard
00613     if (!Failed)
00614     {
00615         Node* FirstNode = pInstance->GetFirstNode();
00616         ERROR3IF(!FirstNode, "Cannot find first clipboard node"); 
00617         if (FirstNode)
00618         {
00619             Node* Root = FirstNode->FindNext(); 
00620             ERROR3IF(!Root, "Clipboard has no root");
00621             ERROR3IF(!(IS_A(Root, NodeDocument)), "This should be the root of the clipboard"); 
00622             if (Root)
00623             { 
00624                 if (!Root->OptimiseAttributes())
00625                 {
00626                     Failed = TRUE; 
00627                     Clear(); 
00628                 }
00629             } 
00630         } 
00631     
00632     }
00633  
00634         
00635     // Ensure that the top level of the tree has bounding rect caches invalidated,
00636     // as we've just plugged an entire new subtree in!
00637     ((Layer *)Root)->InvalidateBoundingRect();
00638 
00639     // We now need to Normalise the attributes of all objects copied
00640     RangeToCopy.NormaliseAttributes(FALSE,TRUE); 
00641 
00642     pInstance->ClipOp = FALSE;
00643     return (!Failed); 
00644 } 

BOOL InternalClipboard::CopyText TCHAR pcBuffer  )  [static]
 

Copies the text on to the clipboard (by converting it to a text object).

Author:
Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>, liberally copied from BodgeTextMap::HandleImport
Date:
24/4/97 Input: pcBuffer The text to copy on to the clipboard
Returns:
-
See also:
TextStory::CreateFromChars, BodgeTextMap::HandleImport

Definition at line 1347 of file clipint.cpp.

01348 {
01349 PORTNOTE("other", "InternalClipboard::CopyText disabled due to use of CCamSrvrItem")
01350 #ifndef EXCLUDE_FROM_XARALX
01351     //We need to tell CCamSrvrItem that what we are about to put on the clipboard 
01352     //should be treated as text
01353 
01354     //To do this, we call RenderProprietary Formats, which sets a flag. The
01355     //returned value will be the old state of this flag, which we must remember
01356     //cos otherwise Justin will beat me up
01357     BOOL fOldState = CCamSrvrItem::RenderProprietaryFormats(FALSE);
01358 
01359     //If we have some text
01360     if (pcBuffer != NULL && pcBuffer[0] != '\0')
01361     {
01362         //Create a text story, which we position arbitarily on the clipboard
01363         TextStory* pTextStory=TextStory::CreateFromChars(DocCoord(100,100), pcBuffer,
01364                     NULL, InternalClipboard::Instance(), NULL, TRUE);
01365 
01366         if (pTextStory!=NULL)
01367         {
01368             //Prepare to copy...this will clear the clipboard
01369             PrepareForCopy();
01370     
01371             // Attach the text story to the clipboard
01372             pTextStory->AttachNode(InternalClipboard::GetInsertionLayer(), LASTCHILD);
01373             pTextStory->NormaliseAttributes();
01374 
01375             // And format the text story properly
01376             pTextStory->FormatAndChildren(NULL,FALSE,FALSE);
01377 
01378             CopyCompleted();
01379 
01380             //And reset the old state of the flag
01381             CCamSrvrItem::RenderProprietaryFormats(fOldState);
01382 
01383             return(TRUE);
01384         }
01385 
01386         // We failed, so clear the clipboard
01387         InternalClipboard::Clear();
01388 
01389         //And reset the old state of the flag
01390         CCamSrvrItem::RenderProprietaryFormats(fOldState);
01391 
01392         return FALSE;
01393     }
01394 #endif
01395 
01396     return FALSE;
01397         
01398 }

void InternalClipboard::Deinit  )  [static]
 

This method destroys the InternalClipboard It is called by main.cpp on shutdown (and now by CCamDocTemplate::CloseAllDocuments immediately prior to shutdown).

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/8/94
Notes: This code may be called multiple times without problems. Please keep it that way.

Definition at line 315 of file clipint.cpp.

00316 {
00317     // Make sure the clipboards are empty.
00318     // Sort out the main clipboard first
00319     Clear();
00320 
00321     // Now sort out the alternate clipborad
00322     Swap();
00323     Clear();
00324     Swap();
00325     
00326     if (pInstance)
00327     {
00328         delete pInstance->GetOilDoc();
00329         pInstance = 0;
00330     }
00331 
00332     if (pOther)
00333     {
00334         delete pOther->GetOilDoc();
00335         pOther = 0;
00336     }
00337 }

void InternalClipboard::DescribeContents String_64 Result  )  [static]
 

To determine the description of the clipboard contents.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/5/95
Parameters:
Result will be filled in with either a blank string, or a description of the [OUTPUTS] current internal clipboard contents.
Notes: Redirects the call to the external clipboard, as it has a better idea of the overall picture.

See also:
ExternalClipboard::DescribeContents

Definition at line 1022 of file clipint.cpp.

01023 {
01024     ERROR3IF(Result == NULL, "Illegal NULL param");
01025 PORTNOTE("extclipboard", "Removed use of External Clipboard")
01026 #ifndef EXCLUDE_FROM_XARALX
01027     ExternalClipboard::DescribeContents(Result);
01028 #else
01029     static String_64 strDesc = String_64(_T("No description (see InternalClipboard::DescribeContents)"));
01030     Result = &strDesc;
01031 #endif
01032 }

void InternalClipboard::DescribeContentsInternal String_64 Result  )  [static, private]
 

To determine the description of the clipboard contents.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/5/95
Parameters:
Result will be filled in with either a blank string, or a description of the [OUTPUTS] current internal clipboard contents.
Notes: Internal version of this call, for the external clipboard only.

See also:
InternalClipboard::DescribeContents

Definition at line 1054 of file clipint.cpp.

01055 {
01056     ERROR3IF(Result == NULL, "Illegal NULL param");
01057 
01058     *Result = TEXT("");
01059     if (IsEmpty(FALSE)) return;
01060 
01061     // --- Scan the document tree to determine the description. Note that this should be
01062     // done by calling a range, except that the code is in SelRange, so I've rewritten it here
01063     // to save myself half a day's delay waiting for a range.h rebuild when I can't afford it...
01064 
01065     Node* Subtree = GetInsertionLayer();
01066     if (Subtree == NULL)
01067         return;
01068 
01069     Range ClipRange(Subtree->FindFirstChild(), Subtree->FindLastChild(),
01070                         RangeControl(TRUE,TRUE,TRUE,TRUE));
01071 
01072     String_256 Description;
01073     Node* Current = ClipRange.FindFirst();
01074     if (Current == NULL) return;
01075 
01076     // Implementation
01077     Node* FirstInRange = Current; 
01078     CCRuntimeClass* NodeType = Current->GetRuntimeClass();  
01079     
01080     // --------------------------------------------------------------------------------
01081     // Determine if there is more than one type of object selected
01082 
01083     BOOL OneTypeOfObject = TRUE;                          // TRUE if range contains only
01084                                                           // one type of object. 
01085     do
01086     {   
01087         if (Current->GetRuntimeClass() != NodeType)       // Range contains more than one
01088                                                           // type of object
01089         {
01090             // Current object is not the same type as the first so we know there is more
01091             // than one type of object.
01092             OneTypeOfObject = FALSE;
01093             break;
01094         }
01095 
01096         Current = ClipRange.FindNext(Current);
01097     }     
01098     while (Current);
01099     
01100     UINT32 NumObjectsInRange = ClipRange.Count();                    // Count is cached
01101     ERROR3IF(NumObjectsInRange <= 0, "No objects selected"); 
01102 
01103     if (OneTypeOfObject)
01104     {
01105         // All objects in the selection are of the same type
01106 
01107         String_32 Name;
01108         BOOL UseClassToDescribe = TRUE;
01109 
01110         NodeGroup* FirstGroup = NULL; 
01111 
01112         if (FirstInRange->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeGroup))
01113         {
01114             UseClassToDescribe = FALSE; 
01115             // If all selected groups have the same name then the name is used in the 
01116             // description
01117             FirstGroup = (NodeGroup*)FirstInRange;
01118             NodeGroup* CurrentGroup = FirstGroup;
01119             Name = CurrentGroup->GetName(); 
01120             if (!(Name.IsEmpty()))
01121             {
01122                 do
01123                 {
01124                     CurrentGroup=(NodeGroup*)ClipRange.FindNext(CurrentGroup); 
01125             
01126                     if (CurrentGroup != NULL)
01127                     {
01128                         if (CurrentGroup->GetName() != Name)
01129                         {
01130                             // A group has been found with a different name. Stop the search and
01131                             // use the class to describe the selection.
01132                             UseClassToDescribe = TRUE; 
01133                             break;                  
01134                         }
01135                     }
01136 
01137                 } while (CurrentGroup != NULL); 
01138             }
01139             else
01140             {
01141                 UseClassToDescribe = TRUE;
01142             }
01143         }
01144         if (UseClassToDescribe)
01145         {
01146             Description = (FirstInRange->Describe(NumObjectsInRange>1));                                   
01147         }
01148         else 
01149         {
01150             // Use the group name to describe the selection
01151             ERROR3IF(FirstGroup == NULL, "FirstGroup should be the first selected group"); 
01152             if (NumObjectsInRange > 1)
01153             {
01154                 Description = SelRange::Pluralise(FirstGroup->GetName()); 
01155             }
01156             else
01157             {
01158                 Description = FirstGroup->GetName();
01159             }
01160         }
01161     }
01162     else
01163     {
01164         // There must be more than one type of selected objects
01165         ERROR3IF(NumObjectsInRange <= 1, "Only a single object is in range"); 
01166         // Cos there are multiple objects of different types we describe them as 'objects'
01167         Description = String(_R(IDS_OBJECTS));  
01168     }
01169 
01170     Description.Left(Result, 63);
01171 }

static Range* InternalClipboard::GetClipboardRange  )  [inline, static]
 

Definition at line 161 of file clipint.h.

00161 { return pInstance->pClipboardRange; }

InternalClipboard::ID InternalClipboard::GetCurrentID  )  [static]
 

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/10/96
Returns:
The ID of the 'current' clipboard, the one return by Instance().

Definition at line 194 of file clipint.cpp.

00195 {
00196     return pInstance->m_id;
00197 }

Layer * InternalClipboard::GetInsertionLayer  )  [static]
 

Returns a pointer to the clipboard's layer node which is the parent of all nodes which get added to the clipboard.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (recoded from Simon's for new clipboard document layout)
Date:
23/4/95 (21/7/94)
Returns:
A pointer to the layer which is the parent of all objects placed on the clipboard

Errors: ERROR3 and returns NULL if an internal consistency check fails

Definition at line 381 of file clipint.cpp.

00382 {
00383     // Is there a tree (this gets called during destruction, which is a real pain).
00384     if (!pInstance || !pInstance->GetFirstNode())
00385     {
00386         TRACEUSER( "JustinF", _T("No first node in InternalClipboard::GetInsertionLayer\n"));
00387         return 0;
00388     }
00389 
00390     // Get the first spread
00391     Node* pSpread = pInstance->FindFirstSpread();
00392     ERROR3IF(pSpread == NULL, "No spread found in clipboard doc");
00393 
00394     // Get the spread's first child...
00395     Node *InsPos = pSpread->FindFirstChild();
00396     ERROR3IF(InsPos == NULL, "No spread-child found in clipboard doc");
00397 
00398     // And now search across until we find the first layer
00399     while (InsPos != NULL && !InsPos->IsLayer())
00400         InsPos = InsPos->FindNext();
00401 
00402     ERROR3IF(InsPos == NULL, "No insertion layer found in clipboard doc");
00403     return (Layer*) InsPos;
00404 }

DocRect InternalClipboard::GetObjectsBounds  )  [static]
 

For finding the bounds of all objects in the clipboard.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/7/94
Returns:
The bounds of all objects in the clipboard

Definition at line 714 of file clipint.cpp.

00715 {
00716     DocRect Bounds;
00717 
00718     ERROR3IF(IsEmpty(FALSE), "InternalClipboard::GetObjectsBounds called when CB is empty");
00719 
00720     Node* CurrentNode = GetInsertionLayer()->FindFirstChild();
00721     while (CurrentNode  != NULL)
00722     {
00723         if (CurrentNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)))
00724         {
00725             Bounds = Bounds.Union(
00726                 ( ((NodeRenderableBounded*)CurrentNode)->GetBoundingRect(TRUE, FALSE)) );
00727         }
00728         CurrentNode = CurrentNode->FindNext();
00729     }
00730 
00731     return Bounds;
00732 }

DocCoord InternalClipboard::GetOriginalCentrePoint  )  [static]
 

Paste-in-place centres the objects when they are pasted at this point.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/10/96
Returns:
The original centre point of the objects on the clipboard before they were copied.
See also:
InternalClipboard::OnNewClipboardObjects;

Definition at line 1305 of file clipint.cpp.

01306 {
01307     return pInstance->dcCentre;
01308 }

BOOL InternalClipboard::Init CCamDoc pOilDoc  )  [protected, virtual]
 

This method initialises the Internal clipboard. It is an internal method, called by Initialise() It calls down to Document::Init, then adds an insertion Layer node to the bottom of the basic doc tree.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/8/94
Parameters:
pOilDoc - the CCamDoc to attach the cliboard to, if any. [INPUTS]
Returns:
FALSE if it failed
See also:
InternalClipboard::Initialise(); Document::Init; Document::InitTree

Reimplemented from Document.

Definition at line 271 of file clipint.cpp.

00272 {
00273     if (!Document::Init(pOilDoc)) return FALSE;
00274 
00275     Node *pSpread = FindFirstSpread();
00276     ERROR3IF(pSpread == NULL, "No Spread in document!");
00277 
00278     Node *InsPos = pSpread->FindFirstChild();
00279     ERROR3IF(InsPos == NULL, "No Spread-child in document!");
00280 
00281     // Now scan the children of the first spread until we find a layer, or run out of nodes
00282     while (InsPos != NULL && !InsPos->IsLayer())
00283         InsPos = InsPos->FindNext();
00284 
00285     if (InsPos == NULL)     // No Layer, so we'd better add one for ourselves
00286     {
00287         String_256 LayerID = String_256(_R(IDS_K_CLIPINT_LAYERNAME));
00288         Layer *pLayer = new Layer(pSpread, LASTCHILD, LayerID);
00289         ERRORIF(!pLayer, _R(IDE_NOMORE_MEMORY), InitFailed())
00290     }
00291 
00292     OriginalCentreLock = TRUE;
00293 
00294     // Sucess.
00295     return(TRUE);;
00296 }

BOOL InternalClipboard::Initialise  )  [static]
 

This method creates the one and only instance of the InternalClipboard and then initialises it. Called by main3.cpp.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/8/94

Definition at line 213 of file clipint.cpp.

00214 {
00215     // Create the clipboards.
00216     if (!(pInstance = new InternalClipboard(InternalClipboard::CLIPBOARD))) return FALSE;
00217 
00218     if (!(pOther = new InternalClipboard(InternalClipboard::DRAGDROP)))
00219     {
00220         delete pInstance;
00221         return FALSE;
00222     }
00223 
00224 //  if (!CCamDoc::Create(pInstance))
00225 PORTNOTE("other", "Clipboard doc should be hidden")
00226     CCamDoc* pOilDoc1 = new CCamDoc(pInstance);
00227     if (pOilDoc1 == NULL)
00228     {
00229         delete pInstance;
00230         delete pOther;
00231         return FALSE;
00232     }
00233 
00234 //  if (!CCamDoc::Create(pOther))
00235 PORTNOTE("other", "Clipboard doc should be hidden")
00236     CCamDoc* pOilDoc2 = new CCamDoc(pOther);
00237     if (pOilDoc2 == NULL)
00238     {
00239         delete pInstance->GetOilDoc();
00240         delete pOther;
00241         return FALSE;
00242     }
00243 
00244     pInstance->OriginalCentreLock = TRUE;
00245      
00246     return TRUE;
00247 }

static InternalClipboard* InternalClipboard::Instance  )  [inline, static]
 

Definition at line 151 of file clipint.h.

00151 { return pInstance; }

virtual BOOL InternalClipboard::IsAClipboard  )  const [inline, protected, virtual]
 

Reimplemented from Document.

Definition at line 203 of file clipint.h.

00203 { return TRUE; };

BOOL InternalClipboard::IsEmpty BOOL  AskExternalClipboard = TRUE  )  [static]
 

To determine if there is anything currently stored on the internal clipboard.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/4/95
Parameters:
AskExternalClipboard - if TRUE, this method will tell you if there is ANY [INPUTS] data available for pasting. If FALSE, it simply checks if the internal clipboard (esentially an internal cache) is empty. ONLY the external clipboard (or internal calls in this class) should ever pass in FALSE for this parameter!
Returns:
TRUE if the clipboard is empty (no data to paste) FALSE if the clipboard is non-empty (there is data available to paste)
Notes: If there is no internal clipboard, it will return TRUE

Definition at line 777 of file clipint.cpp.

00778 {
00779     if (pInstance == NULL)
00780         return(TRUE);
00781 
00782     Layer *templayer = pInstance->GetInsertionLayer();
00783     if (!templayer) {   ERROR3("Can't get clipboard insertion layer!"); return TRUE; }
00784 
00785     Node* n = templayer->FindFirstChild();
00786     BOOL Empty = (n == NULL);
00787 
00788     if (Empty && AskExternalClipboard)
00789     {
00790 PORTNOTE("extclipboard", "Removed use of External Clipboard")
00791 #ifndef EXCLUDE_FROM_XARALX
00792         // We're empty, so ask the External clipboard if it can supply us with data
00793         ExternalClipboard *Clipboard = ExternalClipboard::GetExternalClipboard();
00794 
00795         if (Clipboard == NULL)
00796             return(TRUE);
00797 
00798         return(Clipboard->IsEmpty());
00799 #else
00800         return TRUE;
00801 #endif
00802     }
00803 
00804     return(Empty);
00805 }

virtual BOOL InternalClipboard::IsNotAClipboard  )  const [inline, protected, virtual]
 

Reimplemented from Document.

Definition at line 202 of file clipint.h.

00202 { return FALSE; };

BOOL InternalClipboard::OnNewClipboardObjects  )  [private]
 

This fn will be called whenever data has successfuly been transfered to the InternalClipboard. i.e. After a Cut, Copy, or (paste from External Clipboard).

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/9/95
Returns:
FALSE if something has gone wrong. An InformError should be called if this occurs. The Cut/Copy/Paste Operation being performed should not be aborted though.
Scope: private

Definition at line 1192 of file clipint.cpp.

01193 {
01194     // Set the bounds of the spread containing the objects to the bounds of the objects.
01195     Spread* pSpread = FindFirstSpread();
01196     ERROR2IF(!pSpread, FALSE, "No first Spread in InternalClipboard::OnNewClipboardObjects");
01197 
01198     // Calculate the bounds of all the objects on the spread (this code is based on
01199     // Spread::GetPageVisibleBounds, ie. the function that Zoom to Drawing uses).
01200     DocRect drBounds;
01201     drBounds.MakeEmpty();
01202 
01203     // Search through all the children of the spread, looking for layers.
01204     Layer* pLayer = pSpread->FindFirstLayer();
01205     while (pLayer)
01206     {
01207         // We ignore the guide layers, which always have an empty bounding box
01208         // (according to Mark Neves!)
01209         if (!pLayer->IsGuide())
01210         {
01211             // Include the bounds of the objects on this layer.
01212             drBounds = drBounds.Union(pLayer->GetBoundingRect());
01213         }
01214 
01215         // And onto the next layer ...
01216         pLayer = pLayer->FindNextLayer();
01217     }
01218 
01219     // If the bounds aren't empty then set the page size to be those bounds, so the
01220     // page is the smallest size that encloses the objects it contains.
01221     if (!drBounds.IsEmpty())
01222     {
01223         // Remember the centre of the bounds of the objects, so Paste-In-Place will
01224         // still work.
01225         dcCentre.x = drBounds.lo.x + drBounds.Width() / 2;
01226         dcCentre.y = drBounds.lo.y + drBounds.Height() / 2;
01227 
01228         // Now convert to document coordinates.
01229         pSpread->SpreadCoordToDocCoord(&drBounds);
01230 
01231         // Work out the new dimensions of the page.
01232 /*      MILLIPOINT mpWidth  = drBounds.Width();
01233         MILLIPOINT mpHeight = drBounds.Height();
01234         
01235         // Inflate the size of the page by 5% to give a pleasing border around the objects.
01236         const double fpInflate = 1.024695076596;
01237         mpWidth  = (MILLIPOINT) floor(mpWidth  *  fpInflate + 0.5);
01238         mpHeight = (MILLIPOINT) floor(mpHeight *  fpInflate + 0.5);
01239 */
01240 
01241 PORTNOTE("other", "Removed use of CCamDoc::SetPageSize")
01242 #ifndef EXCLUDE_FROM_XARALX
01243 //#if (_OLE_VER >= 0x200)       
01244         // Resize the page to just surround the objects, but don't scale the objects
01245         // by the same amount.
01246         ERROR2IF(!GetOilDoc()->SetPageSize(mpWidth, mpHeight, FALSE),
01247                  FALSE, "SetPageSize failed in InternalClipboard::OnNewClipboardObjects");
01248 //#endif
01249 #endif
01250 
01251         // Discard any undo information in this clipboard document.
01252         EmptyOperationHistory();
01253     }
01254 #ifdef _DEBUG
01255     else
01256     {
01257         // This should be investigated if you see this TRACE.  Perhaps because the selection
01258         // consisted of invisible layers?
01259         TRACE( _T("Warning: no bounds for SetPageSize in InternalClipboard::OnNewClipboardObjects (?)\n"));
01260     }
01261 #endif
01262 
01263     // Currently this routine creates a new Range of objects on the clipboard
01264     delete pClipboardRange;
01265     pClipboardRange = NULL; 
01266 
01267     // Find the first child of the clipboard's layer
01268     Node* pNode = Node::FindFirstChapter(this);  
01269     NodeRenderableInk* pInkNode = NULL;
01270     if (pNode) pNode = ((Chapter*) pNode)->FindFirstSpread(); 
01271     if (pNode) pNode = ((Spread*) pNode)->FindFirstLayer();
01272     if (pNode)
01273     {
01274         pInkNode = (NodeRenderableInk*)pNode->FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk));
01275         while (pInkNode!=NULL && !pInkNode->CanSelectAsCompoundParent())
01276         {
01277             if (pInkNode->IsCompoundClass() && ((NodeCompound*)pInkNode)->GetInkNodeFromController())
01278                 pInkNode = ((NodeCompound*)pInkNode)->GetInkNodeFromController();
01279             else
01280                 pInkNode = (NodeRenderableInk*)pInkNode->FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk));
01281         }
01282     }
01283 
01284     ERROR3IF(!pInkNode, "InternalClipboard::OnNewClipboardObjects, Where has the clipboard gone ??");
01285     if (!pInkNode) return FALSE; // What else can we do ?
01286     
01287     // Try to create a range of all objects.
01288     pClipboardRange = new Range(pInkNode, NULL, RangeControl(TRUE, TRUE));
01289     return pClipboardRange != 0;
01290 }

static InternalClipboard* InternalClipboard::Other  )  [inline, static]
 

Definition at line 152 of file clipint.h.

00152 { return pOther; }

BOOL InternalClipboard::PasteCompleted void   )  [static]
 

Tells the InternalClipboard that you have finished copying data from it. This provides interaction with the external clipboard.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/4/95
Returns:
TRUE if all went well FALSE if the paste failed in some way
Notes: Before starting to copy data to the clipboard you MUST call PrepareForCopy

See also:
InternalClipboard::PrepareForPaste; ExternalClipboard::PasteCompleted

Definition at line 981 of file clipint.cpp.

00982 {
00983     if (IsEmpty(FALSE))
00984     {
00985         ERROR3("That paste wasn't much fun - the clipboard's empty now!");
00986     }
00987 
00988 PORTNOTE("extclipboard", "Removed use of External Clipboard")
00989 #ifndef EXCLUDE_FROM_XARALX
00990     ExternalClipboard *Clipboard = ExternalClipboard::GetExternalClipboard();
00991 
00992     if (Clipboard == NULL)
00993         return(FALSE);
00994 
00995     return(Clipboard->PasteCompleted());
00996 #else
00997     return TRUE;
00998 #endif
00999 }

BOOL InternalClipboard::PrepareForCopy void   )  [static]
 

To ready the clipboard for a cut/copy operation (copy data TO the clipboard). This will interact with the external clipboard in order to claim the global clipboard, and readies the clipboard for use.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/4/95
Returns:
TRUE if the clipboard is ready to accept new data FALSE if the copy must be aborted
Notes: After you have copied data to the clipboard, you MUST call CopyCompleted

See also:
InternalClipboard::CopyCompleted; InternalClipboard::PrepareForPaste; ExternalClipboard::PrepareForCopy

Definition at line 830 of file clipint.cpp.

00831 {
00832     Clear();
00833 PORTNOTE("extclipboard", "Removed use of External Clipboard")
00834 #ifndef EXCLUDE_FROM_XARALX
00835     ExternalClipboard* pcb = ExternalClipboard::GetExternalClipboard();
00836     return pcb ? pcb->PrepareForCopy() : FALSE;
00837 #else
00838     return TRUE;
00839 #endif
00840 }

BOOL InternalClipboard::PrepareForPaste BOOL *  ExternalSource = 0  )  [static]
 

To ready the clipboard for a paste operation (copy data FROM the clipboard). This may interact with the external clipboard in order to provide the necessary data.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/4/95
Parameters:
ExternalSource,: When the function returns TRUE, ExternalSource will be TRUE [OUTPUTS] if the data has come from the external clipboard, and FALSE if not.
Returns:
TRUE if the clipboard is ready to provide data for pasting FALSE if the paste must be aborted (nothing to paste)
Notes: After copying data from the clipboard you MUST call PasteCompleted

See also:
InternalClipboard::PasteCompleted; InternalClipboard::PrepareForCopy; ExternalClipboard::PrepareForPaste

Definition at line 919 of file clipint.cpp.

00920 {
00921     if (ExternalSource)
00922         *ExternalSource = FALSE;   // Until we know better
00923 
00924     pInstance->OriginalCentreLock = TRUE;                       // Don't allow centre to be reset
00925 
00926     // If we are empty, then we'll have to go and look outside for something to put onto
00927     // the internal clipboard.
00928     if (IsEmpty(FALSE))
00929     {
00930 PORTNOTE("extclipboard", "Removed use of External Clipboard")
00931 #ifndef EXCLUDE_FROM_XARALX
00932         ExternalClipboard *Clipboard = ExternalClipboard::GetExternalClipboard();
00933         if (Clipboard == NULL || !Clipboard->PrepareForPaste())
00934             return(FALSE);
00935 
00936         // Optimise attributes on the clipboard
00937         Node* FirstNode = pInstance->GetFirstNode();
00938         ERROR3IF(!FirstNode, "Cannot find first clipboard node"); 
00939         if (FirstNode)
00940         {
00941             Node* Root = FirstNode->FindNext(); 
00942             ERROR3IF(!Root, "Clipboard has no root");
00943             ERROR3IF(!(IS_A(Root, NodeDocument)), "This should be the root of the clipboard"); 
00944             if (Root && !Root->OptimiseAttributes()) return FALSE;
00945         }
00946 
00947         // Objects successfully transferred to clipboard. Perform neccessary processing
00948         if (!pInstance->OnNewClipboardObjects()) InformError();
00949         
00950         pInstance->OriginalCentreLock = FALSE;                      // Allow centre to be reset on first Paste
00951 
00952         // Data has come from external clipboard 
00953         if (ExternalSource) *ExternalSource = TRUE;
00954 #endif
00955     }
00956 
00957     return(TRUE);
00958 }

void InternalClipboard::SetOriginalCentrePoint DocCoord  NewCentre  )  [static]
 

Paste-in-place centres the objects when they are pasted at this point. Reset the centre point but only do so when the centre point is unlocked.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/10/96 Input: NewCentre A position that the caller would like to record as being the "original centre" of the objects on the clipboard.
Returns:
-
See also:
InternalClipboard::OnNewClipboardObjects, OpPaste::DoPasteStandard;

Definition at line 1326 of file clipint.cpp.

01327 {
01328     if (!pInstance->OriginalCentreLock)
01329     {
01330         pInstance->dcCentre = NewCentre;
01331         pInstance->OriginalCentreLock = TRUE;
01332     }
01333 }

void InternalClipboard::Swap  )  [static]
 

Swaps the two internal clipboards, pInstance and pOther. Used to allow drag'n'drop operations to happen without disturbing the internal clipboard.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/9/96
Returns:
Errors: -
See also:
-

Definition at line 355 of file clipint.cpp.

00356 {
00357     InternalClipboard* pcb = pInstance;
00358     pInstance = pOther;
00359     pOther = pcb;
00360 }


Friends And Related Function Documentation

friend class ExternalClipboard [friend]
 

Definition at line 223 of file clipint.h.

friend class OpDeleteBitmap [friend]
 

Definition at line 224 of file clipint.h.


Member Data Documentation

BOOL InternalClipboard::ClipOp [private]
 

Definition at line 215 of file clipint.h.

DocCoord InternalClipboard::dcCentre [private]
 

Definition at line 216 of file clipint.h.

ID InternalClipboard::m_id [private]
 

Definition at line 217 of file clipint.h.

BOOL InternalClipboard::OriginalCentreLock [private]
 

Definition at line 218 of file clipint.h.

Range* InternalClipboard::pClipboardRange [private]
 

Definition at line 214 of file clipint.h.

InternalClipboard * InternalClipboard::pInstance = 0 [static, private]
 

Definition at line 212 of file clipint.h.

InternalClipboard * InternalClipboard::pOther = 0 [static, private]
 

Definition at line 213 of file clipint.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:55:31 2007 for Camelot by  doxygen 1.4.4