NativeClipMap Class Reference

Clipboard mapping class for Native files -- wired into the system in winoil.cpp. More...

#include <natclipm.h>

Inheritance diagram for NativeClipMap:

ClipboardMapping ListItem CCObject SimpleCCObject List of all members.

Static Public Member Functions

static void CreateAndRegister (ClipboardMappingType TheType, UINT32 ClaimType=0)
 Constructs and registers a clipboard mapping with the ExternalClipboard manager. This mapping info describes a filter which is able to import data from or export data to a windows clipboard in some way.

Protected Member Functions

 NativeClipMap ()
 NativeClipMap (ClipboardMappingType TheType, UINT32 ClaimType=0)
 Constructs a clipboard mapping with the ExternalClipboard manager. This mapping info describes a filter which is able to import data from or export data to a windows clipboard in some way.
virtual BOOL HandleImport (SelOperation *Caller, HANDLE ClipboardData, InternalClipboard *Dest)
 Calls the parent filter as appropriate to import the given data from the external clipboard.
virtual HANDLE HandleExport (Operation *Caller, InternalClipboard *Source)
 Invokes this mapping for exporting This takes the document tree of Source, and exports it to the external (windows) clipboard. Usually this just involves calling Filter::DoExport for the parent filter, and then returning the handle to the global memory block to be placed onto the external clipboard.

Private Member Functions

BOOL RemoveMultipleLayers (InternalClipboard *Dest)
 This ensures that there is only one layer after an import into the given clipboard doc. Objects that live in any extra layers are moved to the first layer, and the extra layers are deleted.

Friends

class ExternalClipboard
class OpClipboardExport
class OpClipboardImport

Detailed Description

Clipboard mapping class for Native files -- wired into the system in winoil.cpp.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/09/96
See also:
ClipboardMapping; ExternalClipboard; Filter

Definition at line 119 of file natclipm.h.


Constructor & Destructor Documentation

NativeClipMap::NativeClipMap  )  [protected]
 

Definition at line 149 of file natclipm.cpp.

00150 {
00151     ERROR3("Please don't press that button again");
00152 }

NativeClipMap::NativeClipMap ClipboardMappingType  TheType,
UINT32  ClaimType = 0
[protected]
 

Constructs a clipboard mapping with the ExternalClipboard manager. This mapping info describes a filter which is able to import data from or export data to a windows clipboard in some way.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/09/96
Parameters:
TheType - indicates import / export / import & export [INPUTS]
ClaimType - specifies the text type that this mapping will claim from the windows clipboard - that is, create 3 of these mappings, specifying CF_TEXT, CF_UNICODETEXT, and CF_OEMTEXT, and they will all ask the clipboard for UNICODE text when they actually go to import. This allows us to detect the 3 implicitly-converted clipboard formats, and map them all to UNICODE, i.e. use the UNICODE mapping for all 3 available formats. If ClaimType == 0, UNICODE is assumed

Notes: DON'T call the constructor - call CreateAndRegister

See also:
BodgeTextClipMap::CreateAndRegister

Definition at line 141 of file natclipm.cpp.

00142                 : ClipboardMapping(TheType, NULL, InternalClipboardFormat(CLIPTYPE_VECTOR),
00143                     ClaimType, 130)
00144 {
00145     if (ClaimType != 0)
00146         ExternalDataType = ClaimType;
00147 }


Member Function Documentation

void NativeClipMap::CreateAndRegister ClipboardMappingType  TheType,
UINT32  ClaimType = 0
[static]
 

Constructs and registers a clipboard mapping with the ExternalClipboard manager. This mapping info describes a filter which is able to import data from or export data to a windows clipboard in some way.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/09/96
Parameters:
TheType - indicates import / export / import & export [INPUTS]
ClaimType - specifies the text type that this mapping will claim from the

Definition at line 171 of file natclipm.cpp.

00172 {
00173     NativeClipMap *Mapping = new NativeClipMap(TheType, ClaimType);
00174     if (Mapping == NULL)
00175         InformError();
00176     else
00177         ExternalClipboard::RegisterDataType(Mapping);
00178 }

HANDLE NativeClipMap::HandleExport Operation Caller,
InternalClipboard Source
[protected, virtual]
 

