00001 // $Id: clipext.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // External clipboard interface - classes for encapsulating clipboard data mappings 00099 // and for managing data transfers between the internal and external clipboards 00100 00101 #include "camtypes.h" 00102 00103 #include "stdafx.h" 00104 //#include "clipdlg.h" 00105 #include "clipext.h" 00106 #include "clipint.h" 00107 #include "clipmap.h" 00108 #include "natclipm.h" 00109 //#include "jason.h" 00110 00111 // **** TEMPORARY BODGE includes for crappy bitmap export 00112 //#include "ccobject.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 //#include "node.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 #include "grndbmp.h" 00115 #include "layer.h" 00116 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 #include "dlgview.h" 00119 #include "vstate.h" 00120 #include "wbitmap.h" 00121 00122 #include "mainfrm.h" 00123 #include "camvw.h" 00124 // **** 00125 00126 #if (_OLE_VER >= 0x200) 00127 #include "camdoc.h" 00128 #include "camelot.h" 00129 #include "srvritem.h" 00130 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00131 #endif 00132 00133 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00134 00135 // --- Support for node types used in scanning the document tree for KeepClipboardOnExit 00136 #include "nodeblnd.h" 00137 #include "nodebmp.h" 00138 #include "bitmpinf.h" 00139 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00140 // --- 00141 00142 // --- OLE clipboard 00143 #if (_OLE_VER >= 0x200) 00144 #include "dataobj.h" 00145 #endif 00146 00147 //#include "richard2.h" // For resource strings 00148 //#include "justin3.h" 00149 //#include "mario.h" 00150 00151 CC_IMPLEMENT_MEMDUMP(ExternalClipboard, CC_CLASS_MEMDUMP) 00152 CC_IMPLEMENT_DYNCREATE(OpClipboardExport, Operation) 00153 CC_IMPLEMENT_DYNCREATE(OpClipboardImport, SelOperation) 00154 CC_IMPLEMENT_DYNAMIC(ClipboardView, View) 00155 CC_IMPLEMENT_DYNCREATE(PasteSpecialDlg, DialogOp) 00156 00157 00158 #define new CAM_DEBUG_NEW 00159 00160 00161 // define this symbol as 1 to enable paste-special behaviour (this makes a paste show 00162 // the paste-special dialogue box) or 0 to get "normal" simple paste behaviour. 00163 #if _DEBUG 00164 #define DO_PASTE_SPECIAL 1 00165 #else 00166 #define DO_PASTE_SPECIAL 1 00167 #endif 00168 00169 00170 // Statics ---------------------------------------------------------------------------------- 00171 ExternalClipboard* ExternalClipboard::pInstance = NULL; 00172 00173 // This value is the (rough) number of nodes in the clipboard tree before we think it's worth 00174 // asking the user about whether they want the clipboard contents retained on exit. This is 00175 // a very rough guide, mainly to eliminate this question when there is only trivial data 00176 // (a sentence or a couple of blobs) on the clipboard. 00177 // Note that this is not a strict node count. For example, blends and grad fill attributes 00178 // cause a large count to be added, as these nodes can produce much larger output in 00179 // standard clipboard formats such as WMF, while text characters cause a lower value. 00180 // Each other node generally adds about 10 to the value, so 2000 corresponds roughly 00181 // to 2000 characters, 200 nodes in the tree, or 10 grad-filled objects. 00182 const INT32 KeepClipboardThreshold = 4000; 00183 // ------------------------------------------------------------------------------------------ 00184 00185 00186 BOOL ExternalClipboard::m_fUpdateSystemClipboard = TRUE; 00187 00188 00189 /******************************************************************************************** 00190 Preference: DontExportCMXInIDataObject 00191 Section: OLE Local Server 00192 Range: 0 .. 1 (FALSE .. TRUE) 00193 Purpose: If TRUE then don't offer to render CorelXARA documents in Corel CMX format 00194 for transfer via the clipboard or drag'n'drop. Setting this pref. to TRUE 00195 overcomes a bug when embedding CorelXARA documents into CorelDRAW. By 00196 default this setting is TRUE. Making it FALSE will allow you to transfer 00197 CorelXARA documents to CorelDRAW via the clipboard or drag'n'drop in the 00198 CMX format, but embedding CorelXARA documents in CorelDRAW will no longer# 00199 work properly. 00200 ********************************************************************************************/ 00201 static BOOL fNoCMXDataExport = TRUE; 00202 00203 00204 /******************************************************************************************** 00205 00206 > ExternalClipboard::ExternalClipboard() 00207 00208 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00209 Created: 16/4/95 00210 00211 Purpose: constructor 00212 00213 ********************************************************************************************/ 00214 00215 ExternalClipboard::ExternalClipboard() 00216 { 00217 if (pInstance == NULL) 00218 pInstance = this; 00219 else 00220 { 00221 ERROR3("Oy! You can't have more than one instance of the ExternalClipboard!"); 00222 } 00223 00224 KeepFormatsOnExit = TRUE; 00225 00226 #if (_OLE_VER >= 0x200) 00227 m_fIgnoreChange = FALSE; 00228 #endif 00229 } 00230 00231 00232 00233 /******************************************************************************************** 00234 00235 > virtual ExternalClipboard::~ExternalClipboard() 00236 00237 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00238 Created: 16/4/95 00239 00240 Purpose: Destructor. Cleans up our lists and wotnot. 00241 00242 ********************************************************************************************/ 00243 00244 ExternalClipboard::~ExternalClipboard() 00245 { 00246 Mappings.DeleteAll(); 00247 00248 if (pInstance == this) 00249 pInstance = NULL; 00250 else 00251 { 00252 ERROR3("Oy! You can't have more than one instance of the ExternalClipboard!"); 00253 } 00254 } 00255 00256 00257 00258 /******************************************************************************************** 00259 00260 > static BOOL ExternalClipboard::Init(void) 00261 00262 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00263 Created: 16/4/95 00264 00265 Purpose: Initialises the ExternalClipboard ready for operation 00266 00267 SeeAlso: ExternalClipboard::Deinit 00268 00269 ********************************************************************************************/ 00270 00271 BOOL ExternalClipboard::Init(void) 00272 { 00273 if (!OpClipboardExport::Init()) 00274 return(FALSE); 00275 00276 if (!OpClipboardImport::Init()) 00277 return(FALSE); 00278 00279 if (!PasteSpecialDlg::Init()) 00280 return(FALSE); 00281 00282 ExternalClipboard *TheClipboard = new ExternalClipboard(); 00283 if (TheClipboard == NULL) 00284 return(FALSE); 00285 00286 00287 // **** !!!! DEBUG BODGE - add export mapping for text characters - ideally this 00288 // clipboard mapping should be provided by a proper text import/export filter, 00289 // but one does not exist yet. 00290 // Add a UNICODE filter - this only works under NT, as nobody else supports unicode 00291 BodgeUnicodeClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT, CF_UNICODETEXT); 00292 00293 // 8-bit text (windows implicitly converts between these for us) 00294 // The first one is the filter, while the second one is an 'alias' for import 00295 // which will make windows convert the OEMTEXT into TEXT and then we put this through 00296 // our normal TEXT mapping... 00297 BodgeTextClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT, CF_TEXT); 00298 BodgeTextClipMap::CreateAndRegister(CLIPMAP_IMPORTONLY, CF_OEMTEXT); 00299 00300 // Add bitmap/DIB import/export mappings 00301 // Note that if we export WMF and DIB, there is no need to bother with Bitmap 00302 // (Corel don't, probably because there is no way of getting a quality image via Bitmaps, 00303 // and also because some programs are stupid and corrupt the DIB by using the palette 00304 // which we supply for the Bitmap! Arrgh!) 00305 // BitmapClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT); 00306 BitmapClipMap::CreateAndRegister(CLIPMAP_IMPORTONLY); 00307 00308 DIBClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT); 00309 00310 // CMX import and export stuff to make commicating with Corel happier 00311 CMX16ClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT, ::RegisterClipboardFormat("Corel Presentation Exchange Data")); 00312 CMX32ClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT, ::RegisterClipboardFormat("Corel 32-bit Presentation Exchange Data")); 00313 00314 // native clipboard thing -- for OLE stuff 00315 // 00316 // this is export only (although functional code does exist for import) 00317 // as there are several technical problems with getting the native filter 00318 // to import into the clipboard document. See the comment near the 00319 // NativeClipMap::HandleImport() function for more details. 00320 NativeClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT /*CLIPMAP_EXPORTONLY*/, ::RegisterClipboardFormat("CorelXARA Document")); 00321 // NativeClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT /*CLIPMAP_EXPORTONLY*/, ::RegisterClipboardFormat("XaraX Document")); 00322 00323 // Add a palette export mapping - used in conjunction with Bitmap exporter, it provides 00324 // the palette for the given bitmap. (not needed now we don't export BMPs) 00325 // PaletteClipMap::CreateAndRegister(); 00326 00327 #if FALSE 00328 // And add our Quark EPS import filter 00329 QuarkPictureClipMap::CreateAndRegister(); 00330 #endif 00331 00332 // Read the bug-fix preference for CMX. 00333 if (!GetApplication()->DeclareSection(TEXT("OLE Local Server"), 5) || 00334 !GetApplication()->DeclarePref(TEXT("OLE Local Server"), 00335 TEXT("DontExportCMXInIDataObject"), 00336 &fNoCMXDataExport, FALSE, TRUE)) 00337 { 00338 TRACEUSER( "JustinF", _T("Couldn't read CMX pref in ExternalClipboard::Init\n")); 00339 return FALSE; 00340 } 00341 00342 return(TRUE); 00343 } 00344 00345 00346 00347 /******************************************************************************************** 00348 00349 > static void ExternalClipboard::Deinit(void) 00350 00351 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00352 Created: 16/4/95 00353 00354 Purpose: De-Initialises the ExternalClipboard when you're shutting down 00355 00356 SeeAlso: ExternalClipboard::Init 00357 00358 ********************************************************************************************/ 00359 00360 void ExternalClipboard::Deinit(void) 00361 { 00362 if (pInstance != NULL) 00363 delete pInstance; 00364 pInstance = NULL; 00365 } 00366 00367 00368 00370 // 00371 // The OLE clipboard 00372 // 00373 00374 #if (_OLE_VER >= 0x200) 00375 00376 /******************************************************************************************** 00377 > void ExternalClipboard::SetRenderMemory(HGLOBAL hMem) 00378 00379 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00380 Created: 16/9/96 00381 Inputs: hMem --- the global memory to delay-render into, or null if 00382 the rendering functions themselves should allocate 00383 it. 00384 Purpose: Sets the memory that the delay-render functions will render into. 00385 SeeAlso: CCamDataSource::OnRenderGlobalData 00386 ********************************************************************************************/ 00387 00388 void ExternalClipboard::SetRenderMemory(HGLOBAL hMem) 00389 { 00390 // Record the handle and its size, if any. 00391 m_hMem = hMem; 00392 m_cbMemSize = (m_hMem != 0) ? ::GlobalSize(m_hMem) : 0; 00393 } 00394 00395 00396 00397 00398 /******************************************************************************************** 00399 > HGLOBAL ExternalClipboard::GetRenderMemory() const 00400 00401 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00402 Created: 16/9/96 00403 Returns: The global memory block that was delay-rendered into. 00404 Purpose: 00405 SeeAlso: ExternalClipboard::SetRenderMemory 00406 ********************************************************************************************/ 00407 00408 HGLOBAL ExternalClipboard::GetRenderMemory() const 00409 { 00410 return m_hMem; 00411 } 00412 00413 #endif 00414 00415 00416 00417 /******************************************************************************************** 00418 > BOOL ExternalClipboard::IsOurs() const 00419 00420 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00421 Created: 16/9/96 00422 Returns: TRUE if Camelot currently owns the clipboard, FALSE if it doesn't or the 00423 clipboard is empty. 00424 SeeAlso: COleDataSource::GetClipboardOwner; CWnd::GetClipboardOwner 00425 ********************************************************************************************/ 00426 00427 BOOL ExternalClipboard::IsOurs() const 00428 { 00429 #if (_OLE_VER >= 0x200) 00430 // OLE does it with data sources (but paste still does it with window handles). 00431 return CCamDataSource::GetClipboardOwner() != 0 || 00432 CWnd::GetClipboardOwner() == GetOwnerWindow(); 00433 #else 00434 // Windows does it with window handles. 00435 return CWnd::GetClipboardOwner() == GetOwnerWindow(); 00436 #endif 00437 } 00438 00439 00440 00442 00443 00444 00445 /******************************************************************************************** 00446 00447 > static void ExternalClipboard::PrepareForShutdown() 00448 00449 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00450 Created: 31/10/95 00451 00452 Purpose: Asks the user if they want to keep the clipboard content and renders the 00453 formats immeidately if they said yes. This is called on exit, BEFORE any 00454 windows close etc, so that the user is aware that Camelot is still running 00455 and that it is busy exporting the clipboard. 00456 00457 The user may not be asked at all (e.g. if we don't own the clipboard) 00458 00459 SeeAlso: ExternalClipboard::RenderAllFormats; ExternalClipboard::CheckKeepClipboardOnExit 00460 00461 ********************************************************************************************/ 00462 00463 BOOL fBodgeNoCMX = FALSE; 00464 00465 void ExternalClipboard::PrepareForShutdown() 00466 { 00467 // Is there a clipboard? 00468 if (InternalClipboard::IsEmpty(FALSE)) return; 00469 00470 ExternalClipboard* pClipboard = GetExternalClipboard(); 00471 if (pClipboard == NULL) return; 00472 00473 pClipboard->CheckKeepClipboardOnExit(); 00474 00475 #if (_OLE_VER >= 0x200) 00476 00477 if (pClipboard->KeepFormatsOnExit) 00478 { 00479 // Render all the clipboard formats now (except CMX cos it may crash if there's a 00480 // bitmap or a fractal about - doh-doh-double-doh?!?!?) 00481 // TRACEUSER( "JustinF", _T("Rendering clipboard formats now ...\n")); 00482 fBodgeNoCMX = TRUE; 00483 CCamDataSource::FlushClipboard(); 00484 fBodgeNoCMX = FALSE; 00485 } 00486 else 00487 { 00488 // Discard the clipboard contents now. 00489 // TRACEUSER( "JustinF", _T("Discarding clipboard formats ...\n")); 00490 COleDataSource* pSource = CCamDataSource::GetClipboardOwner(); 00491 if (pSource) pSource->Empty(); 00492 } 00493 00494 #else 00495 00496 // This member var. will have been set by someone calling CheckKeepClipboardOnExit() 00497 if (!pClipboard->KeepFormatsOnExit) 00498 { 00499 // They don't want to keep the clipboard formats, so wipe the clipboard. 00500 CWnd* pParent = GetOwnerWindow(); 00501 if (pParent->OpenClipboard() != NULL) 00502 { 00503 ::EmptyClipboard(); 00504 ::CloseClipboard(); 00505 } 00506 return; 00507 } 00508 00509 // They do want to keep the clipboard contents, so render all formats to it now 00510 pClipboard->RenderAllFormats(); 00511 00512 #endif 00513 00514 // And make sure that we ignore any further attempt to make us render formats 00515 pClipboard->KeepFormatsOnExit = FALSE; 00516 } 00517 00518 00519 00520 /******************************************************************************************** 00521 00522 > void ExternalClipboard::CheckKeepClipboardOnExit(void) 00523 00524 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00525 Created: 21/4/95 00526 00527 Purpose: Called once on exit to check if the user wants the contents of the clipboard 00528 to be available after camelot is gone. This is supposed to be done when 00529 RenderAllFormats is called, but this happens after the main frame window has 00530 departed, so we want someone to call this method sometime between the last 00531 document being closed and the main frame being removed. 00532 00533 It flags the user's choice, and this result will be used if/when we get 00534 a render-all-formats request. 00535 00536 The user may not be asked at all (e.g. if we don't own the clipboard) 00537 00538 SeeAlso: ExternalClipboard::RenderAllFormats 00539 00540 ********************************************************************************************/ 00541 00542 void ExternalClipboard::CheckKeepClipboardOnExit(void) 00543 { 00544 if (InternalClipboard::IsEmpty(FALSE)) // No clipboard! 00545 return; 00546 00547 // Do we own the clipboard? 00548 if (!IsOurs()) return; 00549 00550 // OK, Now let's determine just how complicated the data is. If it looks like it 00551 // will take an INT32 time or a lot of memory to leave it on the CB, then we'll 00552 // ask the user - if not, we'll just stay quiet about it and lump it all onto 00553 // the CB without asking permission. 00554 // This is done with a very rough guide: A node count of the clipboard content, 00555 // modified slightly to take account of the fact that blends and grad fills usually 00556 // cause a lot more output (in WMF format etc). 00557 Node *pRoot = InternalClipboard::GetInsertionLayer(); 00558 if (pRoot == NULL) 00559 { 00560 KeepFormatsOnExit = TRUE; 00561 return; 00562 } 00563 00564 Node *pNode = pRoot->FindFirstDepthFirst(); 00565 INT32 RoughNodeCount = 0; 00566 00567 while (pNode != NULL && RoughNodeCount < KeepClipboardThreshold) 00568 { 00569 if (pNode->IsAVisibleTextNode()) 00570 { 00571 RoughNodeCount += 1; // Text chars export small, so count as 1 00572 } 00573 else if (IS_A(pNode, NodeBlend)) 00574 { 00575 // Each blend step counts as another 8 00576 RoughNodeCount += 128 * (((NodeBlend *)pNode)->GetNumBlendSteps()); 00577 } 00578 else if (pNode->IsAnAttribute()) 00579 { 00580 // Each fill counts as 64 (in case it's a grad fill) 00581 if (pNode->IsKindOf(CC_RUNTIME_CLASS(AttrFillGeometry))) 00582 RoughNodeCount += 64; 00583 } 00584 else if (IS_A(pNode, NodeBitmap)) 00585 { 00586 // Add Bitmap memory size to the count 00587 // This will hit the threshold at about 128kB 00588 KernelBitmapRef *BmpRef = ((NodeBitmap*)pNode)->GetBitmapRef(); 00589 if (BmpRef != NULL) 00590 { 00591 KernelBitmap *KernelBmp = BmpRef->GetBitmap(); 00592 if (KernelBmp != NULL) 00593 { 00594 OILBitmap *OilBmp = KernelBmp->ActualBitmap; 00595 if (OilBmp != NULL) 00596 { 00597 BitmapInfo BmpInfo; 00598 OilBmp->GetInfo(&BmpInfo); 00599 RoughNodeCount += BmpInfo.MemoryUsed / 32; 00600 } 00601 } 00602 } 00603 00604 } 00605 else 00606 RoughNodeCount += 10; // All other nodes count as 10 00607 00608 pNode = pNode->FindNextDepthFirst(pRoot); 00609 } 00610 00611 // Default to saving the clipboard content on exit... 00612 KeepFormatsOnExit = TRUE; 00613 00614 if (RoughNodeCount >= KeepClipboardThreshold) 00615 { 00616 // It looks a bit complicated, so maybe we'd better ask the user if they want the 00617 // clipboard contents to stick around once Camelot has quit. 00618 INT32 ButtonPressed = AskQuestion(_R(IDS_CLIPBOARD_KEEPONQUIT), 00619 _R(IDS_CLIPBOARD_KEEP), _R(IDS_CLIPBOARD_DISCARD)); 00620 00621 // Then remember whether we should render all available formats to the clipboard 00622 KeepFormatsOnExit = (ButtonPressed == 1); 00623 } 00624 } 00625 00626 00627 /******************************************************************************************** 00628 00629 > static BOOL ExternalClipboard::CanImport(UINT32 WindowsFormat) 00630 00631 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00632 Created: 2/5/95 00633 00634 Inputs: WindowsFormat - the windows format (e.g. CF_ constant) which you wish to check 00635 00636 Returns: TRUE if it can import that data type 00637 00638 Purpose: Determines if there is an import mapping that can cope with the given format 00639 00640 ********************************************************************************************/ 00641 00642 BOOL ExternalClipboard::CanImport(UINT32 WindowsFormat) 00643 { 00644 if (pInstance == NULL) 00645 return(FALSE); 00646 00647 ClipboardMapping *Mapping = (ClipboardMapping *) pInstance->Mappings.GetHead(); 00648 while (Mapping != NULL) 00649 { 00650 if (Mapping->Type != CLIPMAP_EXPORTONLY && Mapping->ExternalDataType == WindowsFormat) 00651 return(TRUE); 00652 00653 Mapping = (ClipboardMapping *) pInstance->Mappings.GetNext(Mapping); 00654 } 00655 00656 return(FALSE); 00657 } 00658 00659 00660 00661 /******************************************************************************************** 00662 00663 > static void ExternalClipboard::RegisterDataType(ClipboardMapping *Mapping) 00664 00665 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00666 Created: 16/4/95 00667 00668 Inputs: TypeInfo - info describing the import/export mapping to add 00669 00670 Purpose: Called by filters to add import/export mappings to the external clipboard. 00671 Each mapping indicates which filter to call in order to convert data 00672 between a particular internal and external clipboard format. 00673 00674 Notes: The Mapping is NOW OWNED by the ExternalClipboard. DO NOT DELETE IT. 00675 00676 ********************************************************************************************/ 00677 00678 void ExternalClipboard::RegisterDataType(ClipboardMapping *Mapping) 00679 { 00680 ERROR3IF(Mapping == NULL, "Illegal NULL param"); 00681 00682 if (pInstance == NULL) 00683 { 00684 ERROR3("Attempt to register a clipboard mapping when there is no ExternalClipboard"); 00685 delete Mapping; 00686 return; 00687 } 00688 00689 List *TheList = &pInstance->Mappings; 00690 ClipboardMapping *Ptr = (ClipboardMapping *) TheList->GetHead(); 00691 00692 while (Ptr != NULL) 00693 { 00694 if (Ptr->Priority < Mapping->Priority) 00695 { 00696 TheList->InsertBefore(Ptr, Mapping); 00697 return; 00698 } 00699 00700 Ptr = (ClipboardMapping *) TheList->GetNext(Ptr); 00701 } 00702 00703 // Haven't found a lower-priority entry, so this one belongs at the tail 00704 TheList->AddTail(Mapping); 00705 } 00706 00707 00708 00709 /******************************************************************************************** 00710 00711 > static void ExternalClipboard::DescribeContents(String_64 *Result) 00712 00713 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00714 Created: 21/5/95 00715 00716 Outputs: Result will be returned with a string describing the current clipboard 00717 format. This may be the format of the internal clipboard (quickshape, 00718 line, etc) or could be from the external clipboard (metafile, text, bitmap) 00719 00720 If no special information can be given, or if the clipboard is empty, Result 00721 will contain an empty string 00722 00723 Purpose: To get the textual description of the clipboard format which will be pasted 00724 if a paste operation is to be applied now. 00725 00726 ********************************************************************************************/ 00727 00728 void ExternalClipboard::DescribeContents(String_64 *Result) 00729 { 00730 ERROR3IF(Result == NULL, "Illegal null param"); 00731 00732 // Ensure a safe return value 00733 *Result = TEXT(""); 00734 00735 if (pInstance == NULL) // There ain't no clipboard hereabouts, mac! 00736 return; 00737 00738 if (pInstance->IsOurs() || !InternalClipboard::IsEmpty(FALSE)) 00739 { 00740 // We own the clipboard, or have a cached result - Use the internal one 00741 ERROR3IF(InternalClipboard::IsEmpty(FALSE), 00742 "We own the clipboard but the internal clipboard is empty!!"); 00743 00744 InternalClipboard::DescribeContentsInternal(Result); 00745 return; 00746 } 00747 00748 if (GetOwnerWindow()->OpenClipboard() == NULL) 00749 return; // Can't open the clipboard 00750 00751 UINT32 ThisFormat = 0; 00752 UINT32 DefaultImportFormat = 0; 00753 INT32 NumExternalFormats = 0; 00754 BOOL IncludesTextFormat = FALSE; 00755 do 00756 { 00757 ThisFormat = EnumClipboardFormats(ThisFormat); 00758 if (ThisFormat != 0 && ExternalClipboard::CanImport(ThisFormat)) 00759 { 00760 // Bodge - text can be on the clipboard in 3 forms, but we only want to treat 00761 // it as a single format for the 'paste special' count 00762 if (ThisFormat == CF_TEXT || ThisFormat == CF_UNICODETEXT || ThisFormat == CF_OEMTEXT) 00763 { 00764 if (!IncludesTextFormat) 00765 NumExternalFormats++; 00766 00767 IncludesTextFormat = TRUE; 00768 } 00769 else 00770 NumExternalFormats++; 00771 00772 // Remember which format we will import by default 00773 if (DefaultImportFormat == 0) 00774 DefaultImportFormat = ThisFormat; 00775 } 00776 } while (ThisFormat != 0); 00777 00778 ::CloseClipboard(); 00779 00780 if (NumExternalFormats > 1) 00781 { 00782 // if there are 2 or more external formats, then we'll paste special ("Paste...") 00783 *Result = _R(IDS_CLIPFORMAT_ELIPSES); // TEXT("..."); 00784 } 00785 else 00786 { 00787 // There is no data, or only one format that we recognise. If there is something we 00788 // can paste, then lob its name on the end ("Paste blobby"), else leave result blank ("Paste") 00789 if (DefaultImportFormat != 0) 00790 GetExternalFormatName(DefaultImportFormat, Result); 00791 } 00792 } 00793 00794 00795 00796 /******************************************************************************************** 00797 00798 > static void ExternalClipboard::GetExternalFormatName(UINT32 ExternalFormat, String_64 *Result) 00799 00800 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00801 Created: 22/4/95 00802 00803 Inputs: ExternalFormat - A windows clipboard format ID (e.g. a CF_ constant) 00804 00805 Outputs: Result will be returned with a string describing this format 00806 00807 Purpose: To get the textual description of a clipboard format 00808 00809 Notes: Microsoft, being in a particularly helpful frame of mind, have 00810 given us a function that does not provide the names of the default 00811 (CF_ constant) clipboard formats. We must therefore recognise all the 00812 likely formats and provide our own names. Thanks, guys. 00813 00814 ********************************************************************************************/ 00815 00816 void ExternalClipboard::GetExternalFormatName(UINT32 ExternalFormat, String_64 *Result) 00817 { 00818 ERROR3IF(Result == NULL, "Illegal NULL param"); 00819 00820 if (ExternalFormat >= 0xC000 && ExternalFormat <= 0xFFFF) 00821 { 00822 GetClipboardFormatName(ExternalFormat, (LPTSTR)((TCHAR *)*Result), 63); 00823 if (*Result==String_64(_T("CorelXARA Document"))) 00824 *Result = String(_R(IDS_CLIPFORMAT_NATIVE)); 00825 } 00826 else 00827 { 00828 switch(ExternalFormat) 00829 { 00830 case CF_TEXT: 00831 *Result = String(_R(IDS_CLIPFORMAT_ATEXT)); 00832 break; 00833 00834 case CF_BITMAP: 00835 *Result = String(_R(IDS_CLIPFORMAT_BMP)); 00836 break; 00837 00838 case CF_METAFILEPICT: 00839 *Result = String(_R(IDS_CLIPFORMAT_WMF)); 00840 break; 00841 00842 // case CF_SYLK: 00843 // *Result = TEXT("Symbolic Link"); 00844 // break; 00845 00846 // case CF_DIF: 00847 // *Result = TEXT("Data Interchange Format"); 00848 // break; 00849 00850 case CF_TIFF: 00851 *Result = String(_R(IDS_CLIPFORMAT_TIFF)); 00852 break; 00853 00854 case CF_OEMTEXT: 00855 *Result = String(_R(IDS_CLIPFORMAT_ATEXT)); // Shares 'unformatted text' with CF_TEXT 00856 break; 00857 00858 case CF_DIB: 00859 *Result = String(_R(IDS_CLIPFORMAT_DIB)); 00860 break; 00861 00862 // case CF_PALETTE: 00863 // *Result = TEXT("Palette"); 00864 // break; 00865 00866 // case CF_PENDATA: 00867 // *Result = TEXT("Pen data"); 00868 // break; 00869 00870 // case CF_RIFF: 00871 // *Result = TEXT("RIFF data"); 00872 // break; 00873 00874 // case CF_WAVE: 00875 // *Result = TEXT("WAVE sound"); 00876 // break; 00877 00878 case CF_UNICODETEXT: 00879 *Result = String(_R(IDS_CLIPFORMAT_UTEXT)); 00880 break; 00881 00882 case CF_ENHMETAFILE: 00883 *Result = String(_R(IDS_CLIPFORMAT_EMF)); 00884 break; 00885 00886 default: 00887 *Result = String(_R(IDS_CLIPFORMAT_UNRECOGNISED_FORMAT)); // "Unrecognised format" 00888 TRACE( _T("WARNING: Unrecognised 'standard' windows clipboard format (%ld), %s,%ld\n"), 00889 (INT32)ExternalFormat, __FILE__, __LINE__); 00890 break; 00891 } 00892 } 00893 00894 00895 // If you want to hack a clipboard format, this little baby knows 00896 // how to dump it into the file c:\jason.tmp 00897 #if FALSE 00898 #if _DEBUG 00899 /* 00900 if (!camStrncmp((TCHAR *)(*Result), "QuarkXPress", 10)) // A Quack XPress clipboard format? 00901 { 00902 HANDLE Bob = GetClipboardData(ExternalFormat); 00903 char *buff = (char *) GlobalLock(Bob); 00904 00905 FILE *fp = _tfopen("c:\\jason.tmp", "wb"); 00906 size_t Size = (size_t)GlobalSize(Bob); 00907 fwrite(buff, 1, Size, fp); 00908 fclose(fp); 00909 00910 GlobalUnlock(Bob); 00911 00912 ERROR3("Quack XPress data detected and saved!"); 00913 } 00914 */ 00915 #endif 00916 #endif 00917 } 00918 00919 00920 00921 /******************************************************************************************** 00922 00923 > static BOOL ExternalClipboard::IsEmpty(void) 00924 00925 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00926 Created: 19/4/95 00927 00928 Returns: TRUE if the clipboard is ready to accept new data 00929 FALSE if the copy must be aborted 00930 00931 Purpose: To ready the clipboard for a cut/copy operation (copy data TO the clipboard). 00932 This will interact with the external clipboard in order to claim the global 00933 clipboard, and readies the clipboard for use. 00934 00935 Notes: After you have copied data to the clipboard, you MUST call CopyCompleted 00936 00937 Scope: protected (for friend class InternalClipboard only) 00938 00939 SeeAlso: ExternalClipboard::CopyCompleted; ExternalClipboard::PrepareForPaste 00940 00941 ********************************************************************************************/ 00942 00943 BOOL ExternalClipboard::IsEmpty(void) 00944 { 00945 BOOL IsEmpty = TRUE; 00946 00947 if (pInstance == NULL) 00948 return(TRUE); 00949 00950 CWnd *Parent = GetOwnerWindow(); 00951 if (Parent == NULL) return TRUE; 00952 00953 if (pInstance->IsOurs()) // We own the clipboard! Use the internal one 00954 { 00955 if (InternalClipboard::IsEmpty(FALSE)) 00956 { 00957 ERROR3("We own the clipboard but the internal clipboard is empty!!"); 00958 } 00959 else 00960 { 00961 ERROR3("Why are you asking the External clipboard if it's empty when the internal one isn't?"); 00962 } 00963 return(FALSE); 00964 } 00965 00966 if (Parent->OpenClipboard() == NULL) 00967 return(TRUE); // Can't open the clipboard, so we're empty 00968 00969 ClipboardMapping *Mapping; 00970 UINT32 ThisFormat = 0; // 0 makes EnumClipboardFormats start from the beginning 00971 do 00972 { 00973 ThisFormat = EnumClipboardFormats(ThisFormat); 00974 00975 if (ThisFormat != 0) 00976 { 00977 Mapping = (ClipboardMapping *) pInstance->Mappings.GetHead(); 00978 while (Mapping != NULL && IsEmpty) 00979 { 00980 // If this mapping is an import mapping and can handle this external format, 00981 // then we need look no further - there is importable data on the clipboard 00982 if (Mapping->Type != CLIPMAP_EXPORTONLY && Mapping->ExternalDataType == ThisFormat) 00983 IsEmpty = FALSE; 00984 00985 Mapping = (ClipboardMapping *) pInstance->Mappings.GetNext(Mapping); 00986 } 00987 } 00988 } while (ThisFormat != 0 && IsEmpty); 00989 00990 ::CloseClipboard(); 00991 return(IsEmpty); 00992 } 00993 00994 00995 00996 /******************************************************************************************** 00997 00998 > BOOL ExternalClipboard::PrepareForCopy(void) 00999 01000 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01001 Created: 19/4/95 01002 01003 Returns: TRUE if the clipboard is ready to accept new data 01004 FALSE if the copy must be aborted 01005 01006 Purpose: To ready the clipboard for a cut/copy operation (copy data TO the clipboard). 01007 This will interact with the external clipboard in order to claim the global 01008 clipboard, and readies the clipboard for use. 01009 01010 Notes: After you have copied data to the clipboard, you MUST call CopyCompleted 01011 01012 Scope: protected (for friend class InternalClipboard only) 01013 01014 SeeAlso: ExternalClipboard::CopyCompleted; ExternalClipboard::PrepareForPaste 01015 01016 ********************************************************************************************/ 01017 01018 BOOL ExternalClipboard::PrepareForCopy(void) 01019 { 01020 // Do nothing 01021 01022 return(TRUE); 01023 } 01024 01025 01026 01027 /******************************************************************************************** 01028 01029 > BOOL ExternalClipboard::CopyCompleted(void) 01030 01031 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01032 Created: 19/4/95 01033 01034 Returns: TRUE if all went well 01035 FALSE if the copy failed in some way 01036 01037 Purpose: Tells the ExternalClipboard that you have finished copying data to it. 01038 This interacts with the external clipboard in order to make the new data 01039 available to the outside world. 01040 01041 Notes: Before starting to copy data to the clipboard you MUST call PrepareForCopy 01042 01043 This is called AFTER have updated the internal clipboard. However, if we 01044 already own the Windows clipboard, Windows very kindly asks us to destroy 01045 our clipboard when we call EmptyClipboard. To avoid disembowling ourselves 01046 we thus have to check if we are the owner of the clipboard so that we only 01047 wipe the internal clipboard if someone else takes control of the 01048 external clipboard - see DestroyClipboard 01049 01050 Scope: protected (for friend class InternalClipboard only) 01051 01052 SeeAlso: ExternalClipboard::PrepareForCopy 01053 01054 ********************************************************************************************/ 01055 01056 BOOL ExternalClipboard::CopyCompleted(void) 01057 { 01058 // TRACEUSER( "JustinF", _T("In ExternalClipboard::CopyCompleted\n")); 01059 InternalClipboardFormat VectorFormat(CLIPTYPE_VECTOR); 01060 01061 ClipboardMapping *Mapping = (ClipboardMapping *) Mappings.GetHead(); 01062 while (Mapping != NULL) 01063 { 01064 // Mark all "vector" mappings available for export 01065 Mapping->Available = Mapping->GetInternalDataType()->IsSameFormat(VectorFormat); 01066 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01067 } 01068 01069 // Scan the InternalClipboard document tree to determine which internal formats are available 01070 Node *pRoot = InternalClipboard::GetInsertionLayer(); 01071 Node *pNode = pRoot->FindFirstDepthFirst(); 01072 BOOL AllDone = FALSE; // Becomes TRUE when there is no need to continue the scan 01073 01074 while (pNode != NULL && !AllDone) 01075 { 01076 AllDone = TRUE; 01077 Mapping = (ClipboardMapping *) Mappings.GetHead(); 01078 while (Mapping != NULL) 01079 { 01080 if (!Mapping->Available && Mapping->Type != CLIPMAP_IMPORTONLY) 01081 { 01082 // Check if this mapping can be used on this node to provide another 01083 // output data format that was previously unavailable 01084 Mapping->Available = pNode->SupportsClipboardFormat(Mapping->GetInternalDataType()); 01085 if (!Mapping->Available) AllDone = FALSE; 01086 } 01087 01088 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01089 } 01090 01091 pNode = pNode->FindNextDepthFirst(pRoot); 01092 } 01093 01094 01095 #if (_OLE_VER >= 0x200) 01096 01097 // Put the contents of the internal clipboard on the OLE clipboard, using the 01098 // associated CCamSrvrItem to do the hard stuff. 01099 01100 m_fIgnoreChange = TRUE; 01101 01102 // Only put stuff on the external clipboard if we are allowed to ... 01103 if (m_fUpdateSystemClipboard) 01104 { 01105 // If you have been using something like GIF construction set then this may 01106 // lock the clipboard. At this point, an exception will be thrown. This is an unknown 01107 // exception as far a Camelot is concerned and so is very bad. We should really stop 01108 // the main expection handler getting its claws on it and not knowing what to do with it. 01109 // Our exception handler can just pretend that nothing really happened. 01110 // Just mention to the user about the problem. 01111 TRY 01112 { 01113 // Get the oil form of the document and the associated server item 01114 CCamDoc * pCamDoc = InternalClipboard::Instance()->GetOilDoc(); 01115 CCamSrvrItem* pServer = NULL; 01116 if (pCamDoc != NULL) 01117 pServer = pCamDoc->GetEmbeddedItem(); 01118 // If that went well then ask it to copy the data to the clipboard 01119 if (pServer != NULL) 01120 pServer->CopyToClipboard(); 01121 } 01122 CATCH(COleException, e) // Handle all ole exceptions 01123 { 01124 // "e" contains information about the exception. 01125 TRACEUSER( "Neville", _T("ExternalClipboard::CopyCompleted exception handler\n")); 01126 01127 // Do nothing special, as all this means is that the external clipboard 01128 // has had a problem. Just report a generic error to the user so that they 01129 // know that something is not working correctly. 01130 InformError(_R(IDE_CLIPBOARDCOPYPROBLEM)); // There was a problem copying to the Windows clipboard 01131 } 01132 END_CATCH 01133 } 01134 01135 m_fIgnoreChange = FALSE; 01136 return TRUE; 01137 01138 #else 01139 01140 CWnd *Parent = GetOwnerWindow(); 01141 if (Parent->OpenClipboard() != NULL) 01142 { 01143 ::EmptyClipboard(); // Clear the windows clipboard 01144 01145 // Add all available export formats onto the clipboard 01146 Mapping = (ClipboardMapping *) Mappings.GetHead(); 01147 while (Mapping != NULL) 01148 { 01149 01150 #if FALSE 01151 #if _DEBUG 01152 TRACEUSER( "Jason", _T("Mapping %s available (for ICF %ld)\n"), 01153 Mapping->Available?"is":"NOT", (INT32)(Mapping->GetInternalDataType()->GetFormatID())); 01154 #endif 01155 #endif 01156 01157 if (Mapping->Available && Mapping->Type != CLIPMAP_IMPORTONLY) 01158 ::SetClipboardData(Mapping->ExternalDataType, NULL); 01159 01160 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01161 } 01162 01163 ::CloseClipboard(); 01164 } 01165 // else another application/window has the clipboard open! 01166 01167 return(TRUE); 01168 01169 #endif 01170 } 01171 01172 01173 #if (_OLE_VER >= 0x200) 01174 01175 /******************************************************************************************** 01176 > void ExternalClipboard::DelayRenderData(CCamDataSource* pDataSource) 01177 01178 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01179 Created: 17/10/96 01180 Inputs: pDataSource --- the data source to render into 01181 Purpose: Delay-renders the old-style Camelot clipboard formats into the given 01182 data source. 01183 SeeAlso: CCamSrvrItem::OnRenderGlobalData; CCamDataSource 01184 ********************************************************************************************/ 01185 01186 void ExternalClipboard::DelayRenderData(CCamDataSource* pDataSource) 01187 { 01188 // JustinF says: bodge alert! We don't want to export *any* proprietary formats, such 01189 // as the native format or OLE embeddables, when this bodgey flag is FALSE. This finds 01190 // out the flag's value without changing it. 01191 BOOL fExportNative = CCamSrvrItem::RenderProprietaryFormats(TRUE); 01192 CCamSrvrItem::RenderProprietaryFormats(fExportNative); 01193 01194 // Tell the data source that we can render some static formats. 01195 for (ClipboardMapping* pMap = (ClipboardMapping*) pInstance->Mappings.GetHead(); 01196 pMap != 0; 01197 pMap = (ClipboardMapping*) pInstance->Mappings.GetNext(pMap)) 01198 { 01199 // JustinF says: bodge alert! We mustn't render CMX formats on shut-down because they 01200 // crash if the clipboard doc contains bitmaps or fractals. 01201 if (pMap->IS_KIND_OF(CMXClipMap) && (fBodgeNoCMX || fNoCMXDataExport)) 01202 { 01203 TRACEUSER( "JustinF", _T("Skipping CMX mapping at 0x%p\n"), (LPVOID) pMap); 01204 continue; 01205 } 01206 01207 // JustinF says: bodge alert! Don't render the native format if this flag is FALSE. 01208 if (pMap->IS_KIND_OF(NativeClipMap) && !fExportNative) 01209 { 01210 TRACEUSER( "JustinF", _T("Skipping native mapping at 0x%p\n"), (LPVOID) pMap); 01211 continue; 01212 } 01213 01214 // Can we export this format? 01215 if (pMap->Available && pMap->Type != CLIPMAP_IMPORTONLY) 01216 { 01217 // Yes, tell the data source to make this format available. 01218 pDataSource->DelayRenderData(pMap->ExternalDataType); 01219 /* TRACEUSER( "JustinF", _T("\t- added format 0x%X to COleDataSource at 0x%p\n"), 01220 (UINT32) pMap->ExternalDataType, (LPVOID) pSource); 01221 */ } 01222 } 01223 } 01224 01225 #endif 01226 01227 01228 01229 #if (_OLE_VER >= 0x200) 01230 01231 /******************************************************************************************** 01232 > static CLIPFORMAT ExternalClipboard::GetBestPasteFormat(COleDataObject* pDataObject) 01233 01234 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01235 Created: 11/10/96 01236 Inputs: pDataObject --- the data object containing the data to be queried 01237 Returns: The data format within the data object that is the most suitable for 01238 pasting, or zero if there isn't one. 01239 Purpose: Works out what we would paste from the given data object. 01240 SeeAlso: ExternalClipboard::PrepareForOlePaste 01241 ********************************************************************************************/ 01242 01243 CLIPFORMAT ExternalClipboard::GetBestPasteFormat(COleDataObject* pDataObject) 01244 { 01245 FORMATETC fmt; 01246 pDataObject->BeginEnumFormats(); 01247 while (pDataObject->GetNextFormat(&fmt)) 01248 { 01249 // Ask all the clipboard mappings if they can import this format. 01250 ClipboardMapping* pMap = (ClipboardMapping*) pInstance->Mappings.GetHead(); 01251 while (pMap) 01252 { 01253 // Can this mapping import this type of data? 01254 if (pMap->Type != CLIPMAP_EXPORTONLY && pMap->ExternalDataType == fmt.cfFormat) 01255 { 01256 // Yes it can. Check for implicit conversions between ANSI and Unicode text. 01257 if (pMap->ExternalDataType == pMap->RealExternalType || 01258 pDataObject->IsDataAvailable(pMap->RealExternalType)) 01259 { 01260 // We found a format. Return it. 01261 return pMap->RealExternalType; 01262 } 01263 } 01264 01265 // Consider the next mapping. 01266 pMap = (ClipboardMapping*) pInstance->Mappings.GetNext(pMap); 01267 } 01268 } 01269 01270 // No format is suitable, so sorry. 01271 return 0; 01272 } 01273 01274 01275 01276 /******************************************************************************************** 01277 > BOOL ExternalClipboard::PrepareForOlePaste(COleDataObject* pDataObject) 01278 01279 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01280 Created: 10/10/96 01281 Inputs: pDataObject --- the data object containing data to be 'pasted' into 01282 Camelot. 01283 Returns: TRUE if successful. 01284 Purpose: 'Pastes' from an MFC/OLE COleDataObject, rather than simply the clipboard. 01285 SeeAlso: ExternalClipboard::PrepareForPaste; ExternalClipboard::GetBestPasteFormat 01286 ********************************************************************************************/ 01287 01288 BOOL ExternalClipboard::PrepareForOlePaste(COleDataObject* pDataObject) 01289 { 01290 // Iterate through all the formats in the data object. We will paste the first that 01291 // is acceptable. 01292 ERROR2IF(!pDataObject, FALSE, 01293 "Null COleDataObject* in ExternalClipboard::PrepareForOlePaste"); 01294 BOOL fOK = FALSE; 01295 FORMATETC fmt; 01296 pDataObject->BeginEnumFormats(); 01297 while (pDataObject->GetNextFormat(&fmt)) 01298 { 01299 // Ask all the clipboard mappings if they can import this format. 01300 ClipboardMapping* pMap = (ClipboardMapping*) Mappings.GetHead(); 01301 while (pMap) 01302 { 01303 // Can this mapping import this type of data? 01304 if (pMap->Type != CLIPMAP_EXPORTONLY && pMap->ExternalDataType == fmt.cfFormat) 01305 { 01306 // Yes it can. Check for implicit conversions between ANSI and Unicode text. 01307 if (pMap->ExternalDataType == pMap->RealExternalType || 01308 pDataObject->IsDataAvailable(pMap->RealExternalType)) 01309 { 01310 // A Bodge In Two Parts. By Markn 01311 // Firstly, Clipboard docs don't have any doc views. 01312 // GetGlobalData() has the side-effect of invoking a call to OnActivateView() 01313 // Our implementation of OnActivateView() is to set the selected view to be a 01314 // view in the current doc. 01315 // Unfortunately, when it can't find a selected view, it sets the selected and current 01316 // view to NULL, BUT ALSO SETS CURRENT & SELECTED DOC TO NULL just for a laugh. 01317 // Bodge part 1 remembers the doc, & part 2 ensures it gets set back again. 01318 // This has been done locally because we are 1 day away from release, and I'm buggered 01319 // if I'm going to change a part of camelot that's called all over the shop. 01320 01321 // Bodge part 1: Remember the selected doc 01322 Document* pSelDoc = Document::GetSelected(); 01323 01324 // Extract the data from the data object into a block of memory. 01325 HGLOBAL hMem = pDataObject->GetGlobalData(pMap->RealExternalType); 01326 ERRORIF(!hMem, _R(IDE_NOMORE_MEMORY), FALSE); 01327 01328 // Bodge part 2: Restore the selected doc in case it got changed 01329 Document::SetSelectedViewAndSpread(pSelDoc); 01330 pSelDoc->SetCurrent(); 01331 01332 // Make sure the clipboard is empty before we import into it 01333 // NOTE! Don't do this before the call to pDataObject->GetGlobalData(), because 01334 // we may be dragging between docs in the same app, which means the clipboard may 01335 // actually be in used to export data when pDataObject->GetGlobalData() is called. 01336 InternalClipboard::Clear(); 01337 01338 // OK, now 'import' the data. 01339 CCRuntimeClass* pClass = CC_RUNTIME_CLASS(OpClipboardImport); 01340 OpDescriptor* pOp = OpDescriptor::FindOpDescriptor(pClass); 01341 if (pOp) 01342 { 01343 pOp->Invoke(&OpParam((INT32) pMap, (INT32) hMem)); 01344 fOK = TRUE; 01345 } 01346 goto Finished; 01347 } 01348 } 01349 01350 // Consider the next mapping. 01351 pMap = (ClipboardMapping*) Mappings.GetNext(pMap); 01352 } 01353 } 01354 01355 Finished: 01356 // Not sure what to do here! Do we destroy the data object? 01357 return fOK; 01358 } 01359 01360 #endif 01361 01362 01363 01364 /******************************************************************************************** 01365 01366 > BOOL ExternalClipboard::PrepareForPaste(void) 01367 01368 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01369 Created: 19/4/95 01370 01371 Returns: TRUE if the clipboard is ready to provide data for pasting 01372 FALSE if the paste must be aborted (nothing to paste) 01373 01374 Purpose: To ready the clipboard for a paste operation (copy data FROM the clipboard). 01375 This may interact with the external clipboard in order to provide the 01376 necessary data. 01377 01378 Notes: After copying data from the clipboard you MUST call PasteCompleted 01379 01380 Scope: protected (for friend class InternalClipboard only) 01381 01382 SeeAlso: ExternalClipboard::PasteCompleted 01383 01384 ********************************************************************************************/ 01385 01386 BOOL ExternalClipboard::PrepareForPaste(void) 01387 { 01388 // Open the clipboard - if this fails, return immediately 01389 CWnd *Parent = GetOwnerWindow(); 01390 if (Parent->OpenClipboard() == NULL) 01391 return(FALSE); 01392 01393 ClipboardMapping *Mapping; 01394 01395 UINT32 ForceFormat = 0; 01396 UINT32 ThisFormat = 0; 01397 01398 #if DO_PASTE_SPECIAL 01399 // First, count how many external formats are available - if there are less than 2 formats 01400 // which we can import, then there is no point in showing the paste-special dialogue. 01401 INT32 NumExternalFormats = 0; 01402 BOOL IncludesTextFormat = FALSE; 01403 do 01404 { 01405 ThisFormat = EnumClipboardFormats(ThisFormat); 01406 if (ThisFormat != 0 && ExternalClipboard::CanImport(ThisFormat)) 01407 { 01408 // Bodge - text can be on the clipboard in 3 forms, but we only want to treat 01409 // it as a single format for the 'paste special' count 01410 if (ThisFormat == CF_TEXT || ThisFormat == CF_UNICODETEXT || ThisFormat == CF_OEMTEXT) 01411 { 01412 if (!IncludesTextFormat) 01413 NumExternalFormats++; 01414 01415 IncludesTextFormat = TRUE; 01416 } 01417 else 01418 NumExternalFormats++; 01419 } 01420 } while (ThisFormat != 0); 01421 01422 // if there are 2 or more external fornmats, then pop up the paste special dialogue automatically 01423 if (NumExternalFormats > 1) 01424 { 01425 ForceFormat = PasteSpecialDlg::InvokeDialog(); 01426 if (ForceFormat == 0) 01427 { 01428 // User pressed "cancel" 01429 ::CloseClipboard(); 01430 return(FALSE); 01431 } 01432 } 01433 01434 #if _DEBUG 01435 { 01436 TRACEUSER( "Jason", _T("\nClipboard formats available:\n")); 01437 UINT32 ThisFormat = 0; 01438 do 01439 { 01440 ThisFormat = EnumClipboardFormats(ThisFormat); 01441 if (ThisFormat != 0) 01442 { 01443 String_64 name; 01444 GetExternalFormatName(ThisFormat, &name); 01445 TRACEUSER( "Jason", _T(" %ld %s %s\n", (INT32)ThisFormat, (TCHAR *)name, CanImport(ThisFormat)?" (supported)":"")); 01446 } 01447 } while (ThisFormat != 0); 01448 } 01449 #endif 01450 #endif 01451 01452 BOOL IKnowWhatType = FALSE; 01453 ThisFormat = 0; 01454 01455 // If we know we`ve only one format type and it`s a text object, find out if the clipboard 01456 // is holding it as a UNICODE format 01457 if(IncludesTextFormat && NumExternalFormats == 1) 01458 { 01459 // To find out if it`s unicode, we need to search the clipboard enumerations to 01460 // see if it contains the unicode type. 01461 IKnowWhatType = TRUE; 01462 UINT32 Type = EnumClipboardFormats(0); 01463 01464 while(Type > 0) 01465 { 01466 if(Type == 13) 01467 { 01468 ThisFormat = 13; 01469 break; 01470 } 01471 01472 Type = EnumClipboardFormats(Type); 01473 } 01474 01475 // If we didn`t find the unicode type set it to the normal type! 01476 if(ThisFormat == 0) 01477 ThisFormat = 1; 01478 } 01479 01480 do 01481 { 01482 if(!IKnowWhatType) 01483 ThisFormat = EnumClipboardFormats(ThisFormat); 01484 01485 if (ThisFormat != 0) 01486 { 01487 if (ForceFormat == 0 || ForceFormat == ThisFormat) 01488 Mapping = (ClipboardMapping *) Mappings.GetHead(); 01489 else 01490 Mapping = NULL; 01491 01492 while (Mapping != NULL) 01493 { 01494 // Is this mapping an import mapping for the given format? 01495 if (Mapping->Type != CLIPMAP_EXPORTONLY && Mapping->ExternalDataType == ThisFormat) 01496 { 01497 // Little check here - if this is a simple mapping, then we can go ahead. however, 01498 // if it says 'unformatted text' but will actually try to use windows' implicit conversion 01499 // to unicode text, we really need to check if the 'real' data type (unicode) is also 01500 // available on the clipboard. 01501 if (Mapping->ExternalDataType == Mapping->RealExternalType || 01502 ::IsClipboardFormatAvailable(Mapping->RealExternalType)) 01503 { 01504 #if _DEBUG 01505 { 01506 String_64 name; 01507 GetExternalFormatName(ThisFormat, &name); 01508 TRACEUSER( "Jason", _T("I choose to import: %s\n"), (TCHAR *)name); 01509 if (Mapping->ExternalDataType != Mapping->RealExternalType) 01510 { 01511 GetExternalFormatName(Mapping->RealExternalType, &name); 01512 TRACEUSER( "Jason", _T(" (Which actually imports via implicit conversion to %s)\n"), (TCHAR *)name); 01513 } 01514 } 01515 #endif 01516 OpDescriptor *ImportOp = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpClipboardImport)); 01517 ERROR3IF(ImportOp == NULL, "Clipboard Import OpDesc not found!"); 01518 01519 if (ImportOp != NULL) 01520 { 01521 OpParam Bob((INT32)Mapping, 0); 01522 ImportOp->Invoke(&Bob); 01523 } 01524 01525 ::CloseClipboard(); 01526 return(!InternalClipboard::IsEmpty(FALSE)); 01527 } 01528 01529 ERROR3("Windows implicit clipboard conversion unavailable! Trying other formats"); 01530 } 01531 01532 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01533 } 01534 } 01535 } while (ThisFormat != 0); 01536 01537 ::CloseClipboard(); 01538 return(FALSE); 01539 } 01540 01541 01542 01543 /******************************************************************************************** 01544 01545 > BOOL ExternalClipboard::PasteCompleted(void) 01546 01547 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01548 Created: 19/4/95 01549 01550 Returns: TRUE if all went well 01551 FALSE if the paste failed in some way 01552 01553 Purpose: Tells the ExternalClipboard that you have finished copying data from it. 01554 This provides interaction with the external clipboard. 01555 01556 Notes: Before starting to copy data to the clipboard you MUST call PrepareForPaste 01557 01558 Scope: protected (for friend class InternalClipboard only) 01559 01560 SeeAlso: ExternalClipboard::PrepareForPaste 01561 01562 ********************************************************************************************/ 01563 01564 BOOL ExternalClipboard::PasteCompleted(void) 01565 { 01566 // Do nothing 01567 01568 return(TRUE); 01569 } 01570 01571 01572 01573 /******************************************************************************************** 01574 01575 > void ExternalClipboard::DestroyClipboard(void) 01576 01577 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01578 Created: 16/4/95 01579 01580 Purpose: Destroys the external and internal clipboards. 01581 01582 Called in response to Windows WM_DestroyClipboard message, when another 01583 application takes ownership of the clipboard away from us. 01584 01585 Notes: Now scans all registered mappings, and calls their RemoveTempFile methods 01586 in order to remove any tempfiles left lying about "on" the clipboard. 01587 01588 ********************************************************************************************/ 01589 01590 void ExternalClipboard::DestroyClipboard(void) 01591 { 01592 // Whenever this method is called, we only wipe the clipboard if someone else owns it 01593 // (we're guaranteed to be called with us as the owner in all the situations where 01594 // we don't want to wipe the internal clipboard! Excellent!) 01595 if (!IsOurs()) 01596 { 01597 // And try to remove any temporary files that were hanging around "on" the clipboard 01598 InternalClipboard::Clear(); 01599 ClipboardMapping* Mapping = (ClipboardMapping*) Mappings.GetHead(); 01600 while (Mapping != NULL) 01601 { 01602 Mapping->RemoveTempFile(); 01603 Mapping = (ClipboardMapping*) Mappings.GetNext(Mapping); 01604 } 01605 } 01606 } 01607 01608 01609 01610 /******************************************************************************************** 01611 01612 > void ExternalClipboard::WindowsClipboardHasChanged() 01613 01614 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01615 Created: 16/4/95 01616 01617 Purpose: Destroys the internal clipboard. 01618 01619 Called whenever the contents of the Windows clipboard are changed. 01620 We use this to destroy the contents of our internal clipboard (cache). 01621 01622 ********************************************************************************************/ 01623 01624 void ExternalClipboard::WindowsClipboardHasChanged() 01625 { 01626 #if (_OLE_VER >= 0x200) 01627 // The comment below is no longer true, as now OLE takes possession of the clipboard 01628 // for us, which the old code thinks is someone else taking possession, and hence it 01629 // clears out the clipboard. This bodgy flag stops that happening when we ask OLE 01630 // to set the clipboard for us. 01631 // TRACEUSER( "JustinF", _T("In ExternalClipboard::WindowsClipboardHasChanged\n")); 01632 if (m_fIgnoreChange) 01633 { 01634 // TRACEUSER( "JustinF", _T("\t- ignoring this change to the clipboard ...\n")); 01635 return; 01636 } 01637 #endif 01638 01639 // Whenever this method is called, we only wipe the clipboard if someone else owns it 01640 // (we're guaranteed to be called with us as the owner in all the situations where 01641 // we don't want to wipe the internal clipboard! Excellent!) 01642 if (!IsOurs() && m_fUpdateSystemClipboard) InternalClipboard::Clear(); 01643 } 01644 01645 01646 01647 /******************************************************************************************** 01648 01649 > void ExternalClipboard::RenderFormat(UINT32 nFmt) 01650 01651 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01652 Created: 16/4/95 01653 01654 Inputs: ClipboardFormat - A CF_ descriptor for a Windows clipboard format 01655 01656 Purpose: "Renders" the given format to the clipboard (i.e. exports the 01657 internal clipboard to the windows clipboard using the specified mapping) 01658 01659 Called in response to WM_RENDER_FORMAT message 01660 01661 Notes: This is the external interface. This then calls the other override of 01662 RenderFormat to actually do the rendering. 01663 01664 Despite what some help entries in books online may say, this method 01665 should NOT OpenClipboard() before doing SetClipboardData() 01666 01667 ********************************************************************************************/ 01668 01669 void ExternalClipboard::RenderFormat(UINT32 nFmt) 01670 { 01671 if (InternalClipboard::IsEmpty(FALSE)) // No clipboard! Eek! 01672 return; 01673 01674 // Check for all the boring old static formats. 01675 ClipboardMapping *Mapping = (ClipboardMapping *) Mappings.GetHead(); 01676 while (Mapping != NULL) 01677 { 01678 // If this mapping is for export, and matches the desired output format 01679 if (Mapping->Type != CLIPMAP_IMPORTONLY && Mapping->ExternalDataType == nFmt) 01680 { 01681 if (Mapping->Available) 01682 RenderFormat(Mapping); 01683 else 01684 { 01685 ERROR2RAW("Requested clipboard format is unavailable!"); 01686 InformError(); 01687 } 01688 01689 return; 01690 } 01691 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01692 } 01693 01694 ERROR2RAW("Requested clipboard format is illegal (unknown)!"); 01695 InformError(); 01696 } 01697 01698 01699 01700 /******************************************************************************************** 01701 01702 > void ExternalClipboard::RenderFormat(ClipboardMapping *Info) 01703 01704 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01705 Created: 16/4/95 01706 01707 Inputs: Info - points to the information on the available format 01708 01709 Purpose: "Renders" the given format to the clipboard (i.e. exports the 01710 internal clipboard to the windows clipboard using the specified mapping) 01711 01712 Called in response to WM_RENDER_FORMAT message 01713 01714 Notes: This is the internal form of this method; It is called by the other 01715 form once the mapping has been determined. 01716 01717 Despite what some help entries in books online may say, this method 01718 should NOT OpenClipboard() before doing SetClipboardData() 01719 01720 ********************************************************************************************/ 01721 01722 void ExternalClipboard::RenderFormat(ClipboardMapping* pMapping) 01723 { 01724 ERROR3IF(pMapping == NULL, "Illegal NULL param"); 01725 ERROR3IF(!pMapping->Available, "Requested clipboard format is not available!"); 01726 ERROR3IF(pMapping->Type == CLIPMAP_IMPORTONLY, "Attempt to use import-only mapping for export"); 01727 01728 if (pMapping == NULL || !pMapping->Available || pMapping->Type == CLIPMAP_IMPORTONLY) 01729 return; 01730 01731 // JustinF says: bodge alert! We mustn't render CMX formats on shut-down because they 01732 // crash if the clipboard doc contains bitmaps or fractals. 01733 if (pMapping->IS_KIND_OF(CMXClipMap) && (fBodgeNoCMX || fNoCMXDataExport)) 01734 { 01735 TRACEUSER( "JustinF", _T("Skipping CMX mapping at 0x%p\n"), (LPVOID) pMapping); 01736 return; 01737 } 01738 01739 // The "export to clipboard" must be done inside an Op so it can call filters, so find the 01740 // OpDescriptor, and call our Export Op. 01741 OpDescriptor* pExportOp = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpClipboardExport)); 01742 ERROR3IF(pExportOp == NULL, "Clipboard Export OpDesc not found!"); 01743 01744 // The OLE clipboard can pass you an already allocated memory block of a given size. 01745 if (pExportOp) 01746 { 01747 #if (_OLE_VER >= 0x200) 01748 01749 // Pass on the mapping and the parameters from SetRenderMemory. 01750 OpClipboardExportParams prm; 01751 prm.pMapping = pMapping; 01752 prm.hMem = m_hMem; 01753 prm.cbMemSize = m_cbMemSize; 01754 prm.pDoc = m_pDoc; 01755 01756 // Invoke the export op for the given format on the given memory. 01757 OpParam opp((INT32) &prm, 0); 01758 pExportOp->Invoke(&opp); 01759 01760 // Maybe the operation allocated the memory, so update these just in case. 01761 m_hMem = prm.hMem; 01762 m_cbMemSize = prm.cbMemSize; 01763 01764 #else 01765 01766 OpParam opp((INT32) pMapping, 0); 01767 pExportOp->Invoke(&opp); 01768 01769 #endif 01770 } 01771 } 01772 01773 01774 01775 /******************************************************************************************** 01776 01777 > void ExternalClipboard::RenderAllFormats(void) 01778 01779 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01780 Created: 16/4/95 01781 01782 Purpose: Renders all available formats onto the windows clipboard 01783 Called when WM_RENDER_ALL_FORMATS is received (if the application quits 01784 when it owns the clipboard) 01785 01786 Notes: Simply calls RenderFormat for all available formats 01787 01788 Despite what some help entries in books online may say, this method 01789 should NOT OpenClipboard() before doing SetClipboardData() 01790 01791 SeeAlso: ExternalClipboard::RenderFormat 01792 01793 ********************************************************************************************/ 01794 01795 void ExternalClipboard::RenderAllFormats(void) 01796 { 01797 if (InternalClipboard::IsEmpty(FALSE)) // No clipboard! Eek! 01798 return; 01799 01800 // **** !!!! Check if the user wants us to keep the clipboard contents 01801 // This should be called from elsewhere so the question box appears before the main frame 01802 // window has been closed... 01803 // CheckKeepClipboardOnExit(); 01804 // **** 01805 01806 // This member var. will have been set by someone calling CheckKeepClipboardOnExit() 01807 if (!KeepFormatsOnExit) 01808 return; 01809 01810 CWnd *Parent = GetOwnerWindow(); 01811 if (Parent->OpenClipboard() != NULL) 01812 { 01813 ClipboardMapping *Mapping = (ClipboardMapping *) Mappings.GetHead(); 01814 while (Mapping != NULL) 01815 { 01816 if (Mapping->Type != CLIPMAP_IMPORTONLY && Mapping->Available) 01817 RenderFormat(Mapping); // Only render the available formats 01818 01819 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01820 } 01821 01822 ::CloseClipboard(); 01823 } 01824 } 01825 01826 01827 01828 /******************************************************************************************** 01829 01830 > static ExternalClipboard *ExternalClipboard::GetExternalClipboard(void) 01831 01832 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01833 Created: 16/4/95 01834 01835 Returns: A pointer to the application-wide instance of the ExternalClipboard 01836 01837 Purpose: Finds the external clipboard. Only really of any use to the InternalClipboard 01838 and the main window which has to pass events to the ExternalClipboard. 01839 01840 ********************************************************************************************/ 01841 01842 ExternalClipboard *ExternalClipboard::GetExternalClipboard(void) 01843 { 01844 return(pInstance); 01845 } 01846 01847 01848 01849 /******************************************************************************************** 01850 01851 > static CWnd *ExternalClipboard::GetOwnerWindow() 01852 01853 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01854 Created: 16/4/95 01855 01856 Returns: A pointer to the CWnd Window which "owns" the clipboard for Camelot. 01857 01858 Purpose: Finds the main window of camelot, which is used to handle all communications 01859 between us and Windows regardingthe clipboard. 01860 01861 Scope: protected 01862 01863 ********************************************************************************************/ 01864 01865 CWnd* ExternalClipboard::GetOwnerWindow() 01866 { 01867 return GetMainFrame(); 01868 } 01869 01870 01871 01872 01873 01874 01875 01876 01877 01878 01879 01880 /******************************************************************************************** 01881 01882 > void OpClipboardExport::DoWithParam(OpDescriptor*, OpParam* pOpParam) 01883 01884 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01885 Created: 21/4/95 01886 01887 Inputs: OpDescriptor - Not Used 01888 01889 pOpParam->Param1 - a (ClipboardMapping *) to control the process 01890 pOpParam->Param2 - unused (should be 0) 01891 01892 Purpose: Exports the current contents of the InternalClipoard onto the 01893 Windows clipboard. 01894 01895 ********************************************************************************************/ 01896 01897 void OpClipboardExport::DoWithParam(OpDescriptor*, OpParam* pOpParam) 01898 { 01899 // Ensure we put any undo information into the clipboard document, not the selected doc! 01900 pOurDoc = InternalClipboard::Instance(); 01901 01902 // Get a clipboard view to be used during the export 01903 View* OldView = View::GetCurrent(); 01904 ClipboardView *View = new ClipboardView; 01905 if (View == NULL || !View->Init()) 01906 { 01907 if (View != NULL) 01908 delete View; 01909 01910 End(); 01911 return; 01912 } 01913 01914 pOurView = View; 01915 View->SetCurrent(); 01916 01917 #if (_OLE_VER >= 0x200) 01918 01919 // Get the operation parameters and do the export. 01920 OpClipboardExportParams* pprm = (OpClipboardExportParams*) pOpParam->Param1; 01921 01922 // Tell the clipboard which memory to use, or to allocate, and the document. 01923 pprm->pMapping->SetRenderMemory(pprm->hMem, pprm->cbMemSize); 01924 pprm->pMapping->SetDocument(pprm->pDoc); 01925 01926 // Do the export into the memory. Save the memory handle and size into the parameters 01927 // in case HandleExport allocated the memory. 01928 pprm->hMem = pprm->pMapping->HandleExport(this, InternalClipboard::Instance()); 01929 pprm->cbMemSize = ::GlobalSize(pprm->hMem); 01930 01931 #else 01932 01933 // Export the data to the global memory block 01934 ClipboardMapping* pMapping = (ClipboardMapping*) pOpParam->Param1; 01935 HANDLE hData = pMapping->HandleExport(this, InternalClipboard::Instance()); 01936 01937 // And finally, chuck the data (if any) on the external clipboard 01938 if (hData != NULL) ::SetClipboardData(pMapping->ExternalDataType, hData); 01939 01940 #endif 01941 01942 // Restore the old view 01943 pOurView = NULL; 01944 01945 if (OldView != NULL) OldView->SetCurrent(); 01946 delete View; 01947 End(); 01948 } 01949 01950 01951 01952 01953 /******************************************************************************************** 01954 01955 > virtual void OpClipboardExport::Do(OpDescriptor* pOpDesc) 01956 01957 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01958 Created: 31/3/95 01959 Inputs: pOpDesc - the OpDescriptor that called this op 01960 Purpose: Saves the Current Doc as the default document 01961 01962 ********************************************************************************************/ 01963 01964 void OpClipboardExport::Do(OpDescriptor* pOpDesc) 01965 { 01966 ERROR3("Don't invoke OpClipboardExport with Do. I don't like it"); 01967 } 01968 01969 01970 01971 /******************************************************************************************** 01972 01973 > BOOL OpClipboardExport::Init() 01974 01975 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01976 Created: 21/4/95 01977 01978 Returns: TRUE if it worked, FALSE if not 01979 01980 Purpose: Registers our OpDescriptor 01981 01982 ********************************************************************************************/ 01983 01984 BOOL OpClipboardExport::Init() 01985 { 01986 return (RegisterOpDescriptor( 01987 0, 01988 _R(IDS_CLIPBOARD_OPEXPORT), 01989 CC_RUNTIME_CLASS(OpClipboardExport), 01990 OPTOKEN_CLIPBOARDEXPORT, 01991 OpClipboardExport::GetState 01992 )); 01993 } 01994 01995 01996 01997 /******************************************************************************************** 01998 01999 > OpState OpClipboardExport::GetState(String_256*, OpDescriptor*) 02000 02001 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02002 Created: 21/4/95 02003 Purpose: Yet another empty OpState function 02004 02005 ********************************************************************************************/ 02006 02007 OpState OpClipboardExport::GetState(String_256*, OpDescriptor*) 02008 { 02009 OpState Bob; 02010 return Bob; 02011 } 02012 02013 02014 02015 02016 02017 02018 02019 02020 02021 02022 02023 /******************************************************************************************** 02024 02025 > void OpClipboardImport::DoWithParam(OpDescriptor*, OpParam* pOpParam) 02026 02027 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02028 Created: 21/4/95 02029 02030 Inputs: OpDescriptor - Not Used 02031 02032 pOpParam->Param1 - a (ClipboardMapping *) to control the process 02033 pOpParam->Param2 - unused (should be 0) 02034 02035 Purpose: Imports data from the Windows clipboard into the InternalClipboard 02036 document. When it is done, you can tell if it succeeded by checking 02037 InternalClipboard::IsEmpty(FALSE); 02038 02039 ********************************************************************************************/ 02040 02041 void OpClipboardImport::DoWithParam(OpDescriptor*, OpParam* pOpParam) 02042 { 02043 // Remember the selected doc, in case it gets changed later on in the function 02044 Document* pSelDoc = Document::GetSelected(); 02045 02046 if (!ExternalClipboard::GetOwnerWindow()->OpenClipboard()) 02047 { 02048 ERROR3("Couldn't open the clipboard"); 02049 End(); 02050 return; 02051 } 02052 02053 InternalClipboard *ClipboardDoc = InternalClipboard::Instance(); 02054 ClipboardMapping *Mapping = (ClipboardMapping*) pOpParam->Param1; 02055 02056 #if (_OLE_VER >= 0x200) 02057 02058 // If Param2 is not NULL then it is an HGLOBAL extracted from a COleDataObject, in 02059 // ExternalClipboard::PrepareForOlePaste. If it is NULL then we have been called 02060 // from PrepareForPaste and we must extract the handle from the Windows clipboard. 02061 HANDLE hClipData = (HANDLE) (HGLOBAL) pOpParam->Param2; 02062 if (!hClipData) hClipData = ::GetClipboardData(Mapping->RealExternalType); 02063 02064 #else 02065 02066 HANDLE hClipData = ::GetClipboardData(Mapping->RealExternalType); 02067 02068 #endif 02069 02070 // Ensure we put any undo information into the clipboard document, not the selected doc! 02071 pOurDoc = ClipboardDoc; 02072 02073 // Get a new view for use during the import 02074 View* OldView = View::GetCurrent(); 02075 ClipboardView *View = new ClipboardView; 02076 if (View == NULL || !View->Init()) 02077 { 02078 // We failed. Set the data to NULL, and we can drop through the rest of the 02079 // function safely to exit. 02080 hClipData = NULL; 02081 if (View != NULL) 02082 delete View; 02083 } 02084 02085 if (hClipData != NULL) 02086 { 02087 pOurView = View; // Make sure we're using a safe view pointer during import 02088 02089 View->SetCurrent(); 02090 Camelot.UpdateSelection(); 02091 02092 // Import the data onto the Internal Clipboard 02093 Mapping->HandleImport(this, hClipData, ClipboardDoc); 02094 02095 pOurView = NULL; // For safety, as View is about to be deleted 02096 02097 // And restore the previous view 02098 if (OldView != NULL) 02099 OldView->SetCurrent(); 02100 delete View; 02101 } 02102 02103 // Close the windows clipboard 02104 ::CloseClipboard(); 02105 02106 // Restore the selected doc on entry as the selected & current doc 02107 Document::SetSelectedViewAndSpread(pSelDoc); 02108 pSelDoc->SetCurrent(); // This extra call is needed if the doc has no doc views (i.e. it's a clipboard) 02109 02110 // Finished the operation 02111 End(); 02112 } 02113 02114 02115 02116 02117 /******************************************************************************************** 02118 02119 > virtual void OpClipboardImport::Do(OpDescriptor* pOpDesc) 02120 02121 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02122 Created: 31/3/95 02123 Inputs: pOpDesc - the OpDescriptor that called this op 02124 Purpose: Saves the Current Doc as the default document 02125 02126 ********************************************************************************************/ 02127 02128 void OpClipboardImport::Do(OpDescriptor* pOpDesc) 02129 { 02130 ERROR3("Don't invoke OpClipboardImport with Do. I don't like it"); 02131 } 02132 02133 02134 02135 /******************************************************************************************** 02136 02137 > BOOL OpClipboardImport::Init() 02138 02139 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02140 Created: 21/4/95 02141 02142 Returns: TRUE if it worked, FALSE if not 02143 02144 Purpose: Registers our OpDescriptor 02145 02146 ********************************************************************************************/ 02147 02148 BOOL OpClipboardImport::Init() 02149 { 02150 return (RegisterOpDescriptor( 02151 0, 02152 _R(IDS_CLIPBOARD_OPIMPORT), 02153 CC_RUNTIME_CLASS(OpClipboardImport), 02154 OPTOKEN_CLIPBOARDIMPORT, 02155 OpClipboardImport::GetState 02156 )); 02157 } 02158 02159 02160 02161 /******************************************************************************************** 02162 02163 > OpState OpClipboardImport::GetState(String_256*, OpDescriptor*) 02164 02165 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02166 Created: 21/4/95 02167 Purpose: Yet another empty OpState function 02168 02169 ********************************************************************************************/ 02170 02171 OpState OpClipboardImport::GetState(String_256*, OpDescriptor*) 02172 { 02173 OpState Bob; 02174 return Bob; 02175 } 02176 02177 02178 02179 02180 /******************************************************************************************** 02181 > virtual ClipboardView::~ClipboardView() 02182 02183 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02184 Created: 18/9/96 02185 Purpose: Destroys a ClipboardView, deallocating it's associated ViewState. 02186 ********************************************************************************************/ 02187 02188 ClipboardView::~ClipboardView() 02189 { 02190 delete pVState; 02191 pVState = 0; 02192 } 02193 02194 02195 02196 02197 /******************************************************************************************** 02198 02199 > BOOL ClipboardView::Init() 02200 02201 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02202 Created: 022/4/95 02203 02204 Returns: TRUE if initialised ok; 02205 FALSE if not 02206 02207 Purpose: Initialise the ClipboardView for rendering. 02208 02209 ********************************************************************************************/ 02210 02211 BOOL ClipboardView::Init() 02212 { 02213 // Think up a particularly stupid dpi value... 02214 INT32 pixwidth = 150; 02215 INT32 pixheight = 150; 02216 02217 // Set up our pixel size 02218 PixelWidth = FIXED16(72000.0 / pixwidth); 02219 PixelHeight = FIXED16(72000.0 / pixheight); 02220 ScaledPixelWidth = PixelWidth; 02221 ScaledPixelHeight = PixelHeight; 02222 02223 // Get ourselves a ViewState object 02224 pVState = new ViewState; 02225 if (pVState == NULL) 02226 return FALSE; 02227 02228 // Connect this view state to this view 02229 pVState->pView = this; 02230 02231 // Always uses the internal clipboard document 02232 pDoc = InternalClipboard::Instance(); 02233 02234 // All ok 02235 return TRUE; 02236 } 02237 02238 02239 02240 /******************************************************************************************** 02241 02242 > BOOL ClipboardView::ViewStateChanged() 02243 02244 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02245 Created: 22/4/95 02246 Returns: TRUE (always). 02247 Purpose: 02248 02249 ********************************************************************************************/ 02250 02251 BOOL ClipboardView::ViewStateChanged() 02252 { 02253 // Local variables... 02254 DocCoord ExtentLo; // coord of bottom-left of logical extent 02255 DocCoord ExtentHi; // coord of top-right of logical extent 02256 02257 // Read DocCoords extent of document & set extent in platform-indy ViewState struct. 02258 pDoc->GetExtents(&ExtentLo, &ExtentHi, &PhysExtent, this); 02259 SetExtent(ExtentLo, ExtentHi); 02260 02261 return TRUE; 02262 } 02263 02264 02265 02266 /******************************************************************************************** 02267 02268 > void ClipboardView::SetViewPixelSize() 02269 02270 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02271 Created: 22/4/95 02272 Purpose: Sets up the pixel size for this view object. 02273 SeeAlso: ClipboardView 02274 02275 ********************************************************************************************/ 02276 02277 void ClipboardView::SetViewPixelSize() 02278 { 02279 // Set the scaled pixel size 02280 ScaledPixelWidth = PixelWidth / Scale; 02281 ScaledPixelHeight = PixelHeight / Scale; 02282 } 02283 02284 02285 02286 /******************************************************************************************** 02287 02288 > void ClipboardView::ContinueRenderView(RenderRegion*, Spread*, BOOL = TRUE, BOOL = TRUE, 02289 BOOL bForceImmediate = FALSE) 02290 02291 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02292 Created: 22/4/95 02293 Inputs: N/A 02294 Purpose: None - ClipboardView is a skeleton class that is only used to access screen 02295 characteristics. 02296 Errors: Always => ERROR3 02297 02298 ********************************************************************************************/ 02299 02300 void ClipboardView::ContinueRenderView(RenderRegion*, Spread*, BOOL, BOOL, 02301 BOOL bForceImmediate) 02302 { 02303 ERROR3("ClipboardView::ContinueRenderView() should not be called!"); 02304 } 02305 02306 02307 02308 /******************************************************************************************** 02309 02310 > CDC *ClipboardView::GetRenderDC() 02311 02312 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02313 Created: 22/4/95 02314 Returns: NULL (always) 02315 Purpose: None - ClipboardView is a skeleton class that is only used to access screen 02316 characteristics. 02317 02318 ********************************************************************************************/ 02319 02320 CDC *ClipboardView::GetRenderDC() 02321 { 02322 return NULL; 02323 } 02324 02325 02326 02327 /******************************************************************************************** 02328 02329 > BOOL ClipboardView::GetForeBackMode() 02330 02331 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02332 Created: 22/4/95 02333 Returns: FALSE - dialogs don't do background rendering. 02334 Purpose: None - ClipboardView is a skeleton class that is only used to access screen 02335 characteristics. 02336 02337 ********************************************************************************************/ 02338 02339 BOOL ClipboardView::GetForeBackMode() 02340 { 02341 // ClipboardViews don't background render. 02342 return FALSE; 02343 } 02344 02345 02346 02347 /******************************************************************************************** 02348 02349 > void ClipboardView::SetForeBackMode(BOOL) 02350 02351 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02352 Created: 22/4/95 02353 Inputs: N/A 02354 Purpose: None - ClipboardView is a skeleton class that is only used to access screen 02355 characteristics. 02356 Errors: ERROR3 always - dialogs cannot background render! 02357 SeeAlso: ClipboardView 02358 02359 ********************************************************************************************/ 02360 02361 void ClipboardView::SetForeBackMode(BOOL) 02362 { 02363 ERROR3("ClipboardView::SetForeBackMode() should not be called!"); 02364 } 02365 02366 02367 02368 /******************************************************************************************** 02369 02370 > DocRect ClipboardView::GetDocViewRect(Spread*) 02371 02372 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02373 Created: 22/4/95 02374 Inputs: N/A 02375 Returns: The bounds of the objects in the InternalClipboard 02376 Purpose: To determine the docrect area that this view is viewing 02377 02378 ********************************************************************************************/ 02379 02380 DocRect ClipboardView::GetDocViewRect(Spread*) 02381 { 02382 return InternalClipboard::GetObjectsBounds(); 02383 } 02384 02385 02386 02387 /******************************************************************************************** 02388 02389 > void ClipboardView::SetExtent(DocCoord, DocCoord) 02390 02391 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02392 Created: 22/4/95 02393 Inputs: Two DocCoords describing the low and high corners of a rectangle in logical 02394 space describing the full extent of the document. I.E. the bottom-left corner 02395 of the last chapter and the top-right corner of the first. 02396 Purpose: Informs the DocView that the extent of the document has changed in some way and 02397 that the view must be altered to take this into account (namely the 02398 scrollbars). 02399 SeeAlso: ClipboardView 02400 02401 ********************************************************************************************/ 02402 02403 void ClipboardView::SetExtent(DocCoord lolog, DocCoord hilog) 02404 { 02405 // Convert the extent given in DocCoord to WorkCoords... 02406 pVState->WorkAreaExtent.lo = lolog.ToWork(pDoc, this); 02407 pVState->WorkAreaExtent.hi = hilog.ToWork(pDoc, this); 02408 } 02409 02410 02411 02412 /******************************************************************************************** 02413 02414 > WorkRect ClipboardView::GetViewRect() 02415 02416 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copying Tim code) 02417 Created: 22/4/95 02418 Returns: An empty rectangle (always). 02419 Purpose: None - ClipboardView is a skeleton class that is only used to access screen 02420 characteristics. 02421 02422 ********************************************************************************************/ 02423 02424 WorkRect ClipboardView::GetViewRect() 02425 { 02426 WorkRect Empty; 02427 return Empty; 02428 } 02429 02430 02431 02432 02433 02434 02435 02436 02437 02438 02439 02440 const INT32 PasteSpecialDlg::IDD = _R(IDD_CAM_PASTESPECIAL); 02441 const CDlgMode PasteSpecialDlg::Mode = MODAL; 02442 02443 /******************************************************************************************** 02444 02445 > PasteSpecialDlg::PasteSpecialDlg(): DialogOp(PasteSpecialDlg::IDD, PasteSpecialDlg::Mode) 02446 02447 02448 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02449 Created: 1/4/95 02450 02451 Purpose: PasteSpecialDlg constructor. 02452 02453 ********************************************************************************************/ 02454 02455 PasteSpecialDlg::PasteSpecialDlg() : DialogOp(PasteSpecialDlg::IDD, PasteSpecialDlg::Mode) 02456 { 02457 } 02458 02459 02460 02461 /******************************************************************************************** 02462 02463 > MsgResult PasteSpecialDlg::Message( CDlgMessage DlgMsg, CGadgetID Gadget) 02464 02465 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02466 Created: 1/4/95 02467 Inputs: - 02468 Outputs: - 02469 Returns: - 02470 Purpose: Handles all the dialog's messages 02471 Errors: - 02472 SeeAlso: - 02473 02474 ********************************************************************************************/ 02475 02476 MsgResult PasteSpecialDlg::Message(Msg* Message) 02477 { 02478 BOOL CloseDlg = FALSE; 02479 02480 if (IS_OUR_DIALOG_MSG(Message)) 02481 { 02482 DialogMsg* Msg = (DialogMsg*)Message; 02483 02484 switch (Msg->DlgMsg) 02485 { 02486 case DIM_CREATE: 02487 { 02488 INT32 Index = 0; 02489 UINT32 ThisFormat = 0; 02490 BOOL HaveTextAlready = FALSE; 02491 do 02492 { 02493 ThisFormat = EnumClipboardFormats(ThisFormat); 02494 if (ThisFormat != 0 && ExternalClipboard::CanImport(ThisFormat)) 02495 { 02496 BOOL AddToList = TRUE; 02497 if (ThisFormat == CF_TEXT || ThisFormat == CF_OEMTEXT || ThisFormat == CF_UNICODETEXT) 02498 { 02499 if (HaveTextAlready) 02500 AddToList = FALSE; 02501 02502 HaveTextAlready = TRUE; 02503 } 02504 02505 if (AddToList) 02506 { 02507 String_64 name; 02508 ExternalClipboard::GetExternalFormatName(ThisFormat, &name); 02509 SetStringGadgetValue(_R(IDC_PASTESPECIAL_LIST), (StringBase *) &name, FALSE, Index); 02510 Index++; 02511 } 02512 } 02513 } while (ThisFormat != 0); 02514 02515 SetSelectedValueIndex(_R(IDC_PASTESPECIAL_LIST), 0); 02516 } 02517 break; 02518 02519 02520 case DIM_SELECTION_CHANGED_COMMIT: 02521 // Assume it was the listbox! 02522 case DIM_COMMIT: 02523 case DIM_SOFT_COMMIT: 02524 { 02525 pParam->Param1 = 0; // Safe default 02526 02527 INT32 Index = GetSelectedValueIndex(_R(IDC_PASTESPECIAL_LIST)); 02528 02529 BOOL HaveTextAlready = FALSE; 02530 UINT32 ThisFormat = 0; 02531 do 02532 { 02533 ThisFormat = EnumClipboardFormats(ThisFormat); 02534 if (ThisFormat != 0 && ExternalClipboard::CanImport(ThisFormat)) 02535 { 02536 BOOL IsInList = TRUE; 02537 if (ThisFormat == CF_TEXT || ThisFormat == CF_OEMTEXT || ThisFormat == CF_UNICODETEXT) 02538 { 02539 if (HaveTextAlready) 02540 IsInList = FALSE; 02541 02542 HaveTextAlready = TRUE; 02543 } 02544 02545 if (IsInList) 02546 { 02547 Index--; 02548 if (Index < 0) 02549 { 02550 pParam->Param1 = ThisFormat; 02551 break; 02552 } 02553 } 02554 } 02555 } while (ThisFormat != 0); 02556 } 02557 02558 CloseDlg = TRUE; 02559 break; 02560 02561 case DIM_CANCEL: 02562 pParam->Param1 = 0; 02563 CloseDlg = TRUE; 02564 break; 02565 } 02566 } 02567 02568 // Call down to the base class to automatically handle help, etc 02569 MsgResult Result = DialogOp::Message(Message); 02570 02571 if (CloseDlg) 02572 { 02573 Close(); 02574 End(); 02575 } 02576 02577 return(Result); 02578 } 02579 02580 02581 02582 /******************************************************************************************** 02583 02584 > OpState PasteSpecialDlg::GetState(String_256*, OpDescriptor*) 02585 02586 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02587 Created: 1/4/95 02588 Purpose: PasteSpecialDlg GetState method 02589 02590 ********************************************************************************************/ 02591 02592 OpState PasteSpecialDlg::GetState(String_256*, OpDescriptor*) 02593 { 02594 OpState OpSt; 02595 return(OpSt); 02596 } 02597 02598 02599 02600 /******************************************************************************************** 02601 02602 > BOOL PasteSpecialDlg::Init(void) 02603 02604 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02605 Created: 1/4/95 02606 02607 Purpose: PasteSpecialDlg Init method. Called by sginit.cpp 02608 02609 ********************************************************************************************/ 02610 02611 BOOL PasteSpecialDlg::Init(void) 02612 { 02613 return (RegisterOpDescriptor( 02614 0, 02615 _R(IDS_PASTESPECIALDLG), 02616 CC_RUNTIME_CLASS(PasteSpecialDlg), 02617 OPTOKEN_PASTESPECIALDLG, 02618 PasteSpecialDlg::GetState, 02619 _R(IDST_PASTESPECIALDLG), 02620 _R(IDBBL_PASTESPECIALDLG) 02621 ) 02622 ); 02623 } 02624 02625 02626 02627 /******************************************************************************************** 02628 02629 > BOOL PasteSpecialDlg::Create() 02630 02631 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02632 Created: 1/4/95 02633 Returns: TRUE if successful, else FALSE 02634 Purpose: PasteSpecialDlg create method 02635 02636 ********************************************************************************************/ 02637 02638 BOOL PasteSpecialDlg::Create() 02639 { 02640 return(DialogOp::Create()); 02641 } 02642 02643 02644 02645 /******************************************************************************************** 02646 02647 > void PasteSpecialDlg::DoWithParam(OpDescriptor*,OpParam* pOpParam) 02648 02649 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02650 Created: 1/4/95 02651 Inputs: pOpParam points to a structure to recieve the return result 02652 pOpParam->Param1 will contain the result on return 02653 02654 Purpose: Creates then opens the dialog 02655 02656 ********************************************************************************************/ 02657 02658 void PasteSpecialDlg::DoWithParam(OpDescriptor*, OpParam* pOpParam) 02659 { 02660 ERROR3IF(pOpParam == NULL, "Come on, play by the rules"); 02661 pParam = pOpParam; 02662 pParam->Param1 = 0; // Set a safe default return result 02663 02664 if (!Create()) 02665 { 02666 InformError(); 02667 End(); 02668 } 02669 } 02670 02671 02672 02673 /******************************************************************************************** 02674 02675 > UINT32 PasteSpecialDlg::InvokeDialog(void) 02676 02677 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02678 Created: 1/4/95 02679 02680 Returns: The Windows clipboard format chosen, or 0 to cancel 02681 02682 Purpose: Opens the paste special dialogue on screen, elicits a response, 02683 and returns having chosen the format to paste. This is a MODAL Dlg. 02684 02685 ********************************************************************************************/ 02686 02687 UINT32 PasteSpecialDlg::InvokeDialog(void) 02688 { 02689 OpParam Info(0, 0); 02690 OpDescriptor *PSDlg = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(PasteSpecialDlg)); 02691 02692 ERROR3IF(PSDlg == NULL, 02693 "PasteSpecialDlg::InvokeDialog is unable to find the Dlg OpDescriptor"); 02694 02695 if (PSDlg != NULL) 02696 PSDlg->Invoke(&Info); 02697 02698 return(Info.Param1); 02699 } 02700 02701 02702 02703 02704 /******************************************************************************************** 02705 02706 > static ExternalClipboard* ExternalClipboard::LinkTempClipboard() 02707 02708 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02709 Created: 27/9/96 02710 Inputs: - 02711 Outputs: - 02712 Returns: 02713 Purpose: Create a new temporary clipboard document and point the statics at it. 02714 02715 ********************************************************************************************/ 02716 02717 ExternalClipboard* ExternalClipboard::LinkTempClipboard() 02718 { 02719 // TODO: Make new internal and external clipboard objects 02720 // BODGE: Just use the existing clipboards 02721 return(ExternalClipboard::pInstance); 02722 } 02723 02724 02725 02726 02727 /******************************************************************************************** 02728 02729 > BOOL ExternalClipboard::UnlinkTempClipboard() 02730 02731 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02732 Created: 27/9/96 02733 Inputs: - 02734 Outputs: - 02735 Returns: 02736 Purpose: Delete the temporary clipboard and return any static pointers to normal 02737 02738 ********************************************************************************************/ 02739 02740 BOOL ExternalClipboard::UnlinkTempClipboard() 02741 { 02742 return TRUE; 02743 }