home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / netsvw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  37.3 KB  |  1,219 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. // netsvw.cpp : implementation of the CNetscapeView class
  20. //
  21.  
  22. #include "stdafx.h"
  23.  
  24. #include "dialog.h"
  25. #include "cntritem.h"
  26. #include "cxsave.h"
  27. #include "cxprint.h"
  28. #include "netsprnt.h"
  29. #include "edt.h"
  30. #include "netsvw.h"
  31. #include "mainfrm.h"
  32. #include "prefapi.h"
  33. #ifdef EDITOR
  34. #include "shcut.h"
  35. #include "edframe.h"
  36. #include "pa_tags.h"   // Needed for P_MAX
  37. #endif
  38. #include "libevent.h"
  39. #ifdef XP_WIN32
  40. #include "shlobj.h" // For clipboard formats
  41. #endif
  42. #include "np.h"
  43.  
  44. #include "intl_csi.h"
  45. #include "libi18n.h"
  46.  
  47. #ifdef MOZ_MAIL_NEWS
  48. // For hiding/restoring Mail Composer toolbars 
  49. //  during Print Preview
  50. // TODO: This should be changed to go through chrome mechanism;
  51. //       CNetscapeView shouldn't know about CComposeFrame
  52. #include "compfrm.h"
  53. #include "compbar.h"
  54. #endif
  55.  
  56. #ifdef _DEBUG
  57. #undef THIS_FILE
  58. static char BASED_CODE THIS_FILE[] = __FILE__;
  59. #endif
  60.  
  61. /////////////////////////////////////////////////////////////////////////////
  62. #ifdef EDITOR
  63. #define GET_MWCONTEXT  (GetContext() == NULL ? NULL : GetContext()->GetContext())
  64.  
  65. // Used to suppress interaction during URL loading, editor setup, layout, etc.
  66. #define CAN_INTERACT  (GetContext() != NULL && GetContext()->GetContext() != NULL \
  67.                        && !GetContext()->GetContext()->waitingMode )
  68.  
  69. extern char *EDT_NEW_DOC_URL;
  70. extern char *EDT_NEW_DOC_NAME;
  71. #endif
  72. // CNetscapeView
  73.  
  74. #ifndef _AFXDLL
  75. #undef new
  76. #endif
  77. IMPLEMENT_DYNCREATE(CNetscapeView, CGenericView)
  78. #ifndef _AFXDLL
  79. #define new DEBUG_NEW
  80. #endif
  81.  
  82. BEGIN_MESSAGE_MAP(CNetscapeView, CGenericView)
  83.     //{{AFX_MSG_MAP(CNetscapeView)
  84.     ON_WM_RBUTTONDOWN()
  85.     ON_UPDATE_COMMAND_UI(ID_NAVIGATE_REPAINT, OnUpdateNavigateRepaint)
  86.     ON_WM_CREATE()
  87.     ON_COMMAND(ID_NAVIGATE_REPAINT, OnNavigateRepaint)
  88.     ON_COMMAND(ID_POPUP_LOADLINK, OnPopupLoadLink)
  89.     ON_COMMAND(ID_POPUP_ADDLINK2BOOKMARKS, OnPopupAddLinkToBookmarks)
  90.     ON_COMMAND(ID_POPUP_LOADLINKNEWWINDOW, OnPopupLoadLinkNewWindow)
  91.     ON_COMMAND(ID_POPUP_LOADFRAMENEWWINDOW, OnPopupLoadFrameNewWindow)
  92.     ON_COMMAND(ID_POPUP_SAVELINKCONTENTS, OnPopupSaveLinkContentsAs)
  93.     ON_COMMAND(ID_POPUP_COPYLINKCLIPBOARD, OnPopupCopyLinkToClipboard)
  94.     ON_COMMAND(ID_POPUP_LOADIMAGE, OnPopupLoadImage)
  95.     ON_COMMAND(ID_POPUP_SAVEIMAGEAS, OnPopupSaveImageAs)
  96.     ON_COMMAND(ID_POPUP_COPYIMGLOC2CLIPBOARD, OnPopupCopyImageLocationToClipboard)
  97.     ON_COMMAND(ID_POPUP_LOADIMAGEINLINE, OnPopupLoadImageInline)
  98.     ON_COMMAND(ID_POPUP_ACTIVATEEMBED, OnPopupActivateEmbed)
  99.     ON_COMMAND(ID_POPUP_SAVEEMBEDAS, OnPopupSaveEmbedAs)
  100.     ON_COMMAND(ID_POPUP_COPYEMBEDLOC, OnPopupCopyEmbedLocationToClipboard)
  101.     ON_COMMAND(ID_POPUP_SETASWALLPAPER, OnPopupSetAsWallpaper)
  102.     ON_COMMAND(ID_POPUP_COPYEMBEDDATA, OnPopupCopyEmbedToClipboard)
  103.     ON_COMMAND(ID_CANCEL_EDIT, OnDeactivateEmbed)
  104.     ON_COMMAND(ID_POPUP_INTERNETSHORTCUT, OnPopupInternetShortcut)
  105.     ON_COMMAND(ID_POPUP_MAILTO, OnPopupMailTo)
  106.     //}}AFX_MSG_MAP
  107.     // Standard printing commands
  108.     ON_WM_SIZE()
  109.     ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
  110.     ON_WM_KEYDOWN()
  111.     ON_WM_KEYUP()
  112.     ON_COMMAND(ID_DRAG_THIS_URL, OnCopyCurrentURL)
  113. #ifdef EDITOR
  114.     ON_UPDATE_COMMAND_UI(ID_DRAG_THIS_URL, OnCanInteract)
  115.     ON_COMMAND(ID_POPUP_EDIT_IMAGE, OnPopupEditImage )       //Implemented in popup.cpp
  116.     ON_COMMAND(ID_POPUP_EDIT_LINK, OnPopupLoadLinkInEditor ) //  "
  117.     // Shift-F10 is same as right mouse button down
  118.     ON_COMMAND( ID_LOCAL_POPUP, OnLocalPopup )
  119. #endif //EDITOR
  120. END_MESSAGE_MAP()
  121.  
  122. #ifndef _AFXDLL
  123. #define new DEBUG_NEW  // MSVC Debugging new...goes to regular new in release mode
  124. #endif
  125.  
  126. CNetscapeView::CNetscapeView()  
  127. {
  128.    m_pChild = NULL;
  129.     //  Initialize some members.
  130.     m_pDropTarget = NULL;
  131.     m_pPreviewContext = NULL;
  132.  
  133.     //    We have no context yet.
  134.     m_pContext = NULL;
  135.  
  136.     m_pSaveFileDlg = NULL;
  137. #ifdef EDITOR
  138.     // This is set to TRUE by derived class CEditView
  139.     //  if we are actually an editor
  140.     m_bIsEditor = FALSE;
  141.  
  142.     // Register our HTML-preserving clipboard format
  143.     m_cfEditorFormat = RegisterClipboardFormat(NETSCAPE_EDIT_FORMAT);
  144.  
  145.     // Be sure BookmarkName clipboard format was registered also
  146.     m_cfBookmarkFormat = (CLIPFORMAT)RegisterClipboardFormat(NETSCAPE_BOOKMARK_FORMAT);
  147.  
  148.     // Used to drag image reference from browser window to insert into editor
  149.     m_cfImageFormat = (CLIPFORMAT)RegisterClipboardFormat(NETSCAPE_IMAGE_FORMAT);
  150.  
  151.     // Construct our list of supported clipboard formats
  152.     // Be sure size is same as number of formats!
  153.     // *** This should be done at some centralized app-data!
  154.     
  155.     m_pClipboardFormats = new UINT[MAX_CLIPBOARD_FORMATS];
  156.     ASSERT(m_pClipboardFormats);
  157.     
  158.     for( int i = 0; i < MAX_CLIPBOARD_FORMATS; i++ ){
  159.         m_pClipboardFormats[i] = 0;
  160.     }
  161.  
  162.     // This is stupid! Clipboard format array must be UINT,
  163.     //  but CLIPFORMAT type is an unsigned short!
  164.     // Editor's own format for HTML text
  165.     m_pClipboardFormats[0] = (UINT)m_cfEditorFormat;
  166.     // Bookmark format
  167.     m_pClipboardFormats[1] = (UINT)m_cfBookmarkFormat;
  168.  
  169.     // Used to drag 
  170.     m_pClipboardFormats[2] = (UINT)m_cfImageFormat;
  171.  
  172.     // These are from shlobj.h Not all used right now
  173. #ifdef XP_WIN32
  174.     m_pClipboardFormats[3] = (UINT)RegisterClipboardFormat(CFSTR_SHELLIDLIST);
  175.     m_pClipboardFormats[4] = (UINT)RegisterClipboardFormat(CFSTR_NETRESOURCES);
  176.     m_pClipboardFormats[5] = (UINT)RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
  177.     m_pClipboardFormats[6] = (UINT)RegisterClipboardFormat(CFSTR_FILECONTENTS);
  178.     m_pClipboardFormats[7] = (UINT)RegisterClipboardFormat(CFSTR_FILENAME);
  179.     m_pClipboardFormats[8] = (UINT)RegisterClipboardFormat(CFSTR_PRINTERGROUP);
  180.     m_pClipboardFormats[9] = (UINT)CF_UNICODETEXT;
  181. #endif
  182.     
  183.     // Built-in Windows formats:
  184.     m_pClipboardFormats[10] = (UINT)CF_TEXT;
  185. #ifdef _IMAGE_CONVERT
  186.     m_pClipboardFormats[11] = (UINT)CF_DIB;
  187.     ASSERT( MAX_CLIPBOARD_FORMATS == 12 );
  188. #else
  189.     ASSERT( MAX_CLIPBOARD_FORMATS == 11 );
  190. #endif //_IMAGE_CONVERT
  191.  
  192.  
  193.             // m_pClipboardFormats[10] = CF_BITMAP;
  194.             // m_pClipboardFormats[11] = CF_DIB;
  195.             // m_pClipboardFormats[12] = CF_METAFILEPICT;
  196.  
  197.     // ARE YOU ADDING A CLIPBOARD FORMAT???
  198.     //  don't forget to update MAX_CLIPBOARD_FORMATS in NETSVW.H
  199.  
  200. #endif // EDITOR
  201. }
  202.  
  203. // No longer accept drop events as we are going away
  204. //
  205. CNetscapeView::~CNetscapeView()  
  206. {
  207.     if(m_pDropTarget) {
  208.         m_pDropTarget->Revoke();
  209.         delete m_pDropTarget;
  210.         m_pDropTarget = NULL;
  211.     }
  212.  
  213. #ifdef EDITOR
  214.     if ( m_pClipboardFormats )
  215.         delete [] m_pClipboardFormats;
  216. #endif
  217. }
  218.  
  219. BOOL CNetscapeView::PreCreateWindow(CREATESTRUCT & cs) 
  220. {
  221.  
  222.     cs.lpszClass = AfxRegisterWndClass(
  223.         CS_BYTEALIGNWINDOW |
  224.         CS_BYTEALIGNCLIENT |
  225.  
  226.         // Although a private DC is convenient to use, it is expensive
  227.         //  in terms of system resources, requiring 800 or more bytes
  228.         //  to store. Private DCs are recommended when performance
  229.         //  considerations outweigh storage costs. 
  230.         //      - MSDN
  231.         // 800 / (64 * 1024) = 1.2% of GDI per window.
  232.         // Win16 can do without?  We'll see.
  233.         CS_OWNDC |
  234.  
  235.         CS_DBLCLKS);
  236.     
  237.     //    Do not add scroll bars anymore.
  238.     cs.style = cs.style | WS_HSCROLL | WS_VSCROLL | WS_CLIPSIBLINGS| WS_CHILD;
  239.  
  240.     return (CGenericView::PreCreateWindow(cs));
  241. }
  242.  
  243. /////////////////////////////////////////////////////////////////////////////
  244. // CNetscapeView drawing
  245.  
  246. void CNetscapeView::OnPrepareDC(CDC *pDC, CPrintInfo * pInfo /* = NULL */) 
  247. {
  248.   //  Color is now set in OnEraseBkgnd  
  249.  
  250. #ifdef ONLY_GRAY_BACKGROUND
  251.     if (!pInfo) 
  252.         pDC->SetBkColor(RGB(192, 192, 192));
  253. #else
  254.     pDC->SetBkMode(TRANSPARENT);
  255. #endif
  256.           
  257. }
  258.  
  259. /////////////////////////////////////////////////////////////////////////////
  260. // CNetscapeView printing
  261. void CNetscapeView::OnFilePrintPreview()
  262. {
  263.     if(GetContext() == NULL ||
  264.         GetFrame()->GetMainWinContext() == NULL ||
  265.         GetFrame()->GetMainWinContext()->GetPane() == NULL ||
  266.         GetFrame()->GetActiveWinContext() == NULL ||
  267.         GetFrame()->GetActiveWinContext()->GetPane() == NULL)    {
  268.  
  269.         return;
  270.     }
  271.     // Note: We used to force saving an editor page here,
  272.     //  but we don't need to with new tempfile mechanism
  273.  
  274.     //    If we're a grid cell, then we have to have the frame's main view
  275.     //        handle this, or MFC gets confused...
  276.     if(GetContext()->IsGridCell() == TRUE)    {
  277.         //    After beta 2, however.
  278.         ((CNetscapeView *)GetFrame()->GetMainWinContext()->GetView())->OnFilePrintPreview();
  279.         return;
  280.     }
  281.  
  282.     //    However, if we're a grid parent, we can't allow this unless we are
  283.     //        not the active context of the frame, and the active context is
  284.     //        not a grid cell.
  285.     if(GetContext()->IsGridParent() == TRUE)    {
  286.         //    Must not be active.
  287.         if(GetContext()->GetFrame()->GetActiveContext() == GetContext())    {
  288.             return;
  289.         }
  290.  
  291.         //    Active must not be Grid Parent.
  292.         if(GetFrame()->GetActiveContext()->IsGridParent() == TRUE)    {
  293.             return;
  294.         }
  295.     }
  296.  
  297.     //    Remember that we've started print preview.
  298.     //    Do this first.
  299.     m_bInPrintPreview = TRUE;
  300.  
  301.     //    Get rid of the URL bar for print preview.
  302.     LPCHROME pChrome = GetFrame()->GetChrome();
  303.     if(pChrome) {
  304.         pChrome->ViewCustToolbar(FALSE);
  305.     }
  306.     // this is not necessary now, but if we ever save things not
  307.     // related to the customizable toolbar it will be
  308.     GetFrame()->SaveBarState();
  309.  
  310. #ifdef MOZ_MAIL_NEWS
  311. #ifdef EDITOR
  312.     // Deal with Message Composer toolbars as well
  313.     MWContext *pMWContext = GetContext()->GetContext();
  314.     if( pMWContext && pMWContext->bIsComposeWindow )
  315.     {
  316.         // Get the Address widget and hide it if its visible
  317.         // Note: For minimum change here, we will always restore it when done previewing
  318.         CComposeBar *pAddressBar = ((CComposeFrame*)GetFrame())->GetComposeBar();
  319.         if( pAddressBar && pAddressBar->IsVisible() )
  320.         {
  321.             pAddressBar->OnToggleShow();    
  322.         }
  323.  
  324.         // Hide the Composer's formatting toolbar,
  325.         //  and remember state so we restore only if currently visible
  326.         m_bRestoreComposerToolbar = FALSE;
  327.         CEditToolBarController * pController = 
  328.             (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  329.         if( pController )
  330.         {
  331.             CComboToolBar * pToolBar = pController->GetCharacterBar();
  332.             if( pToolBar )
  333.             {
  334.                 m_bRestoreComposerToolbar = pToolBar->IsVisible();
  335.                 if( m_bRestoreComposerToolbar )
  336.                     pController->ShowToolBar( FALSE, pToolBar );
  337.             }
  338.         }
  339.     }
  340. #endif
  341. #endif //MOZ_MAIL_NEWS
  342.  
  343.     //    Must outlive this function.
  344.     CPrintPreviewState *pState = new CPrintPreviewState;
  345.  
  346.     if(!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this, RUNTIME_CLASS(CNetscapePreviewView), pState))    {
  347.         AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
  348.         delete pState;
  349.         if(pChrome) {
  350.             pChrome->ViewCustToolbar(TRUE);
  351.         }
  352.         GetFrame()->RestoreBarState();
  353.  
  354.         //    Do this last.
  355.         m_bInPrintPreview = FALSE;
  356.     }
  357. }
  358.  
  359. void CNetscapeView::OnEndPrintPreview(CDC *pDC, CPrintInfo *pInfo, POINT pXY, CPreviewView *pPreView)    {
  360.     CNetscapePreviewView *pView = (CNetscapePreviewView *)pPreView;
  361.  
  362.     if (pView->m_pPrintView != NULL)
  363.         ((CNetscapeView *)pView->m_pPrintView)->OnEndPrinting(pDC, pInfo);
  364.  
  365.     CFrameWnd* pParent = (CFrameWnd*)GetFrame()->GetFrameWnd(); //AfxGetThread()->m_pMainWnd;
  366.     ASSERT_VALID(pParent);
  367.     ASSERT(pParent->IsKindOf(RUNTIME_CLASS(CFrameWnd)));
  368.  
  369.     // restore the old main window
  370.     pParent->OnSetPreviewMode(FALSE, pView->m_pPreviewState);
  371.  
  372.     // Force active view back to old one
  373.     pParent->SetActiveView(pView->m_pPreviewState->pViewActiveOld);
  374.     if (pParent != GetParentFrame())
  375.         OnActivateView(TRUE, this, this);   // re-activate view in real frame
  376.     
  377.     //CLM: This fixes the print preview crash OnClose
  378.     //     Some MFC weirdness, but we have to delete this
  379.     //     and not let pPreView try to do it 
  380.     delete pView->m_pPreviewState;
  381.     pView->m_pPreviewState = NULL;
  382.  
  383.     pView->DestroyWindow();     // destroy preview view
  384.             // C++ object will be deleted in PostNcDestroy
  385.  
  386.     // restore main frame layout and idle message
  387.     pParent->RecalcLayout();
  388.     pParent->SendMessage(WM_SETMESSAGESTRING, (WPARAM)AFX_IDS_IDLEMESSAGE, 0L);
  389.     pParent->UpdateWindow();
  390.  
  391.     //    If we have a print context, get rid of it here.
  392.     if(m_pPreviewContext != NULL)    {
  393.         //    If it's still loading, just have it cancel.
  394.         //    It will delete itself.
  395.         if(m_pPreviewContext->GetDisplayMode() == BLOCK_DISPLAY)    {
  396.             m_pPreviewContext->CancelPrintJob();
  397.         }
  398.         else    {
  399.             //    We can get rid of it right now.
  400.             m_pPreviewContext->DestroyContext();
  401.         }
  402.         m_pPreviewContext = NULL;
  403.     }
  404.     LPCHROME pChrome = GetFrame()->GetChrome();
  405.     if(pChrome) {
  406.         pChrome->ViewCustToolbar(TRUE);
  407.     }
  408.  
  409.     // this is not necessary now, but if we ever save things not
  410.     // related to the customizable toolbar it will be
  411.     GetFrame()->RestoreBarState();
  412.  
  413. #ifdef MOZ_MAIL_NEWS
  414. #ifdef EDITOR
  415.     // Restore Message Composer toolbars as well
  416.     MWContext *pMWContext = GetContext()->GetContext();
  417.     if( pMWContext && pMWContext->bIsComposeWindow )
  418.     {
  419.         // Note: We always restore Address widget when done previewing
  420.         CComposeBar *pAddressBar = ((CComposeFrame*)GetFrame())->GetComposeBar();
  421.         if( pAddressBar && !pAddressBar->IsVisible() )
  422.         {
  423.             pAddressBar->OnToggleShow();    
  424.         }
  425.  
  426.         // Restore Composer format/character toolbar only if it was visible before
  427.         if( m_bRestoreComposerToolbar )
  428.         {
  429.             CEditToolBarController * pController = 
  430.                 (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  431.             if( pController )
  432.             {
  433.                 CComboToolBar * pToolBar = pController->GetCharacterBar();
  434.                 if( pToolBar )
  435.                     pController->ShowToolBar( TRUE, pToolBar );
  436.             }
  437.         }
  438.         m_bRestoreComposerToolbar = FALSE;
  439.     }
  440. #endif // EDITOR
  441. #endif // MOZ_MAIL_NEWS
  442.  
  443.     //    Do this last.
  444.     m_bInPrintPreview = FALSE;
  445. }
  446.  
  447. BOOL CNetscapeView::OnPreparePrinting(CPrintInfo *pInfo)    {
  448.     //    This only gets called in print preview mode.
  449.     //    Never in print only mode.
  450.     return(DoPreparePrinting(pInfo));
  451. }
  452.  
  453. void CNetscapeView::OnPrint(CDC *pDC, CPrintInfo *pInfo)    {
  454.     //    This only gets called in print preview mode.
  455.     //    Never in print only mode.
  456.     if(m_pPreviewContext == NULL)    {
  457.         
  458.         CAbstractCX *pContext = GetFrame()->GetActiveContext();
  459.  
  460.         //    Since we have no preview context, this means we're
  461.         //        starting to preview a page.
  462.         //    We need to load it.
  463.         //    We must call on behalf of the active context, or MFC get's confused.
  464.         if( !pContext || pContext->CanCreateUrlFromHist() == FALSE)    {
  465.             return;
  466.         }
  467.         // This also sets m_pPreviewContext once called to non NULL.
  468.         //  Always pass the WYSIWYG attribute for printing URLs (javascript).
  469.         SHIST_SavedData SavedData;
  470.         URL_Struct *pUrl = pContext->CreateUrlFromHist(TRUE, &SavedData, TRUE);
  471.         pUrl->position_tag = 0;
  472.  
  473.         char *pDisplayUrl = NULL;
  474. #ifdef EDITOR
  475.         // Save actual address we want to show in header or footer
  476.         //  to pass on to print context
  477.         if( pUrl->address )
  478.             pDisplayUrl = XP_STRDUP(pUrl->address);
  479.  
  480.         // If necessary (Mail Compose Window, new page, or changes in current page),
  481.         //  copy current page to a temp file and switch
  482.         //  to that URL address in URL_Struct
  483.         if( !FE_PrepareTempFileUrl(pContext->GetContext(), pUrl) )
  484.         {
  485.             XP_FREEIF(pDisplayUrl);
  486.             // Failed to save to the temp file - abort
  487.             return;
  488.         }
  489. #endif
  490.         // Copy the necessary information into the URL's saved data so that we don't
  491.         // make a copy of the plug-ins when printing
  492.         NPL_PreparePrint(pContext->GetContext(), &pUrl->savedData);
  493.  
  494.         CPrintCX::PreviewAnchorObject(m_pPreviewContext, pUrl, this, pDC, pInfo, &SavedData, pDisplayUrl);
  495.         XP_FREEIF(pDisplayUrl);
  496.     }
  497.  
  498.     //    Either the page is loading in the print context, or it's done loading.
  499.     //    In any event, attempt to have it print the page.
  500.     m_pPreviewContext->PrintPage(pInfo->m_nCurPage, pDC->GetSafeHdc(), pInfo);
  501. }
  502.  
  503. BOOL CNetscapeView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
  504.     CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
  505. {
  506.     ASSERT_VALID_IDR(nIDResource);
  507.     ASSERT_VALID(pPrintView);
  508.     ASSERT(pPreviewViewClass != NULL);            
  509. #ifdef XP_WIN32    
  510.     ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CPreviewView)));
  511. #endif
  512.     ASSERT(pState != NULL);
  513.  
  514.     CFrameWnd* pParent = (CFrameWnd*)GetFrame()->GetFrameWnd(); // AfxGetThread()->m_pMainWnd;
  515.     ASSERT_VALID(pParent);
  516.     ASSERT(pParent->IsKindOf(RUNTIME_CLASS(CFrameWnd)));
  517.  
  518.     CCreateContext context;
  519.     context.m_pCurrentFrame = pParent;
  520.     context.m_pCurrentDoc = GetDocument();
  521.     context.m_pLastView = this;
  522.  
  523.     // Create the preview view object
  524.     CNetscapePreviewView* pView = (CNetscapePreviewView*)pPreviewViewClass->CreateObject();
  525.     if (pView == NULL)
  526.     {
  527.         TRACE0("Error: Failed to create preview view.\n");
  528.         return FALSE;
  529.     }
  530.     ASSERT(pView->IsKindOf(RUNTIME_CLASS(CPreviewView)));
  531.     pView->m_pPreviewState = pState;        // save pointer
  532.  
  533.     pParent->OnSetPreviewMode(TRUE, pState);    // Take over Frame Window
  534.  
  535.     // Create the toolbar from the dialog resource
  536.     pView->m_pToolBar = new CDialogBar;
  537.     if (!pView->m_pToolBar->Create(pParent, MAKEINTRESOURCE(nIDResource),
  538.         CBRS_TOP, AFX_IDW_PREVIEW_BAR))
  539.     {
  540.         TRACE0("Error: Preview could not create toolbar dialog.\n");
  541.         pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
  542.         delete pView->m_pToolBar;       // not autodestruct yet
  543.         pView->m_pToolBar = NULL;
  544.         pView->m_pPreviewState = NULL;  // do not delete state structure
  545.         // (because pState is deleted by caller)
  546.         delete pView;
  547.         return FALSE;
  548.     }
  549.     pView->m_pToolBar->m_bAutoDelete = TRUE;    // automatic cleanup
  550.  
  551.     // Create the preview view as a child of the App Main Window.  This
  552.     // is a sibling of this view if this is an SDI app.  This is NOT a sibling
  553.     // if this is an MDI app.
  554.  
  555.     if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
  556.         CRect(0,0,0,0), pParent, AFX_IDW_PANE_FIRST, &context))
  557.     {
  558.         TRACE0("Error: couldn't create preview view for frame.\n");
  559.         pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
  560.         // Note:
  561.         //CLM: Delete here -- looks better!
  562.         delete pView->m_pPreviewState;
  563.         pView->m_pPreviewState = NULL;  // do not delete state structure
  564.         // (because pState is deleted by caller)
  565.         delete pView;
  566.         return FALSE;
  567.     }
  568.  
  569.     // Preview window shown now
  570.  
  571.     pState->pViewActiveOld = pParent->GetActiveView();
  572.     CView* pActiveView = pParent->GetActiveFrame()->GetActiveView();
  573.     if (pActiveView != NULL)
  574.         ((CNetscapeView *)pActiveView)->OnActivateView(FALSE, pActiveView, pActiveView);
  575.  
  576.     if (!pView->SetPrintView(pPrintView))
  577.     {
  578.         pView->OnPreviewClose();
  579.         return TRUE;            // signal that OnEndPrintPreview was called
  580.     }
  581.  
  582.     pParent->SetActiveView(pView);  // set active view - even for MDI
  583.  
  584.     // update toolbar and redraw everything
  585.     pView->m_pToolBar->SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);
  586.     pParent->RecalcLayout();            // position and size everything
  587.     pParent->UpdateWindow();
  588.  
  589.     return TRUE;
  590. }
  591.  
  592. /////////////////////////////////////////////////////////////////////////////
  593. // CNetscapeView diagnostics
  594.  
  595. #ifdef _DEBUG
  596. void CNetscapeView::AssertValid() const
  597. {
  598.     CGenericView::AssertValid();
  599. }
  600.  
  601. void CNetscapeView::Dump(CDumpContext& dc) const
  602. {
  603.     CGenericView::Dump(dc);
  604. }
  605. #endif //_DEBUG
  606.  
  607. CGenericDoc* CNetscapeView::GetDocument()    {
  608.     CGenericDoc *pRetval = NULL;
  609.     if(m_pContext != NULL)    {
  610.         pRetval = m_pContext->GetDocument();
  611.     }
  612.  
  613.     return(pRetval);
  614. }
  615.  
  616.  
  617. /////////////////////////////////////////////////////////////////////////////
  618. // CNetscapeView message handlers
  619.  
  620. int CNetscapeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  621. {
  622.     if (CGenericView::OnCreate(lpCreateStruct) == -1)
  623.         return -1;
  624.  
  625.     // initialize the drop target
  626.     if(!m_pDropTarget) {
  627.         m_pDropTarget = new CViewDropTarget;
  628.         m_pDropTarget->Register(this);
  629.     }
  630.     //Ok, I'm confused!
  631.     // CMainFrame does DragAcceptFiles(TRUE),
  632.     //  which should enable drop for all child windows
  633.     // But doing DragAcceptFiles(TRUE) actually 
  634.     //  prevents files dropped into the view from being accepted!
  635.     //  And putting DragAcceptFiles(FALSE) here enables it!
  636.     //  Leaving it out also enables it, so lets do that
  637.     //
  638.     // DragAcceptFiles(FALSE);
  639.     return 0;
  640. }
  641.  
  642. // Force a window repaint
  643. // Don't do this by hand (i.e. by calling LO_RefreshArea()) or we will be
  644. //  unable to cache the pDC
  645. //
  646. void CNetscapeView::OnNavigateRepaint()
  647. {
  648.     InvalidateRect(NULL, FALSE);
  649.     UpdateWindow();
  650. }
  651.  
  652. void CNetscapeView::OnUpdateNavigateRepaint(CCmdUI* pCmdUI)
  653. {
  654.     pCmdUI->Enable(TRUE);
  655. }
  656.  
  657. // Block of Editor functions removed from here
  658. // Following are formerly editor functions that are useful in Browser
  659.  
  660. #ifdef EDITOR
  661. // Use this for any commands that are enabled most of the time
  662. void CNetscapeView::OnCanInteract(CCmdUI* pCmdUI)
  663. {
  664.     pCmdUI->Enable(CAN_INTERACT);
  665. }
  666.  
  667. void CNetscapeView::OnLocalPopup()
  668. {
  669.     if( CAN_INTERACT ) {
  670.         CPoint CaretPoint = GetCaretPos();
  671.         // Send message to appropriate view's OnRButtonDown to bring up
  672.         //   context menu at caret location
  673.         PostMessage(WM_RBUTTONDOWN, 0, MAKELPARAM(CaretPoint.x, CaretPoint.y));
  674.     }
  675. }
  676.  
  677. void CNetscapeView::SpawnExternalEditor(MWContext *pMWContext, const char *pPrefName, char *pURL, UINT nIDCaption)
  678. {
  679.     if( !pMWContext || !pPrefName ){
  680.         return;
  681.     }
  682.  
  683.     // Get Editor application name from preferences
  684.     char * pEditor = NULL;
  685.     PREF_CopyCharPref(pPrefName, &pEditor);
  686.  
  687.     if( pEditor == NULL || pEditor[0] == '\0' ){
  688. GET_EDITOR:
  689.         // If no Editor name in preferences, get from OpenFile dialog
  690.         pEditor = wfe_GetExistingFileName(this->m_hWnd, szLoadString(nIDCaption), EXE, TRUE);
  691.         if( pEditor ){
  692.             // Save new editor name
  693.             PREF_SetCharPref(pPrefName, pEditor);
  694.         }
  695.     }
  696.     if(pEditor == NULL) return;
  697.  
  698.     char *pLocalName = NULL;
  699.     CString csMsg;
  700.     BOOL bError = TRUE;
  701.  
  702.     CString csURL(pURL);
  703.     CString csEditor(pEditor);
  704.  
  705.     if( XP_ConvertUrlToLocalFile(csURL, &pLocalName) ){
  706.         CString csCommand;
  707.         // Enclose any string containing spaces with quotes for long filenames
  708.         if ( csURL.Find(' ') > 0 ){
  709.             csCommand = csEditor + " \"" + pLocalName + "\"";    
  710.         } else {
  711.             csCommand = csEditor + " " + pLocalName;
  712.         }
  713.         UINT nSpawn = WinExec(csCommand, SW_SHOW);
  714.         if(nSpawn < 32)    {
  715.             switch(nSpawn) {
  716.                 case 2:                                      
  717.                 case 3:
  718.                     // Instead of useless error message,
  719.                     //  jump to prompt user to enter external Editor application
  720.                     goto GET_EDITOR;
  721.                 default:
  722.                     char szMsg[80];
  723.                     sprintf(szMsg, szLoadString(IDS_UNABLE_TO_LAUNCH_EDITOR), nSpawn);
  724.                     csMsg = szMsg;
  725.                     break;
  726.             }        
  727.         } else {
  728.             bError = FALSE;
  729.         }
  730.     } else {
  731.         AfxFormatString1(csMsg, IDS_ERR_SRC_NOT_FOUND, pLocalName);  
  732.     }
  733.     if( pLocalName ){
  734.         XP_FREE(pLocalName);
  735.     }
  736.     if( bError ){
  737.         MessageBox(csMsg, szLoadString(IDS_SPAWNING_APP),
  738.                    MB_OK | MB_ICONEXCLAMATION);
  739.     }
  740.  
  741.     XP_FREE(pEditor);
  742. }
  743.  
  744. void CNetscapeView::OnEditSource()
  745. {
  746.     MWContext *pMWContext = GET_MWCONTEXT;
  747.     if( !FE_SaveDocument(pMWContext) ){
  748.         return;
  749.     }
  750.  
  751.     // Base URL is the address of current document
  752.     History_entry * hist_ent = SHIST_GetCurrent(&(pMWContext->hist));
  753.     if ( hist_ent == NULL || hist_ent->address == NULL ){
  754.         return;
  755.     }
  756.     // Launch an external editor for current page
  757.     SpawnExternalEditor(pMWContext, "editor.html_editor", hist_ent->address, IDS_SELECT_HTML_EDITOR);
  758. }
  759.  
  760. void CNetscapeView::EditImage(char *pImage)
  761. {
  762.     MWContext *pMWContext = GET_MWCONTEXT;
  763.     if( pImage == NULL || XP_STRLEN(pImage) == 0 ||
  764.         pMWContext == NULL)
  765.     {
  766.         return;
  767.     }
  768.  
  769.     // Base URL is the address of current document
  770.     History_entry * hist_ent = SHIST_GetCurrent(&(pMWContext->hist));
  771.     if ( hist_ent == NULL || hist_ent->address == NULL )
  772.     {
  773.         return;
  774.     }
  775.  
  776.     char * pURL = NET_MakeAbsoluteURL(hist_ent->address, pImage);
  777.  
  778.     // Check if image is remote reference - TODO: Automatically download image to edit it
  779.     if( pURL )
  780.     {
  781.         if( !NET_IsLocalFileURL(pURL) )
  782.         {
  783.             CWnd *pWnd = GetContext()->GetDialogOwner();
  784.             pWnd->MessageBox(szLoadString(IDS_IMAGE_IS_REMOTE), 
  785.                        szLoadString(IDS_EDIT_IMAGE_CAPTION),
  786.                        MB_OK | MB_ICONEXCLAMATION);
  787.             XP_FREE(pURL);
  788.             return;
  789.         }
  790.         SpawnExternalEditor(pMWContext, "editor.image_editor", pURL, IDS_SELECT_IMAGE_EDITOR);
  791.         XP_FREE(pURL);
  792.     }
  793. }
  794.  
  795. // *** end of "formerly editor functions"
  796. #endif /* EDITOR */
  797.  
  798. void CNetscapeView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
  799. {
  800.     // Pass it off to the context to handle if it can.
  801.     if(GetContext() != NULL && GetContext()->IsDestroyed() == FALSE)
  802.         GetContext()->OnKeyUp(nChar, nRepCnt, nFlags);
  803. }
  804.  
  805. void CNetscapeView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  806. {         
  807.     
  808.     // Pass it off to the context to handle if it can.
  809.     if(GetContext() != NULL && GetContext()->IsDestroyed() == FALSE) {
  810.         if(GetContext()->OnKeyDown(nChar, nRepCnt, nFlags))
  811.             return;
  812.     }
  813.      
  814.     switch(nChar) {
  815.     case ' ':
  816.     case VK_NEXT:
  817.         // page down
  818.         OnVScroll(SB_PAGEDOWN, 0, NULL);
  819.         break;
  820.     case VK_BACK:
  821.     case VK_PRIOR:
  822.         // page up
  823.         OnVScroll(SB_PAGEUP, 0, NULL);
  824.         break;
  825.     case VK_UP:
  826.         // line up
  827.         OnVScroll(SB_LINEUP, 0, NULL);
  828.         break;
  829.     case VK_DOWN:
  830.         // line down
  831.         OnVScroll(SB_LINEDOWN, 0, NULL);
  832.         break;
  833.     case VK_RIGHT:
  834.         // line right
  835.         OnHScroll(SB_LINERIGHT, 0, NULL);
  836.         break;
  837.     case VK_LEFT:
  838.         // line left
  839.         OnHScroll(SB_LINELEFT, 0, NULL);
  840.         break;
  841.     case VK_ESCAPE: {
  842.             CWinCX *pWinCX = GetContext();
  843.             //  escape, kill off any selected items.
  844.             if(pWinCX && pWinCX->m_pSelected != NULL) {
  845.                 OnDeactivateEmbed();
  846.             }
  847.         }
  848.         break;
  849.     case VK_HOME:
  850.         if (::GetKeyState(VK_CONTROL) < 0)
  851.             OnVScroll(SB_TOP, 0, NULL);
  852.         else
  853.             OnHScroll(SB_TOP, 0, NULL);
  854.         break;
  855.     case VK_END:
  856.         if (::GetKeyState(VK_CONTROL) < 0)
  857.             OnVScroll(SB_BOTTOM, 0, NULL);
  858.         else
  859.             OnHScroll(SB_BOTTOM, 0, NULL);
  860.         break;
  861.     default:
  862.         CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  863.     }
  864. }
  865.  
  866. void CNetscapeView::OnInitialUpdate() 
  867. {
  868.     //  Assign in our document, since no one else has bothered
  869.     if(m_pDocument == NULL)    {
  870.         m_pContext->GetDocument()->AddView(this);
  871.     }
  872.   
  873.   CGenericView::OnInitialUpdate();  
  874. }
  875.  
  876.  
  877. void CNetscapeView::OnDeactivateEmbed() {
  878.     if(m_pContext != NULL)    {
  879.         m_pContext->OnDeactivateEmbedCX();
  880.     }
  881. }
  882.  
  883. //
  884. // Focus management to support international forms
  885. //
  886. void CNetscapeView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
  887. {
  888.     //    Remember focus before we activate.
  889.     HWND hWndFocus = m_hWndFocus;
  890.     CGenericView::OnActivateView(bActivate, pActivateView, pDeactiveView);
  891.  
  892.     if(bActivate) {
  893.         //    Restore focus to child if exists.
  894.         if(hWndFocus && ::IsWindow(hWndFocus))    {
  895.             ::SetFocus(hWndFocus);
  896.         }
  897.     } else {
  898.         HWND tmp = ::GetFocus();
  899.  
  900.         if(tmp && ::IsChild(m_hWnd, tmp))
  901.             m_hWndFocus = tmp;
  902.         else
  903.             m_hWndFocus = NULL;
  904.  
  905.     }
  906.     //TRACE2("CNetscapeView::OnActivateView: bActivate = %d, m_hWndFocus = %d\n", bActivate, m_hWndFocus);
  907. }
  908.  
  909. void CNetscapeView::OnActivateFrame(UINT nState, CFrameWnd* /*pFrameWnd*/)
  910. {
  911.     if (nState == WA_INACTIVE) {
  912.         HWND tmp = ::GetFocus();
  913.  
  914.         if(tmp && ::IsChild(m_hWnd, tmp))
  915.             m_hWndFocus = tmp;
  916.         else
  917.             m_hWndFocus = NULL;
  918.     }
  919.     //TRACE1("CNetscapeView::OnActivateFrame: m_hWndFocus = %d\n", m_hWndFocus);
  920. }
  921.  
  922. FILE * fpSeriousHackery = NULL;
  923.  
  924.  
  925. // We just got focus
  926. // See who wants it
  927. //
  928. void CNetscapeView::OnSetFocus(CWnd *pOldWin)   
  929. {
  930.    if (m_pChild)
  931.    {
  932.       m_pChild->SetFocus();
  933.       return;
  934.    }
  935.     // See if an active OLE item used to have focus
  936.     if(GetDocument() != NULL)    {
  937.         CNetscapeCntrItem *pItem = (CNetscapeCntrItem *)GetDocument()->GetInPlaceActiveItem(this);
  938.         if(pItem != NULL && pItem->GetItemState() == COleClientItem::activeUIState)   {
  939.             //  Active item, give it focus.
  940.             CWnd *pWnd = pItem->GetInPlaceWindow();
  941.             if(pWnd != NULL)    {
  942.                 pWnd->SetFocus();
  943.                 return;
  944.             }
  945.         }
  946.     }
  947.  
  948.     // Did a form element used to have focus?
  949.     if(m_hWndFocus && ::IsWindow(m_hWndFocus)) {
  950.         ::SetFocus(m_hWndFocus);
  951.         return;
  952.     }                           
  953.  
  954.     // No one wants it.  Just pass it to the base class
  955.     CGenericView::OnSetFocus(pOldWin);
  956. }
  957.  
  958. //////////////////////////////////////////////////////////////////////////////
  959. // Drag from the Bitmap Menu item
  960. void CNetscapeView::OnCopyCurrentURL()
  961. {
  962.     if ( GetContext() ) {
  963.         GetContext()->CopyCurrentURL();
  964.     }
  965. }
  966.  
  967. /////////////////////////////////////////////////////////////////////////
  968. CViewDropSource::CViewDropSource(UINT nDragType)
  969.     : m_nDragType(nDragType) 
  970. {
  971. }
  972.  
  973. SCODE CViewDropSource::GiveFeedback(DROPEFFECT dropEffect)
  974. {
  975.     if( dropEffect != DROPEFFECT_COPY &&
  976.         dropEffect != DROPEFFECT_MOVE ){
  977.             return COleDropSource::GiveFeedback(dropEffect);
  978.     }
  979.     BOOL bCopy = (dropEffect == DROPEFFECT_COPY);
  980.  
  981.     switch ( m_nDragType ) {
  982.         case FE_DRAG_TEXT:
  983.             SetCursor(theApp.LoadCursor( bCopy ?
  984.                         IDC_TEXT_COPY : IDC_TEXT_MOVE));
  985.             break;
  986.         case FE_DRAG_HTML:
  987.             SetCursor(theApp.LoadCursor( bCopy ?
  988.                         IDC_HTML_COPY : IDC_HTML_MOVE));
  989.             break;
  990.         case FE_DRAG_TABLE:
  991.             SetCursor(theApp.LoadCursor( bCopy ?
  992.                         IDC_TABLE_COPY : IDC_TABLE_MOVE));
  993.             break;
  994.         case FE_DRAG_LINK:
  995.             SetCursor(theApp.LoadCursor( bCopy ?
  996.                         IDC_LINK_COPY : IDC_LINK_MOVE));
  997.             break;
  998.         case FE_DRAG_IMAGE:
  999.             SetCursor(theApp.LoadCursor( bCopy ?
  1000.                         IDC_IMAGE_COPY : IDC_IMAGE_MOVE));
  1001.             break;
  1002.         default:
  1003.             return COleDropSource::GiveFeedback(dropEffect);
  1004.     }
  1005.     return NOERROR;
  1006. }
  1007.  
  1008. void CNetscapeView::OnSize ( UINT nType, int cx, int cy )
  1009. {
  1010.     CGenericView::OnSize ( nType, cx, cy );
  1011.     if ( m_pChild )
  1012.     {
  1013.         ShowScrollBar ( SB_BOTH, FALSE );
  1014.         CRect rect ( 0, 0, cx, cy );
  1015.         GetClientRect(rect);
  1016.         m_pChild->MoveWindow ( rect );
  1017.     }
  1018. }
  1019.  
  1020. //////////////////////////////////////////////////////////////////////////////
  1021. CViewDropTarget::CViewDropTarget() 
  1022. {
  1023. }
  1024.  
  1025.  
  1026. typedef struct drag_closure {
  1027.     char        * tmpUrl;
  1028.     char        ** jsUrl;
  1029.     CNetscapeView    * cView;
  1030. } drag_closure;
  1031.  
  1032. /* Mocha has processed the event handler for the drop event.  Now come back and execute
  1033.  * the drop files call if EVENT_OK or cleanup and go away.
  1034.  */
  1035. static void
  1036. win_on_drop_callback(MWContext * pContext, LO_Element * pEle, int32 event,
  1037.                      void * pObj, ETEventStatus status)
  1038. {
  1039.     char * tmpUrl;
  1040.     
  1041.     drag_closure * pClose = (drag_closure *) pObj;
  1042.     tmpUrl = pClose->tmpUrl;
  1043.  
  1044.     // make sure document hasn't gone away or event cancelled
  1045.     if(status == EVENT_PANIC || status == EVENT_CANCEL) {
  1046.     XP_FREE(pClose->jsUrl[0]);
  1047.         XP_FREE(pClose->jsUrl);
  1048.         XP_FREE(pClose);
  1049.         XP_FREE(tmpUrl);
  1050.     return;
  1051.     }
  1052.  
  1053.     // find out who we are
  1054.     CNetscapeView * cView = pClose->cView;
  1055.     
  1056.     cView->GetContext()->NormalGetUrl(tmpUrl);
  1057.    
  1058.     XP_FREE(pClose->jsUrl[0]);
  1059.     XP_FREE(pClose->jsUrl);
  1060.     XP_FREE(pClose);
  1061.     XP_FREE(tmpUrl);
  1062.     return;
  1063. }
  1064.  
  1065.  
  1066. BOOL CViewDropTarget::OnDrop(CWnd* pWnd, 
  1067.                 COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
  1068. {
  1069.  
  1070.     if(!pDataObject || !pWnd)
  1071.         return(FALSE);
  1072.  
  1073. #ifdef XP_WIN32
  1074.     // we only handle text at the moment
  1075.     if(! (pDataObject->IsDataAvailable(CF_TEXT) || pDataObject->IsDataAvailable(CF_UNICODETEXT)))
  1076.         return(FALSE);
  1077. #else
  1078.     // we only handle text at the moment
  1079.     if(!pDataObject->IsDataAvailable(CF_TEXT))
  1080.         return(FALSE);
  1081. #endif
  1082.  
  1083.     CNetscapeView * cView = (CNetscapeView *) pWnd;
  1084.  
  1085.     BOOL bUseUnicodeData = FALSE;
  1086.     char * tmpUrl;
  1087.  
  1088. #ifdef XP_WIN32
  1089.     // in the case of WIN32, Try CF_UNICODETEXT first
  1090.     int16 wincsid = INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo( cView->GetContext()->GetContext() ));
  1091.     if( (CS_USER_DEFINED_ENCODING != (wincsid & ~CS_AUTO)) && 
  1092.         pDataObject->IsDataAvailable(CF_UNICODETEXT)
  1093.       )
  1094.     {    // we have Unicode data and we want to use it.
  1095.         HGLOBAL hString = pDataObject->GetGlobalData(CF_UNICODETEXT);
  1096.         if(hString)
  1097.         {
  1098.             // get a pointer to the actual bytes
  1099.             char * pString = (char *) GlobalLock(hString);
  1100.             if(pString)
  1101.             {
  1102.                 // Now, let's convert the Unicode text into the datacsid encoding
  1103.                 int ucs2len = CASTINT(INTL_UnicodeLen((INTL_Unicode*)pString));
  1104.                 int    mbbufneeded = CASTINT(INTL_UnicodeToStrLen(wincsid, 
  1105.                                                             (INTL_Unicode*)pString, 
  1106.                                                             ucs2len));
  1107.                 if(NULL != (tmpUrl = (char*)XP_ALLOC(mbbufneeded + 1)))
  1108.                 {
  1109.                     INTL_UnicodeToStr(wincsid, (INTL_Unicode*)pString, ucs2len, 
  1110.                                             (unsigned char*) tmpUrl, mbbufneeded + 1);
  1111.                     bUseUnicodeData = TRUE;
  1112.                 }
  1113.                 GlobalUnlock(hString);
  1114.             }
  1115.         }
  1116.     }
  1117. #endif
  1118.     if(! bUseUnicodeData)
  1119.     {
  1120.         // get the data
  1121.         HGLOBAL hString = pDataObject->GetGlobalData(CF_TEXT);
  1122.         if(hString == NULL)
  1123.             return(FALSE);
  1124.  
  1125.         // get a pointer to the actual bytes
  1126.         char *  pString = (char *) GlobalLock(hString);    
  1127.         if(!pString)
  1128.             return(FALSE);
  1129.  
  1130.         tmpUrl = XP_STRDUP(pString);
  1131.  
  1132.         GlobalUnlock(hString);
  1133.     }
  1134.  
  1135.     drag_closure * pClosure = XP_NEW_ZAP(drag_closure);
  1136.     pClosure->cView = cView;
  1137.     pClosure->tmpUrl = tmpUrl;
  1138.     pClosure->jsUrl = (char**)XP_ALLOC(sizeof(char*));
  1139.     pClosure->jsUrl[0] = XP_STRDUP(tmpUrl);
  1140.  
  1141.     XY Point;
  1142.  
  1143.     CWinCX *pContext = cView->GetContext();
  1144.     if (pContext) {
  1145.     pContext->ResolvePoint(Point, point);
  1146.     }
  1147.     else {
  1148.     Point.x = 0;
  1149.     Point.y = 0;
  1150.     }
  1151.  
  1152.     cView->ClientToScreen( &point );
  1153.  
  1154.     JSEvent *event;
  1155.     event = XP_NEW_ZAP(JSEvent);
  1156.     event->type = EVENT_DRAGDROP;
  1157.     event->which = 0;
  1158.     event->x = 0;
  1159.     event->y = 0;
  1160.     event->docx = Point.x;
  1161.     event->docy = Point.y;
  1162.     event->screenx = point.x;
  1163.     event->screeny = point.y;
  1164.     event->modifiers = (GetKeyState(VK_SHIFT) < 0 ? EVENT_SHIFT_MASK : 0) 
  1165.             | (GetKeyState(VK_CONTROL) < 0 ? EVENT_CONTROL_MASK : 0) 
  1166.             | (GetKeyState(VK_MENU) < 0 ? EVENT_ALT_MASK : 0); 
  1167.     event->dataSize = 1;
  1168.     event->data = (void *)pClosure->jsUrl;
  1169.  
  1170.     ET_SendEvent(cView->GetContext()->GetContext(), 0, event, win_on_drop_callback, pClosure);
  1171.     return(TRUE);
  1172.  
  1173.     //Mocha will handle cleanup and free tmpUrl when it calls back in.
  1174. }
  1175.  
  1176.  
  1177. DROPEFFECT CViewDropTarget::OnDragEnter(CWnd* pWnd, 
  1178.                 COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
  1179. {
  1180.     m_nIsOKDrop = FALSE;
  1181.  
  1182. #ifdef XP_WIN32
  1183.     // we only handle text at the moment
  1184.     if(! (pDataObject->IsDataAvailable(CF_TEXT) || pDataObject->IsDataAvailable(CF_UNICODETEXT)))
  1185.         return(FALSE);
  1186. #else
  1187.     // we only handle text at the moment
  1188.     if(!pDataObject->IsDataAvailable(CF_TEXT))
  1189.         return(FALSE);
  1190. #endif
  1191.  
  1192.     // can't drag onto ourselves
  1193.     CNetscapeView * cView = (CNetscapeView *) pWnd;
  1194.     if(cView && cView->GetContext() && cView->GetContext()->IsDragging())
  1195.         return(FALSE);
  1196.  
  1197.     // looks like its OK
  1198.     m_nIsOKDrop = TRUE;
  1199.  
  1200.     // Default is to copy
  1201.     return(DROPEFFECT_COPY);
  1202.  
  1203. }
  1204.  
  1205. DROPEFFECT CViewDropTarget::OnDragOver(CWnd* pWnd, 
  1206.                 COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
  1207. {
  1208.     if(!m_nIsOKDrop)
  1209.         return(DROPEFFECT_NONE);
  1210.  
  1211.     return(DROPEFFECT_COPY);
  1212.  
  1213. }
  1214.  
  1215. void CViewDropTarget::OnDragLeave(CWnd* pWnd)
  1216. {
  1217. }
  1218.  
  1219.