Invokes this mapping for exporting This takes the document tree of Source, and exports it to the external (windows) clipboard. Usually this just involves calling Filter::DoExport for the parent filter, and then returning the handle to the global memory block to be placed onto the external clipboard.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/09/96
Parameters:
Caller - the operation within which this method is being called [INPUTS] Source - the internal clipboard (document) to be exported
Returns:
NULL (if it failed), or a windows handle of the data to be placed on the clipboard.
Notes: The returned handle should be the thing you'd pass to SetClipboardData if you were dealing with it directly. You must adhere to all the Windows rules for this - i.e. a global data block, unlocked, etc etc.

Reimplemented from ClipboardMapping.

Definition at line 453 of file natclipm.cpp.

00454 {
00455     // get a temporary file name from the base class to use as 
00456     // something to export files into it -- this is only one
00457     // possible way of getting a CCLexFile derivative to
00458     // put the exported data into.
00459     char *tempname = GetTempFileName();
00460     if (tempname == NULL)
00461     {
00462         ERROR3("Couldn't get a temp filename");
00463         return(FALSE);
00464     }
00465 
00466     // make a new disk file of this name
00467     CCDiskFile File;
00468     PathName pathname(tempname);
00469     if(!File.open(pathname, (ios::in | ios::out | ios::binary)))
00470         return 0;       // error!
00471     
00472     // get a filter to export the thingy to
00473     // we create a new filter to use rather than scanning for the
00474     // one in the filter list because it's basically just that
00475     // little bit easier
00476     CamelotNativeFilter *pFilter = new CamelotNativeFilter;
00477     BOOL ok = (pFilter != NULL);
00478 
00479     if(ok)
00480     {
00481         // export to the file -- the filter will realise it's exporting
00482         // from a clipboard, so won't get destressed and export a preview
00483         // bitmap, which won't work as we don't have an OilDoc for
00484         // the InternalClipboard documents
00485         ok = pFilter->DoExport(Caller, &File, &pathname, (Document *)Source, FALSE);
00486     }
00487 
00488     // delete the filter, we don't need it any more
00489     delete pFilter;
00490     pFilter = NULL;
00491 
00492     // this is scary Windows stuff. We're allocating a chunk of memory we
00493     // can throw at the clipboard, and we're going to read the temporary
00494     // file into it.
00495     void* pMem;
00496     INT32 FileSize;
00497     HANDLE hGlobalMem;
00498 
00499     if (ok)
00500     {
00501         // find out how big the file is
00502         FileSize = File.Size();
00503 
00504     #if (_OLE_VER >= 0x200)
00505     
00506         // Is memory already allocated?
00507         if ((hGlobalMem = m_hMem) != 0)
00508         {
00509             // Is the file too big?
00510             if (UINT32(FileSize) > m_cbMemSize) return 0;
00511         }
00512         else
00513         {
00514             // No.  Allocate some.
00515             hGlobalMem = m_hMem = GlobalAlloc(GHND, FileSize);
00516         }
00517 
00518     #else
00519         
00520         // copy the file into the global block
00521         pMem = GlobalLock(hGlobalMem);
00522     
00523     #endif
00524 
00525         // Lock the block.
00526         pMem = GlobalLock(hGlobalMem);
00527         ok = (pMem != 0);
00528     }
00529 
00530     if (ok)
00531     {
00532         // seek to beginning of file
00533         File.seekIn(0);
00534 
00535         // load data..
00536         File.read(pMem, FileSize);
00537     }
00538 
00539     // close the file
00540     if(File.isOpen()) File.close();
00541 
00542     // get rid of the temp file
00543     RemoveTempFile();
00544 
00545     // We must unlock the block before giving it to the clipboard
00546     GlobalUnlock(hGlobalMem);
00547 
00548     // and there we go, one block of memory with a native file sans preview bitmap
00549     // ready to be splatted onto the windows clipboard
00550     return hGlobalMem;
00551 }

BOOL NativeClipMap::HandleImport SelOperation Caller,
HANDLE  ClipboardData,
InternalClipboard Dest
[protected, virtual]
 

Calls the parent filter as appropriate to import the given data from the external clipboard.

Parameters:
Caller - The operation within which this method is being called [INPUTS] ClipboardData - The result of calling GetClipboardData for your datatype Dest - The InternalClipboard (document) to import the data into.
Returns:
TRUE for success
Notes: This base-class default treats the clipboard data as a file, and makes the associated filter import it directly. (Note: It is currently implemented by slaving a temp file to disc, in order to avoid CCMemFiles which are not currently good enough for us to use)

Reimplemented from ClipboardMapping.

Definition at line 195 of file natclipm.cpp.

