scrcamvw.cpp

Go to the documentation of this file.
00001 // $Id: scrcamvw.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 
00099 // The ScreenCamView class - subclass of ScreenView used for screen display.
00100 
00101 /*
00102 */
00103 
00104 #include "camtypes.h"
00105 
00106 
00107 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 #include "scrcamvw.h"
00109 #include "scrvw.h"
00110 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 #include "camelot.h"
00112 #include "camdoc.h"
00113 //#include "ccmdikid.h"
00114 #include "vstate.h"
00115 #include "rendwnd.h"
00116 //#include "scroller.h"
00117 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00118 //#include "ops.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00119 //#include "oiltool.h"
00120 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00121 //#include "justin.h"
00122 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00123 #include "ccdc.h"
00124 #include "csrstack.h"
00125 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00126 //#include "mainfrm.h"
00127 //#include "oilkeys.h"
00128 //#include "monotime.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00129 #include "pen.h"
00130 //#include "bars.h"
00131 #include "impexpop.h"   // Import/Export ops
00132 //#include "resource.h"
00133 #include "statline.h"
00134 #include "prntview.h"
00135 //#include "prncamvw.h"
00136 #include "page.h"
00137 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00138 //#include "dragmgr.h"
00139 //#include "dragcol.h"
00140 //#include "viewrc.h"
00141 //#include "printdlg.h"
00142 //#include "prdlgctl.h"
00143 #include "princomp.h"
00144 #include "printctl.h"
00145 #include "psrndrgn.h"
00146 //#include "markn.h"
00147 //#include "oilruler.h"
00148 //#include "rulers.h"
00149 #include "keypress.h"
00150 //#include "localenv.h"
00151 //#include "tool.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00152 
00153 #include "cutop.h"
00154 #include "insertnd.h"
00155 
00156 #include "clipint.h"
00157 //#include "clipext.h"
00158 //#include "srvritem.h"
00159 //#include "oleprefs.h"
00160 #include "cutop.h"
00161 #include "selector.h"
00162 //#include "justin3.h"
00163 
00164 #include "osrndrgn.h"
00165 
00166 #if (_OLE_VER >= 0x200)
00167   // Extra OLE 2.0 stuff in MFC 2.5
00168   #include "cntritem.h"
00169   #include "ole2id.h"
00170 #endif
00171 
00172 DECLARE_SOURCE("$Revision: 1282 $");
00173 
00175 // ScreenCamCanvas the message map.
00176 
00177 BEGIN_EVENT_TABLE( ScreenCamView::ScreenCamCanvas, ScreenView::ScreenCanvas )
00178     EVT_SIZE(           ScreenCamView::ScreenCamCanvas::OnSize )
00179 END_EVENT_TABLE()
00180 
00181 ReflectIntoView( ScreenCamView::ScreenCamCanvas, ScreenCamView, OnSize,     wxSizeEvent )
00182 
00184 // ScreenCamView serialization & the message map.
00185 
00186 IMPLEMENT_DYNAMIC_CLASS( ScreenCamView, ScreenView )
00187 
00188 BEGIN_EVENT_TABLE( ScreenCamView, ScreenView )
00189 END_EVENT_TABLE()
00190 
00191 /*********************************************************************************************
00192 >   afx_msg INT32 ScreenCamView::OnCreate(LPCREATESTRUCT lpCreateStruct)
00193 
00194     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00195     Created:    ages ago
00196     Inputs:     A long pointer to a Windows CREATESTRUCT object.
00197     Outputs:    Calling the base class handler may change the CREATESTRUCT pointed to . . . ?
00198     Returns:    0 for success, -1 for failure.
00199     Purpose:    Called upon receipt of a WM_CREATE message for the view window.  Constructs
00200                 MFC/C++ surrogates on the heap, then tries to link up with Windows by
00201                 calling the base class function OnCreate() and the Create function for
00202                 each of the child windows of ScreenView, any or all of which can fail.
00203                 Calculates the size of a pixel and sets the appropriate fields
00204                 in the ViewState.  If this is a new view upon a new document
00205                 the rest of the fields of the ViewState are filled by the
00206                 default characteristics of the ScreenView.  If the document is
00207                 not new then the ScreenView assumes that the kernel has already
00208                 set up the ViewState, and changes its size, position etc to
00209                 fit.                
00210     Errors:     _R(IDE_CREATEVIEWFAILED) if either the C++ or Windows side of construction
00211                 fails.  Note that if the function does fail then MFC is responsible for
00212                 tidying up afterwards.
00213     Scope:      Protected
00214     SeeAlso:    ScreenView::ScreenView(); ScreenView::Create() CView::OnCreate()
00215 
00216 **********************************************************************************************/ 
00217 
00218 bool ScreenCamView::OnCreate( wxDocument* doc, /* TYPENOTE: Correct */ long flags )
00219 {
00220     // Construct the (C++) child windows.
00221 PORTNOTE("other","ScreenCamView::OnCreate - Removed scroller / ruler usage")
00222 #ifndef EXCLUDE_FROM_XARALX
00223     RenderWindow = new CRenderWnd;
00224 
00225     HScrollBar = new CWinScroller(TRUE);
00226     VScrollBar = new CWinScroller(FALSE);
00227     Corner = new CScrollerCorner;
00228 // WEBSTER - markn 15/1/97
00229 // No rulers in Webster
00230 #ifndef WEBSTER
00231     HRuler = new OILHorizontalRuler;
00232     VRuler = new OILVerticalRuler;
00233     OGadget = new OriginGadget;
00234 #endif //webster    
00235     if (!RenderWindow || !HScrollBar || !VScrollBar || !Corner 
00236 #ifndef WEBSTER
00237         ||!HRuler ||!VRuler ||!OGadget
00238 #endif //webster
00239         )
00240     {
00241         Error::SetError(_R(IDE_CREATE_VIEW_FAILED), 0);
00242         InformError();
00243         return -1;
00244     } 
00245 #endif
00246     // Get base class to call CView functions, and get a document for this view.
00247     if( !CCamView::OnCreate( doc, flags ) )
00248         // Something went wrong - pass error back.
00249         return false;
00250 
00251 PORTNOTE("other","ScreenCamView::OnCreate - Removed scroller usage")
00252     // Now get Windows to do its side of the construction.  The stated sizes and
00253     // positions of the windows here will be changed very soon.
00254 #ifndef EXCLUDE_FROM_XARALX
00255     const CRect rcARect(-100,-100,-90,-90);
00256     if (!RenderWindow->Create("", "", 0, rcARect, this, 1) ||
00257         !HScrollBar->Create(0, rcARect, this, 2) ||
00258         !VScrollBar->Create(0, rcARect, this, 3) ||
00259         !Corner->Create("", "", 0, rcARect, this, 4)
00260 // WEBSTER - markn 15/1/97
00261 // No rulers in Webster
00262 #ifndef WEBSTER
00263         || !OGadget->Create(this)
00264         || !HRuler->Create(this)
00265         || !VRuler->Create(this)
00266 #endif //webster
00267         )
00268     {
00269         Error::SetError(_R(IDE_CREATE_VIEW_FAILED), 0);
00270         InformError();
00271         return -1;
00272     }
00273 #endif
00274     CreateNewDocView();
00275 
00276 // WEBSTER - markn 15/1/97
00277 // No rulers in Webster
00278 #ifndef WEBSTER
00279 
00280     // init the kernel rulers and establish pointer links to them
00281 PORTNOTE("other","ScreenCamView::OnCreate - Removed ruler usage")
00282 #ifndef EXCLUDE_FROM_XARALX
00283     RulerPair* pRulers=pDocView->GetpRulerPair();
00284     pRulers->Init(pDocView,HRuler,VRuler,OGadget);
00285     HRuler->LinkToKernel(pRulers->GetpHorizontalRuler());
00286     VRuler->LinkToKernel(pRulers->GetpVerticalRuler());
00287 #endif
00288 #endif //webster
00289     ENSURE(pDocView != 0, "ScreenView::ScreenView can't get a new DocView!");
00290     pDocView->ConnectToOilView(this);
00291     
00292     // find the last view so we can use some of it's settings to create the new
00293 //  DocView * LastView = DocView::GetSelected();
00294 
00295     // Link this and the DocView to the ViewState object.
00296     pDocView->SetViewState(Status);
00297 
00299     
00300     wxScreenDC dc;
00301     wxSize pixsize=OSRenderRegion::GetFixedDCPPI(dc);
00302 
00303 PORTNOTE("other","ScreenCamView::OnCreate - Removed scroller usage")
00304 #ifndef EXCLUDE_FROM_XARALX
00305     // Set the logical pixel size accordingly (measured in millipoints).  Take the
00306     // opportunity to pass the values into the scrollers and the OIL -> Windows coordinate
00307     // transform system.
00308     HScrollBar->SetGranularity(72000L / pixwidth);
00309     VScrollBar->SetGranularity(72000L / pixheight);
00310 #endif
00311 
00312     // Tell DocView how big the pixel size is.
00313     FIXED16 PixelWidth  = FIXED16(72000.0/pixsize.x);
00314     FIXED16 PixelHeight = FIXED16(72000.0/pixsize.y);
00315     ERROR3IF(PixelWidth != PixelHeight, "Luke says non-square pixels are not supported");
00316     pDocView->SetPixelSize(PixelWidth, PixelHeight);
00317 
00318     // Make our DocView the current DocView
00319     pDocView->SetCurrent();
00320 
00321     GetCanvas()->SetScrollRate(1,1);
00322 
00323     if (GetFrame())
00324         GetFrame()->GetClientSize(&CurrentSize.width,&CurrentSize.height);
00325     // Now the scrollers have all their information, we can set their appearance.
00326     // Make sure that they are invisible until the rest of the frame is ready
00327 /*  XLONG x1 = CurrentSize.GetWidth () * PixelWidth;
00328     XLONG x2 = CurrentSize.GetHeight() * PixelHeight;
00329     GetFrame()->SetScrollbar(wxHORIZONTAL,0,x1,Status->WorkAreaExtent.hi.x-Status->WorkAreaExtent.lo.x,false);
00330     GetFrame()->SetScrollbar(  wxVERTICAL,0,x2,Status->WorkAreaExtent.hi.y-Status->WorkAreaExtent.lo.y,false);
00331 */
00332     SetScrollerStyle(ScrollerStyle = PropScrollersOn);
00333     
00334     ShowScrollers(DefaultScrollersState);
00335     ShowRulers(DefaultRulersState);
00336 
00338     
00339     // Register for WM_DROPFILES messages
00340 //  DragAcceptFiles(TRUE);
00341 
00342 // WEBSTER - markn 12/2/97  
00343 #if (_OLE_VER >= 0x200)
00344     // Register with OLE as a drop target.
00345     m_DropTarget.Register(this);
00346 #endif
00347 
00349 
00350     // now that the ScreenView (and hence DocView) is stable, broadcast a message to let everyone know
00351     BROADCAST_TO_ALL(DocViewMsg(pDocView,DocViewMsg::NEWANDSTABLE));
00352 
00353 // ****************** BODGE **************************
00354 // This code will tell windows to send us messages when
00355 // the joystick gets waggled about.
00356 // We should really release the joystick at some point later,
00357 // but it gets released automatically when this ScreenView is
00358 // destroyed, so it will do for now.
00359 
00360 // The messages get passed to 'OnJoystickMove' member of this
00361 // class.
00362     
00363 #ifdef WIN32
00364 
00365 PORTNOTE("other","ScreenCamView::OnCreate - Removed joystick usage")
00366 #ifndef EXCLUDE_FROM_XARALX
00367     JOYINFO joyinfo;
00368     UINT32 wNumDevs, wDeviceID;
00369     BOOL bDev1Attached, bDev2Attached;
00370 
00371     // Are there any Joysticks available ?
00372     if((wNumDevs = joyGetNumDevs()) == 0)
00373         return 0;   // Nope.
00374 
00375     // Are there One or Two of them ?
00376     bDev1Attached = joyGetPos(JOYSTICKID1,&joyinfo) != JOYERR_UNPLUGGED;
00377     bDev2Attached = wNumDevs == 2 &&
00378                      joyGetPos(JOYSTICKID2,&joyinfo) != JOYERR_UNPLUGGED;
00379 
00380     if(bDev1Attached || bDev2Attached)      // Decide which joystick to use
00381         wDeviceID = bDev1Attached ? JOYSTICKID1 : JOYSTICKID2;
00382     else
00383         return 0;
00384 
00385     // Grab those Messages !!
00386     MMRESULT JoyResult = joySetCapture(m_hWnd, wDeviceID, NULL, TRUE);
00387 #endif
00388 
00389 #endif
00390 
00391 // ****************** BODGE **************************
00392 
00393     // Return success!
00394     return true;
00395 }
00396 
00397 /*********************************************************************************************
00398 >   afx_msg void ScreenCamView::OnSize(UINT32 nType, INT32 cx, INT32 cy)
00399 
00400     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
00401     Created:    ages ago
00402     Inputs:     A flag indicating whether the window is maximised, minimised
00403                 etc., the width and height of the ScreenView client area.
00404     Outputs:    -
00405     Returns:    -
00406     Purpose:    Resizes and repositions all child windows to fit the new size
00407                 of the ScreenView.  Updates the ViewState object with the
00408                 size and position of the view, in an OS-independent manner.
00409                 Resets the scroller's page and line size, and forces an
00410                 immediate redraw of all affected windows.
00411     Errors:     -
00412     Scope:      Protected
00413     SeeAlso:    CScroller::CalcPosFromParentClient(); CScroller::SetPageSize();
00414                 CScroller::SetLineSize(); class CRendWnd; class CScrollerCorner;
00415                 struct ViewState; DocView::ViewStateChanged()
00416 
00417 
00418 **********************************************************************************************/ 
00419 
00420 void ScreenCamView::OnSize( wxSizeEvent &event )
00421 {
00422     // This is called early, so if pDocView is null do nothing
00423     if( NULL == pDocView )
00424         return;
00425 
00426     SetCurrentStates();
00427 
00428     Document* pCurDoc = Document::GetCurrent();
00429     DocView* pCurView = DocView::GetCurrent();
00430     
00431     // these lines are here to stop very strange things happening on exit under Win32s
00432     // when this fn gets called when it really shouldn't. I would like to really know
00433     // just what on earth os going on under Win32s but it iss something strange in message
00434     // handling as far as I can tell.
00435 
00436     wxSize  size( event.GetSize() );
00437 
00438     // Check for irrelevant or potty messages.
00439     if (size.x <= 0 || size.y <= 0)
00440     {
00441 //      TRACEUSER( "JustinF", _T("Strange size msg in ScreenView::OnSize(0x%X, %d, %d)\n"), 
00442 //                  nType, cx, cy);
00443         return;
00444     }
00445 
00446     // Handle OLE 2.0 in-place activation stuff.
00447 #if (_OLE_VER >= 0x200)
00448     if(GetDocument())
00449     {
00450         COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
00451         if (pActiveItem) pActiveItem->SetItemRects();
00452     }   
00453 #endif
00454 
00455     if (Status->ScrollersVisible)
00456     {
00457 PORTNOTETRACE( "other", "ScreenCamView::OnSize - Removed scroller usage" );
00458 #if !defined(EXCLUDE_FROM_XARALX)
00459         // Resize and reposition the proportional scrollers.
00460         wxRect hrect, vrect;
00461         HScrollBar->CalcPosFromParentClient(&hrect);
00462 
00463         UINT32 RulerWidth = OILRuler::GetWidth();
00464         //if rulers are switched on the scroll bars are made
00465         // smaller to accomodate them
00466         if (Status->RulersVisible)
00467             hrect.left += RulerWidth;
00468         if (RULER_BORDERS)
00469             hrect.left-=2;
00470 
00471         HScrollBar->MoveWindow(&hrect, TRUE);
00472         VScrollBar->CalcPosFromParentClient(&vrect);
00473 
00474         if (Status->RulersVisible)
00475             vrect.top += RulerWidth;
00476         if (RULER_BORDERS)
00477             vrect.top-=2;
00478 
00479         VScrollBar->MoveWindow(&vrect, TRUE);
00480 
00481         // Reposition the corner window at the bottom-right.
00482         Corner->MoveWindow(vrect.left, hrect.top, vrect.Width(), hrect.Height());
00483      
00484         // Resize/reposition the rendering window.
00485         CurrentSize.left = CurrentSize.top = 0;
00486         CurrentSize.right = cx - vrect.Width() + 1;
00487         CurrentSize.bottom = cy - hrect.Height() + 1;
00488 #endif
00489     }
00490     else
00491     {   
00492         CurrentSize.x = CurrentSize.y = 0;
00493         CurrentSize.width  = size.x;
00494         CurrentSize.height = size.y;
00495     }
00496 
00497     if (Status->RulersVisible)
00498     {
00499 PORTNOTETRACE( "other", "ScreenCamView::OnSize - Removed scroller / ruler usage" );
00500 #if !defined(EXCLUDE_FROM_XARALX)
00501         wxRect hRect, vRect, oRect;
00502 
00503         HRuler->CalcPosFromParentClient(&hRect);
00504         HRuler->MoveWindow(&hRect, TRUE);
00505         HRuler->PositionLegend();
00506         
00507         CurrentSize.top = 0 + hRect.Height() ;
00508             
00509         VRuler->CalcPosFromParentClient(&vRect);
00510         VRuler->MoveWindow(&vRect, TRUE);
00511         CurrentSize.left = 0 + vRect.Width(); 
00512 
00513         OGadget->CalcPosFromParentClient(&oRect);
00514         OGadget->MoveWindow(&oRect, TRUE);
00515         if (RULER_BORDERS)
00516         {
00517             CurrentSize.top --;
00518             CurrentSize.left--; 
00519         }
00520 #endif
00521     }
00522 
00523 PORTNOTE( "other", "ScreenCamView::OnSize - Removed RenderWindow usage -not sure if needed" )
00524 #ifndef EXCLUDE_FROM_XARALX
00525     RenderWindow->MoveWindow(&CurrentSize, TRUE);
00526 #endif
00527     // Update the rest of the window placement information.
00528     UpdateViewPosition();
00529 
00530     // Calculate the work area, page & line sizes etc etc.
00531     FIXED16 PixelWidth, PixelHeight;
00532     pDocView->GetPixelSize(&PixelWidth, &PixelHeight);
00533 
00534 PORTNOTE( "other", "ScreenCamView::OnSize - Removed scroller usage" )
00535 #if !defined(EXCLUDE_FROM_XARALX)
00536     XLONG x1 = CurrentSize.GetWidth() * PixelWidth;
00537     XLONG x2 = CurrentSize.GetHeight() * PixelHeight;
00538     HScrollBar->SetPageSize(x1);
00539     VScrollBar->SetPageSize(x2);
00540     HScrollBar->SetLineSize(x1 / xlong(10) + xlong(1)); 
00541     VScrollBar->SetLineSize(x2 / xlong(10) + xlong(1));
00542 #endif
00543     SetWorkAreaExtent(Status->WorkAreaExtent, FALSE);
00544 
00545     // Make sure the scroll offsets are valid - if we resize the bottom of the window
00546     // when at the extreme bottom of the view, then the scroll offsets should be
00547     // changed - we use the scrollers' own integrity checks to do this automatically.
00548     // Don't do this until the setup flag is TRUE, so we don't overwrite scroll offsets
00549     // that have been reloaded.
00550     if (fSetupDone)
00551     {
00552         WorkCoord CurrScrollPos;
00553         GetScrollOffset(&CurrScrollPos);
00554         SetScrollOffset(CurrScrollPos, TRUE);
00555     }   
00556 
00557     // Inform the associated DocView object that something has happened.
00558     pDocView->ViewStateChanged();
00559     pCurDoc->SetCurrent();
00560     pCurView->SetCurrent();
00561 }
00562 
00563 #if (_OLE_VER >= 0x200)
00564 
00565 /*********************************************************************************************
00566 >   BOOL ScreenCamView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
00567 
00568     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00569     Created:    26/9/96
00570     Inputs:     pDataObject     Pointer to ColeDataObject
00571                 dropEffect      Copy, Move or Link
00572                 point           The drop position
00573     Outputs:    -
00574     Returns:    -
00575     Purpose:    Respond to OLE drop on a ScreenCamView
00576     Errors:     -
00577     Scope:      Public
00578 **********************************************************************************************/ 
00579 
00580 BOOL ScreenCamView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
00581 {
00582     if (!m_DropFormatOK || pDataObject == NULL)
00583         return FALSE;
00584 
00585 //  Document* pSelDoc = Document::GetSelected();
00586 
00587     Document* pClipDoc = InternalClipboard::Instance();
00588     if (pClipDoc != NULL)
00589     {
00590         Document::SetSelectedViewAndSpread(pClipDoc);
00591         pClipDoc->ResetInsertionPosition();
00592         pClipDoc->SetCurrent();
00593 
00594         // If there is *still* a format on the external clip board we like, then it's ok to drop
00595         CLIPFORMAT ClipFormat = ExternalClipboard::GetBestPasteFormat(pDataObject);
00596         ExternalClipboard* pExtClipBoard = ExternalClipboard::GetExternalClipboard();
00597 
00598         if (ClipFormat != 0 && pExtClipBoard !=NULL && pExtClipBoard->PrepareForOlePaste(pDataObject))
00599         {
00600             Document::SetSelectedViewAndSpread(GetDocument()->GetKernelDoc(),GetDocViewPtr());
00601             DocView *pDocView = DocView::GetCurrent();
00602 
00603             if (pDocView != NULL)
00604             {
00605                 // Make the drop point a WinCoord so we can turn it into an oil coord
00606                 WinCoord DropPoint(point.x,point.y);
00607 
00608                 // Turn it into Oil coordinates...
00609                 OilCoord OilPos = DropPoint.ToOil(pDocView);
00610 
00611                 // Find the spread that contains the coord
00612                 Spread* pSpread = pDocView->FindEnclosingSpread(OilPos);
00613                 if (pSpread != NULL)
00614                 {
00615                     // First of all convert the OilCoord into device coords
00616                     DocCoord Centre = OilPos.ToDoc(pSpread, pDocView);
00617                 
00618                     // Translate the coord to spread coords
00619                     pSpread->DocCoordToSpreadCoord(&Centre);
00620 
00621                     // 'Centre' now contains the centre point for the paste, in spread coords
00622 
00623                     TRY
00624                     {
00625                         // Wrap all this in a TRY/CATCH block so that if OLE throws a wobbly, we can
00626                         // ensure that the clipboard remains intacted on exit.
00627 
00628                         // Copy the selection to the drag'n'drop clipboard.
00629                         OpDescriptor* pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_PASTE);
00630                         ERROR3IF(!pOp, "No paste operation in ScreenCamView::OnDrop");
00631 
00632                         if (pOp != NULL)
00633                         {
00634                             Document::SetSelectedViewAndSpread(pClipDoc);
00635                             pClipDoc->SetCurrent();
00636                             pClipDoc->ResetInsertionPosition();
00637                             InsertionNode* pInsertNode = pClipDoc->GetInsertionPosition();
00638                             if (pInsertNode != NULL)
00639                             {
00640                                 pInsertNode->UnlinkNodeFromTree();
00641                                 delete pInsertNode;
00642                                 pInsertNode = NULL;
00643                             }
00644 
00645                             Document::SetSelectedViewAndSpread(GetDocument()->GetKernelDoc(),GetDocViewPtr());
00646                             
00647                             // create a param object that contains the centre point in the spread at which
00648                             // we would like the objects to be pasted
00649                             OpParamPasteAtPosition Param(pSpread,Centre);
00650 
00651                             // Call the paste op via its DoWithParams() funtion
00652                             pOp->Invoke(&Param);
00653                         }
00654                     }
00655                     CATCH_ALL(e)
00656                     {
00657                         if (m_ClipBoardSwapped = FALSE)
00658                         {
00659 //                          TRACEUSER( "Markn", _T("Swapping back to clipboard doc (Catch in ScreenCamView::OnDrop())\n"));
00660                             InternalClipboard::Swap();
00661                             ExternalClipboard::UpdateSystemClipboard(TRUE);
00662                         }
00663                         THROW_LAST();
00664                     }
00665                     END_CATCH_ALL
00666                 }
00667             }
00668         }
00669     }
00670 
00671     // Tidy up any data which was stored when the mouse entered the view...
00672     OnDragLeave();
00673 
00674     Document::SetSelectedViewAndSpread(GetDocument()->GetKernelDoc(),GetDocViewPtr());
00675     ((CMDIChildWnd*)GetParentFrame())->MDIActivate();
00676 
00677 //  GetParentFrame()->GetParent()->PostMessage(WM_MDIACTIVATE, (WPARAM) GetParentFrame()->GetSafeHwnd());
00678 
00679     if (CCamSrvrItem::GetDragStartView() != NULL)
00680     {
00681         GetRenderWindow()->InvalidateRect(NULL);
00682         CCamSrvrItem::GetDragStartView()->GetRenderWindow()->InvalidateRect(NULL);
00683     }
00684 
00685     return TRUE;
00686 }
00687 
00688 
00689 
00690 
00691 /*********************************************************************************************
00692 >   DROPEFFECT ScreenCamView::OnDragOver( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
00693 
00694     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00695     Created:    26/9/96
00696     Inputs:     pDataObject     Pointer to ColeDataObject
00697                 dwKeyState      Shift, Ctrl, Alt state
00698                 point           The proposed drop position
00699     Outputs:    -
00700     Returns:    DROPEFFECT      Drop possibility
00701     Purpose:    Respond to OLE drop on a ScreenCamView
00702     Errors:     -
00703     Scope:      Public
00704 **********************************************************************************************/ 
00705 
00706 DROPEFFECT ScreenCamView::OnDragOver( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
00707 {
00708     DROPEFFECT DropEffect = DROPEFFECT_NONE;
00709 
00710     if (m_DropFormatOK)
00711     {
00712         DWORD KeyModifierMask = (MK_CONTROL | MK_SHIFT | MK_ALT);
00713 
00714         // WEBSTER - markn 14/2/97
00715         // Changed the unmodified drag to be DROPEFFECT_COPY & the modified one to DROPEFFECT_MOVE
00716         // It used to be the other way round
00717 
00718         if ((dwKeyState & KeyModifierMask) == 0)                // No modifier keys? if so move.
00719             DropEffect = DROPEFFECT_COPY;
00720         else if ((dwKeyState & KeyModifierMask) == MK_CONTROL)  // Ctrl only down? if so copy
00721             DropEffect = DROPEFFECT_MOVE;
00722 
00723         // If we are moving data between two views of the same doc, then change to a copy
00724         // because move does not work correctly
00725         if (DropEffect == DROPEFFECT_MOVE)
00726         {
00727             if (CCamSrvrItem::GetDragStartView() != NULL)
00728             {
00729                 CCamDoc* pThisViewDoc = GetDocument();
00730                 CCamDoc* pOtherViewDoc = CCamSrvrItem::GetDragStartView()->GetDocument();
00731 
00732                 if (pThisViewDoc == pOtherViewDoc)
00733                     DropEffect = DROPEFFECT_COPY;
00734             }
00735         }
00736     }
00737 
00738     return DropEffect;
00739 }
00740 
00741 
00742 
00743 
00744 /*********************************************************************************************
00745 >   DROPEFFECT ScreenCamView::OnDragEnter( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
00746 
00747     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00748     Created:    26/9/96
00749     Inputs:     pDataObject     Pointer to ColeDataObject
00750                 dwKeyState      Shift, Ctrl, Alt state
00751                 point           The proposed drop position
00752     Outputs:    -
00753     Returns:    DROPEFFECT      Drop possibility
00754     Purpose:    Mouse is entering our view so cache any useufl data which would speed up
00755                 future calls to OnDragOver.
00756     Errors:     -
00757     Scope:      Public
00758 **********************************************************************************************/ 
00759 
00760 DROPEFFECT ScreenCamView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
00761 {
00762     if (pDataObject == NULL)
00763         return DROPEFFECT_NONE;
00764 
00765     // Set up the kernel with this item's document as 'current'.
00766     GetDocument()->GetKernelDoc()->SetCurrent();
00767 
00768     // Disconnect from the Windows clipboard and swap in the drag'n'drop clipboard.
00769     if (InternalClipboard::GetCurrentID() == InternalClipboard::CLIPBOARD)
00770     {
00771 //      TRACEUSER( "Markn", _T("Swapping to DragNDrop clipboard doc (ScreenCamView::OnDragEnter())\n"));
00772         ExternalClipboard::UpdateSystemClipboard(FALSE);
00773         InternalClipboard::Swap();
00774         InternalClipboard::Clear();
00775         m_ClipBoardSwapped = TRUE;
00776     }
00777     else
00778         m_ClipBoardSwapped = FALSE;
00779 
00780     // If there is a format on the external clipboard we like, then it's ok to drop.
00781     UINT32 nFormat = ExternalClipboard::GetBestPasteFormat(pDataObject);
00782     m_DropFormatOK = (nFormat != 0);
00783 //  m_DropFormatOK = TRUE;
00784     
00785     // Update the status-line prefix with what we would drop.
00786     if (m_DropFormatOK)
00787     {
00788         // Ask the clipboard what the name of the given format is.
00789         String_64 strName;
00790         ExternalClipboard::GetExternalFormatName(nFormat, &strName);
00791 
00792         // Set the formatted text in the status line.
00793         String_64 strLine;
00794         strLine.MakeMsg(_R(IDS_DROP_FORMAT_TEXT), (LPCTSTR) strName);
00795         StatusLine::SetPrefix(strLine);
00796     }
00797 
00798     // Call OnDragOver to ensure consistent response
00799     return OnDragOver(pDataObject, dwKeyState, point);
00800 }
00801 
00802 
00803 
00804 
00805 /*********************************************************************************************
00806 >   void ScreenCamView::OnDragLeave()
00807 
00808     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00809     Created:    26/9/96
00810     Purpose:    The mouse is leaving our View so tidy up anything that was setup in
00811                 OnDragEnter if we need to.
00812     Scope:      Public
00813 **********************************************************************************************/ 
00814 
00815 void ScreenCamView::OnDragLeave()
00816 {
00817     // Swap out the drag'n'drop clipboard and reconnect to the Windows clipboard.
00818     if (m_ClipBoardSwapped)
00819     {
00820 //      TRACEUSER( "Markn", _T("Swapping back to clipboard doc (ScreenCamView::OnDragLeave())\n"));
00821         InternalClipboard::Swap();
00822         ExternalClipboard::UpdateSystemClipboard(TRUE);
00823     }
00824 
00825     // Remove the status-line prefix.
00826     StatusLine::SetDefaultPrefix();
00827 }
00828 
00829 
00830 
00831 
00832 /*********************************************************************************************
00833 >   virtual void ScreenCamView::HandleOleDragOutOfView(CPoint point);
00834 
00835     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>/Phil/Justin
00836     Created:    26/9/96
00837     Inputs:     point - The current mouse pointer position
00838     Purpose:    Called when doing a DRAGTYPE_OLESCROLL and the mouse pointer moves outside
00839                 the view window. The base class does nothing, so dragging continues as normal,
00840                 but in the derived ScreenCamView class, this is used to cancel the internal
00841                 XOR drag operation, and start an OLE drag and drop export procedure.
00842     Notes:      May cancel the current Drag Op
00843     Scope:      Protected
00844     SeeAlso:    ScreenView::HandleOleDragOutOfView
00845 **********************************************************************************************/ 
00846 
00847 void ScreenCamView::HandleOleDragOutOfView(CPoint point)
00848 {
00849     // Is it OK to start an OLE drag and drop now? (This depends on a preference, and may
00850     // depend on whether a special modifier key is depressed).
00851     if (!OLEPrefs::OKToActivateDrag()) return;
00852 
00853     // Check for junk.
00854     TRACEUSER( "JustinF", _T("Starting up an OLE drag ...\n"));
00855     ERROR3IF(InternalClipboard::GetCurrentID() != InternalClipboard::CLIPBOARD,
00856                 "Current clipboard is wrong in ScreenCamView::HandleOleDragOutOfView");
00857     ERROR3IF(!Tool::GetCurrent() || Tool::GetCurrent()->GetID() != TOOLID_SELECTOR,
00858                 "Selector tool isn't current in ScreenCamView::HandleOleDragOutOfView");
00859 
00860     // Suspend any kernel drag operation (but *don't* kill it, we may restart it later).
00861     if (pCurrentDragOp)
00862     {
00863         // Release the mouse so OLE can process the mouse's messages.
00864         ::ReleaseCapture();
00865 
00866         // Make the kernel drag operation remove all of its XOR blobs. This isn't really necessary
00867         // for most drags, but is vital if we drag into another view of the same document, as
00868         // otherwise the XOR gets well screwed up. Of course if nobody remembers to draw the XOR
00869         // back in before resuming this drag, the XOR will be screwed beyond belief anyway.
00870         Spread* pSpread = pDocView->FindEnclosingSpread(((WinCoord*) &point)->ToOil(pDocView, TRUE));
00871         if (pSpread)
00872         {
00873             // Get the DocView's viewport, in Spread Coords, because we have to supply a DocRect to
00874             // this stupid routine which won't let us pass a NULL pointer in to just redraw
00875             // it all, depsite the fact that all the functions it calls will allow it. Grrr.
00876             // (And using the Spread's bounding rect doesn't work because its bounding rect is in
00877             // chapter coords, not spread coords. Tread carefully...
00878             DocRect ClipRect = pDocView->GetDocViewRect(pSpread);
00879             pSpread->DocCoordToSpreadCoord(&ClipRect);
00880             pCurrentDragOp->RenderDragBlobs(ClipRect, pSpread, pDocView->GetCurrentSolidDragState());
00881         }
00882     }
00883 
00884     // Find the bounds of the dragged object, in Document coordinates / millipoints.
00885     ERROR3IF(Tool::GetCurrent()->GetID() != TOOLID_SELECTOR, 
00886                 "ScreenCamView::HandleOleDragOutOfView: not the selector tool");
00887     DocRect drBounds = ((SelectorTool*) Tool::GetCurrent())->GetSelectionBounds();
00888     if (drBounds.IsEmpty() || !drBounds.IsValid())
00889     {
00890         TRACEUSER( "JustinF", _T("Invalid/empty bounds in ScreenCamView::HandleOleDragOutOfView\n"));
00891         return;
00892     }
00893 
00894     // Convert it's dimensions to pixels.
00895     CSize szItem(CCamSrvrItem::MPtoPX(drBounds.Width()),
00896                  CCamSrvrItem::MPtoPX(drBounds.Height()));
00897 
00898     // Work out the bounds of the object, in pixels, and the offset from the mouse to the
00899     // top-left corner of the object, in pixels.
00900     CRect rItem(CPoint(point.x - szItem.cx / 2, point.y - szItem.cy / 2), szItem);
00901     CPoint ptOffset(point - CPoint(rItem.left, rItem.top));
00902 
00903     // Ask the drag'n'drop clipboard to start an OLE drag operation.
00904     InternalClipboard::Other()->GetOilDoc()->GetEmbeddedItem()->DoDragDrop(&rItem, ptOffset);
00905 }
00906 
00907 #endif

Generated on Sat Nov 10 03:48:50 2007 for Camelot by  doxygen 1.4.4