00196 {
00197 /*
00198     Ben Summers wrote this on 12/9/96:
00199 
00200         The following code does work as far as getting data off the clipboard is concerned.
00201         
00202         However, it can't work as it should as there are are fundamental problems with the
00203         clipboard document and the way the native file format is imported.
00204 
00205         The native filter ignores the old system for importing data, and grafts the new
00206         subtree into a document tree all by it's very own. It always imports with layers,
00207         and this shafts the internal clipboard which expects everything to go onto a
00208         special layer it creates, preferably getting the Op to do the attaching.
00209 
00210         It's also possible that the Op can get a bit confused with the nodes going
00211         directly into the tree, but this could be a incorrect rumour.
00212 
00213         It could be done with some major bodging, but it has been decided not to do this.
00214 
00215         So we've got an export only thingy for OLE.
00216 
00217         It's stuff like this which makes me think that programming is in fact a
00218         particularly bad career choice. Why can't we just sit down and do lots
00219         of mathematics all day?
00220 
00221         We could also sit down more often for tea and biscuits, be nice to
00222         each other, design systems without letting spurious unjustified religious
00223         ideas from assembly language ideas hang over into OO programs, and maybe
00224         even stop inventing the wheel.
00225 
00226         Maybe then we'd all be happier, and Camelot smaller, neater and possible
00227         to maintain.
00228 
00229   Markn wrote this on 9/10/96:
00230         
00231         This func can now import native files safely using the current paste system by doing
00232         a bit of housekeeping on the doc before returning, ensuring that all the objects on the 
00233         clipboard are pastable. This housekeeping is done in RemoveMultipleLayers().
00234 
00235         It is a little bit of a bodge, but it's not horrendous.  It gives the same level of pasting you
00236         get when you copy objects from one doc, and paste into another doc, where both docs live in the
00237         same instance of Camelot.
00238 
00239         I agree with Ben that we should have tea and biscuits more often.  But do we have to be nice
00240         to each other as well?
00241 
00242 ---------------------------- */
00243 
00244     BOOL ok = FALSE;
00245 
00246     // Get a scratch file - if TMP isn't set, this will try for c:\temp.
00247     // The filename will have XS as a prefix
00248     char *tempname = GetTempFileName();
00249     if (tempname == NULL)
00250     {
00251         ERROR3("Couldn't get a temp filename");
00252         return(FALSE);
00253     }
00254 
00255     void *pMem = GlobalLock(ClipboardData);
00256     ok = (pMem != NULL);
00257 
00258     // you may not want to stop importing with layers -- but only
00259     // do this if you're not importing into the InternalClipboard
00260     // document -- it's not too happy if you bung layers in it
00261     BOOL Layers = Filter::ImportWithLayers;
00262     Filter::ImportWithLayers = FALSE;
00263 
00264     // pFilter is a class var which is the filter which will be used
00265     // for importing this file
00266     pFilter = 0;
00267 
00268     // find the cam native filter...
00269     Filter* pSearchFilter = Filter::GetFirst();
00270     while (pSearchFilter != NULL)
00271     {
00272         // is this the right filter?
00273         if(pSearchFilter->FilterID == FILTERID_NATIVE)
00274         {
00275             // got it!
00276             pFilter = pSearchFilter;
00277             break;
00278         }
00279 
00280         // next!
00281         pSearchFilter = Filter::GetNext(pSearchFilter);
00282     }
00283 
00284     TRACEUSER( "Ben", _T("NativeClipMap prospective native filter is 0x%x\n"), pFilter);            
00285 
00286     // got one?
00287     ok = (pFilter != NULL);
00288 
00289     CCDiskFile File;
00290     if(ok)
00291     {
00292         // get a file and write to it
00293         PathName pathname(tempname);
00294         if(!File.open(pathname, (ios::out | ios::binary)))
00295             ok = FALSE;     // error!
00296     }
00297 
00298     // bung out the data
00299     if(ok)
00300     {
00301         File.write(pMem, GlobalSize(ClipboardData));
00302 
00303         File.close();
00304     }
00305 
00306     // unlock the block of data
00307     GlobalUnlock(ClipboardData);
00308 
00309     // do our funky stuff with the large lump of stuff
00310     if(ok)
00311     {
00312         ok = ImportFromTempFile(tempname, Caller, Dest);
00313     }
00314 
00315     // we don't like temp files which aren't needed any more
00316     RemoveTempFile();
00317 
00318     // Make sure all the objects in the clipboard live on the first layer, so that paste works correctly
00319     ok = RemoveMultipleLayers(Dest);
00320 
00321     // unset our pointer to the filter
00322     pFilter = NULL;
00323 
00324     // we don't want to screw things up with importing layers, because that would be bad
00325     Filter::ImportWithLayers = Layers;
00326 
00327     return(ok);
00328 }

BOOL NativeClipMap::RemoveMultipleLayers InternalClipboard pImportDoc  )  [private]
 

This ensures that there is only one layer after an import into the given clipboard doc. Objects that live in any extra layers are moved to the first layer, and the extra layers are deleted.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/10/96
Parameters:
pImportDoc = ptr to the clipboard doc that received the imported file. [INPUTS]
Returns:
TRUE if ok, FALSE otherwise
This function is used to get around the limitation of the current pasting system. Pasting assumes that all the objects live on the first layer in the clipboard doc. This function ensures that the doc is in a state that allows its entire contents to be pasted by the paste op.

Definition at line 349 of file natclipm.cpp.

00350 {
00351     ERROR2IF(pImportDoc == NULL,FALSE,"NULL import doc ptr");
00352 
00353     // We must have a spread.  If not, error
00354     Spread* pSpread = pImportDoc->FindFirstSpread();
00355     if (pSpread == NULL)
00356         return FALSE;
00357 
00358     // There must be a first layer.  If not error
00359     Layer* pFirstLayer = pSpread->FindFirstLayer();
00360     if (pFirstLayer == NULL)
00361         return FALSE;
00362 
00363     // Likewise, there must be a last layer.
00364     Layer* pLastLayer = pSpread->FindLastLayer();
00365     if (pLastLayer == NULL)
00366         return FALSE;
00367 
00368     // If there isn't a layer after the first layer (i.e. there's only one layer), 
00369     // then return now, as there's nothing to do
00370     Layer* pLayer = pFirstLayer->FindNextLayer();
00371     if (pLayer == NULL)
00372         return TRUE;
00373 
00374     // If the layer after the first layer is also the last layer, then we have only two layers.
00375     // When there's only two layers, don't bother grouping the objects from the second layer when
00376     // moving them onto the first layer.
00377     BOOL GroupLayerContents = (pLayer != pLastLayer);
00378 
00379     while (pLayer != NULL)
00380     {
00381         Node* pContextNode = NULL;
00382 
00383         // If moving the contents of the layer into a group, create a group, attach it into the 
00384         // first layer, and make the group the context node
00385         if (GroupLayerContents)
00386         {
00387             pContextNode = new NodeGroup;
00388             if (pContextNode == NULL)       // If unable to make a group, fail
00389                 return FALSE;
00390 
00391             pContextNode->AttachNode(pFirstLayer,LASTCHILD);
00392         }
00393         else
00394             pContextNode = pFirstLayer;     // Otherwise just make the first layer the context node
00395 
00396         if (pContextNode != NULL)
00397         {
00398             Node* pNode = pLayer->FindFirstChild();
00399             while (pNode != NULL)
00400             {
00401                 // Move each child of the layer as a last child of the context node
00402                 Node* pNext = pNode->FindNext();
00403                 pNode->MoveNode(pContextNode,LASTCHILD);
00404                 pNode = pNext;
00405             }
00406         }
00407 
00408         // This layer is an extra layer that is now empty, so make it the layer to delete
00409         Layer* pLayerToDelete = pLayer;
00410         // First, invalidate the bounding rect
00411         pLayerToDelete->InvalidateBoundingRect();
00412 
00413         // Find the next layer before we delete the current one
00414         pLayer = pLayer->FindNextLayer();
00415 
00416         // Delete that empty layer
00417         pLayerToDelete->CascadeDelete();
00418         delete pLayerToDelete;
00419     }
00420 
00421     // Lastly, invalidate the bounding rect of the layer where all the objects are now
00422     pFirstLayer->InvalidateBoundingRect();
00423 
00424     return TRUE;
00425 }


Friends And Related Function Documentation

friend class ExternalClipboard [friend]
 

Reimplemented from ClipboardMapping.

Definition at line 123 of file natclipm.h.

friend class OpClipboardExport [friend]
 

Reimplemented from ClipboardMapping.

Definition at line 124 of file natclipm.h.

friend class OpClipboardImport [friend]
 

Reimplemented from ClipboardMapping.

Definition at line 125 of file natclipm.h.


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