gecko-dev/cmd/winfe/popup.cpp

1472 строки
42 KiB
C++
Executable File

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "stdafx.h"
#include "cntritem.h"
#include "cxsave.h"
#include "netsvw.h"
#include "mainfrm.h"
#include "shcut.h"
#include "shcutdlg.h"
#include "np.h"
#include "feembed.h"
#include "feimage.h"
#include "prefInfo.h"
#include "mailmisc.h"
#include "libi18n.h"
#include "edt.h"
//
// If the mouse is over a link or an image, allow the user to copy the URL
// to the clipboard
//
BOOL CNetscapeView::AddClipboardToPopup(CMenu * pMenu, LO_Element * pElement, BOOL bAddSeparator)
{
BOOL bLink, bImage, bCopy;
// See if it can be copied
bCopy = GetContext()->CanCopySelection();
// See if it's a link
CString csURL = GetAnchorHref(pElement);
bLink = !csURL.IsEmpty();
// See if it's an image
csURL = GetImageHref(pElement);
bImage = !csURL.IsEmpty();
if((bCopy || bLink || bImage) && bAddSeparator)
pMenu->AppendMenu(MF_SEPARATOR);
if(bCopy)
{
pMenu->AppendMenu(MF_ENABLED,
ID_EDIT_COPY,
szLoadString(ID_POPUP_COPY));
}
if (bLink) {
pMenu->AppendMenu(MF_ENABLED,
ID_POPUP_COPYLINKCLIPBOARD,
szLoadString(IDS_POPUP_COPYLINKCLIPBOARD));
}
if (bImage) {
pMenu->AppendMenu(MF_ENABLED,
ID_POPUP_COPYIMGLOC2CLIPBOARD,
szLoadString(IDS_POPUP_COPYIMGLOC2CLIPBOARD));
}
return(bLink || bCopy || bImage || bAddSeparator);
}
//
// If the mouse is over a link, add the appropriate items to the list
// If we're in a browser window then bBrowser is TRUE.
BOOL CNetscapeView::AddLinkToPopup(CMenu * pMenu, LO_Element * pElement, BOOL bBrowser)
{
UINT uState, uSaveAsState, uMailtoState;
// If there is no link just return
CString csAppend = m_csRBLink;
BOOL bLink = !csAppend.IsEmpty();
BOOL bFrame = FALSE;
CString csEntry;
if(bLink) {
// We need slightly different text in menu to differentiate between
// Browser and Editor windows
// "Browse to: "
csEntry.LoadString(IDS_POPUP_LOAD_LINK_EDT);
uState = MF_ENABLED;
LPSTR lpszSuggested =
#ifdef MOZ_MAIL_NEWS
MimeGuessURLContentName(GetContext()->GetContext(), csAppend);
#else
NULL;
#endif
if (lpszSuggested) {
csEntry += "(";
csEntry += lpszSuggested;
csEntry += ")";
XP_FREE(lpszSuggested);
} else {
WFE_CondenseURL(csAppend, 25);
csEntry += csAppend;
}
csAppend.Empty();
// Need to figure out mailto state, and any other URLs
// that won't make sense in a new window, or with
// save as.
if(strnicmp(m_csRBLink, "mailto:", 7) == 0 || strnicmp(m_csRBLink, "telnet:", 7) == 0 ||
strnicmp(m_csRBLink, "tn3270:", 7) == 0 || strnicmp(m_csRBLink, "rlogin:", 7) == 0) {
uMailtoState = MF_GRAYED;
}
else {
uMailtoState = MF_ENABLED;
}
// Need to figure out if we can do a save as without interrupting the window.
// But now, we don't need to!
uSaveAsState = MF_ENABLED;
if(uMailtoState == MF_GRAYED) {
uSaveAsState = MF_GRAYED;
}
}
// Add "Open in Editor" only if a Browser context
// because of a bug (18428) in editing link in mail message
// TODO: Lou fixed mail bug -- remove this context check later
// "Open in &New Browser Window"
CString cs;
if(bLink)
{
if(bBrowser)
cs.LoadString(IDS_POPUP_LOADLINKNEWWINDOW);
else
cs.LoadString(IDS_POPUP_LOADLINKNAVIGATOR);
pMenu->AppendMenu(uMailtoState, ID_POPUP_LOADLINKNEWWINDOW, cs);
}
if(GetContext() && GetContext()->IsGridCell())
{
cs.LoadString(IDS_POPUP_LOADFRAMENEWWINDOW);
bFrame = TRUE;
pMenu->AppendMenu(MF_ENABLED, ID_POPUP_LOADFRAMENEWWINDOW, cs);
}
#ifdef EDITOR
if(bLink)
{
int type = NET_URL_Type(m_csRBLink);
// Only add menu item if we are sure we can edit the link
if( type == FTP_TYPE_URL ||
type == HTTP_TYPE_URL ||
type == SECURE_HTTP_TYPE_URL ||
type == FILE_TYPE_URL )
{
cs.LoadString(IDS_POPUP_EDIT_LINK);
pMenu->AppendMenu(uMailtoState,ID_POPUP_EDIT_LINK, cs);
}
}
#endif /* EDITOR */
return(bLink || bFrame);
}
//
// If the mouse is over an embedded object, add the appropriate items to the list
//
BOOL CNetscapeView::AddEmbedToPopup(CMenu * pMenu, LO_Element * pElement, CL_Layer *layer, BOOL bAddSeparator)
{
#ifdef MOZ_NGLAYOUT
XP_ASSERT(0);
return FALSE;
#else
UINT uState, uInlineState, uSaveAsState;
CString csAppend, csEntry;
// Inline
CNetscapeCntrItem *pItem = NULL;
if(pElement != NULL && pElement->type == LO_EMBED) {
NPEmbeddedApp *pPluginShim = (NPEmbeddedApp *)((LO_EmbedStruct *)pElement)->objTag.FE_Data;
if(pPluginShim != NULL && wfe_IsTypePlugin(pPluginShim) == FALSE) {
pItem = (CNetscapeCntrItem *)pPluginShim->fe_data;
}
}
if(pItem != NULL && pItem->m_bLoading == FALSE && pItem->m_lpObject != NULL) {
// Embed rules!
csAppend = m_csRBEmbed;
// if there is no embeded element don't do anything
if(csAppend.IsEmpty())
return bAddSeparator;
if(bAddSeparator)
pMenu->AppendMenu(MF_SEPARATOR);
csEntry.LoadString(IDS_POPUP_LOADEMBED);
if(csAppend.IsEmpty() == TRUE || pItem->m_bBroken == TRUE) {
uState = MF_GRAYED;
uInlineState = MF_GRAYED;
uSaveAsState = MF_GRAYED;
csAppend.LoadString(IDS_POPUP_NOEMBED);
csEntry += csAppend;
}
else {
CString csActivate;
csActivate.LoadString(IDS_POPUP_ACTIVATE_EMBED);
csEntry = csActivate + csEntry;
uState = MF_ENABLED;
WFE_CondenseURL(csAppend, 25);
csEntry += csAppend;
csAppend.Empty();
// Eventually, we'll need to do selective inline loading of embedded items.
uInlineState = MF_GRAYED;
// Need to figure out if we can do a save as without interrupting the window.
uSaveAsState = MF_ENABLED;
}
pMenu->AppendMenu(uState, ID_POPUP_ACTIVATEEMBED, csEntry);
csEntry.LoadString(IDS_POPUP_SAVEEMBEDAS);
pMenu->AppendMenu(uSaveAsState, ID_POPUP_SAVEEMBEDAS, csEntry);
csEntry.LoadString(IDS_POPUP_COPYEMBEDLOC);
pMenu->AppendMenu(MF_ENABLED, ID_POPUP_COPYEMBEDLOC, csEntry);
CString csDescription;
if(pItem->m_bBroken == TRUE) {
csDescription.LoadString(IDS_UNKNOWN_DOCTYPE);
}
else {
pItem->GetUserType(USERCLASSTYPE_SHORT, csDescription);
}
csEntry.LoadString(IDS_POPUP_COPYEMBEDDATA);
csEntry += csDescription;
pMenu->AppendMenu(uState, ID_POPUP_COPYEMBEDDATA, csEntry);
// Selective inline loading to be done here.
return TRUE;
}
return bAddSeparator;
#endif /* MOZ_NGLAYOUT */
}
BOOL CNetscapeView::AddSaveItemsToPopup(CMenu * pMenu, LO_Element * pElement, CL_Layer *layer, BOOL bAddSeparator)
{
BOOL bLink, bImage;
// See if it's a link
CString csURL = m_csRBLink;
bLink = !csURL.IsEmpty();
// See if it's an image
CString imageURL = m_csRBImage;
bImage = !imageURL.IsEmpty();
CString csEntry;
if((bLink || bImage) && bAddSeparator)
pMenu->AppendMenu(MF_SEPARATOR);
if(bLink)
pMenu->AppendMenu(MF_ENABLED, ID_POPUP_SAVELINKCONTENTS,
szLoadString(IDS_POPUP_SAVELINKCONTENTS));
if(bImage && pElement && pElement->type == LO_IMAGE)
{
LO_ImageStruct *pImage = (LO_ImageStruct *)pElement;
#ifdef EDITOR
// Save the image object just like we do
// during drag n drop so we can copy
// all image data to clipboard
GetContext()->m_pLastImageObject = pImage;
#endif
// Allow them to save the image, or use it as wallpaper
// Only, can't save internal icons.
csEntry.LoadString(IDS_POPUP_SAVEIMAGEAS);
IL_ImageReq *image_req = pImage->image_req;
IL_Pixmap *image = IL_GetImagePixmap(image_req);
if (image) {
FEBitmapInfo* imageInfo = (FEBitmapInfo*)image->client_data;
if (!image->bits && imageInfo && !imageInfo->hBitmap)
pMenu->AppendMenu(MF_GRAYED,ID_POPUP_SAVEIMAGEAS, csEntry);
else
pMenu->AppendMenu( MF_ENABLED,ID_POPUP_SAVEIMAGEAS, csEntry);
}
} else {
#ifdef MOZ_NGLAYOUT
XP_ASSERT(0);
#else
LO_ImageStruct *pLOImage;
CL_Layer *parent_layer;
char *layer_name;
layer_name = CL_GetLayerName(layer);
if (layer_name && ((XP_STRCMP(layer_name, LO_BODY_LAYER_NAME) == 0) ||
(XP_STRCMP(layer_name, LO_BACKGROUND_LAYER_NAME) == 0))) {
parent_layer = CL_GetLayerParent(layer);
pLOImage = LO_GetLayerBackdropImage(parent_layer);
}
else
pLOImage = LO_GetLayerBackdropImage(layer);
if (pLOImage && pLOImage->image_req) {
CString strEntry;
m_csRBImage = (char *) pLOImage->image_url;
strEntry.LoadString(IDS_POPUP_SAVEBACKGROUNDAS);
pMenu->AppendMenu(MF_ENABLED, ID_POPUP_SAVEIMAGEAS, strEntry);
m_pRBElement = (LO_Element*)pLOImage;
PA_UNLOCK(pLOImage->image_url);
// Do your stuff here.
}
#endif
}
return (bLink || bImage || bAddSeparator);
}
void CNetscapeView::AddBrowserItemsToPopup(CMenu * pMenu, LO_Element * pElement, CL_Layer *layer)
{
CString imageURL = GetImageHref(pElement);
Bool bImage = !imageURL.IsEmpty();
CString csEntry;
if(bImage && pElement && pElement->type == LO_IMAGE)
{
LO_ImageStruct *pImage = (LO_ImageStruct *)pElement;
#ifdef EDITOR
// Save the image object just like we do
// during drag n drop so we can copy
// all image data to clipboard
GetContext()->m_pLastImageObject = pImage;
#endif
IL_ImageReq *image_req = pImage->image_req;
IL_Pixmap *image = IL_GetImagePixmap(image_req);
if (image) {
csEntry.LoadString(IDS_POPUP_SETASWALLPAPER);
pMenu->AppendMenu(GetContext()->CanWriteBitmapFile(pImage) ? MF_ENABLED : MF_GRAYED,
ID_POPUP_SETASWALLPAPER, csEntry);
}
} else {
#ifdef MOZ_NGLAYOUT
XP_ASSERT(0);
#else
// this is the case for saving backdrop image.
LO_ImageStruct *pLOImage;
CL_Layer *parent_layer;
char *layer_name;
layer_name = CL_GetLayerName(layer);
if (layer_name && ((XP_STRCMP(layer_name, LO_BODY_LAYER_NAME) == 0) ||
(XP_STRCMP(layer_name, LO_BACKGROUND_LAYER_NAME) == 0))) {
parent_layer = CL_GetLayerParent(layer);
pLOImage = LO_GetLayerBackdropImage(parent_layer);
}
else
pLOImage = LO_GetLayerBackdropImage(layer);
if (pLOImage && pLOImage->image_req) {
CString strEntry;
m_csRBImage = (char*)pLOImage->image_url;
strEntry.LoadString(IDS_POPUP_SETASWALLPAPER);
pMenu->AppendMenu(MF_ENABLED, ID_POPUP_SETASWALLPAPER, strEntry);
m_pRBElement = (LO_Element*)pLOImage;
PA_UNLOCK(pLOImage->image_url);
// Do your stuff here.
}
#endif /* MOZ_NGLAYOUT */
}
MWContext *pContext = GetContext()->GetContext();
csEntry.LoadString(IDS_POPUP_ADDLINK2BOOKMARKS);
pMenu->AppendMenu(
(SHIST_GetCurrent(&(pContext->hist)) != NULL) ? MF_ENABLED : MF_GRAYED,
ID_POPUP_ADDLINK2BOOKMARKS, csEntry);
// check for shell support and add shortcut item if available
CInternetShortcut InternetShortcut;
if (InternetShortcut.ShellSupport())
{
csEntry.LoadString(IDS_POPUP_SHORTCUT);
pMenu->AppendMenu(
(SHIST_GetCurrent(&(pContext->hist)) != NULL) ? MF_ENABLED : MF_GRAYED,
ID_POPUP_INTERNETSHORTCUT, csEntry );
}
pMenu->AppendMenu((SHIST_GetCurrent(&(pContext->hist)) != NULL) ? MF_ENABLED : MF_GRAYED,
ID_POPUP_MAILTO, szLoadString(IDS_POPUP_SENDPAGE));
}
void CNetscapeView::AddNavigateItemsToPopup(CMenu *pMenu, LO_Element * pElement, CL_Layer *layer)
{
CString csEntry;
// Back
csEntry.LoadString(IDS_POPUP_BACK);
pMenu->AppendMenu(MF_STRING, ID_NAVIGATE_BACK, csEntry);
// Forward
csEntry.LoadString(IDS_POPUP_FORWARD);
pMenu->AppendMenu(MF_STRING, ID_NAVIGATE_FORWARD, csEntry);
if(GetContext()->IsGridCell())
{
csEntry.LoadString(IDS_POPUP_RELOADFRAME);
pMenu->AppendMenu(MF_STRING, ID_NAVIGATE_RELOADCELL, csEntry);
}
else
{
csEntry.LoadString(IDS_POPUP_RELOAD);
pMenu->AppendMenu(MF_STRING, ID_NAVIGATE_RELOAD, csEntry);
}
if(!prefInfo.m_bAutoLoadImages)
{
csEntry.LoadString(IDS_POPUP_SHOWIMAGE);
pMenu->AppendMenu(MF_ENABLED, ID_POPUP_LOADIMAGEINLINE, csEntry);
}
csEntry.LoadString(IDS_POPUP_STOP);
pMenu->AppendMenu(MF_STRING, ID_NAVIGATE_INTERRUPT, csEntry);
}
//
// If the mouse is over a frame, add the appropriate items to the list
//
void CNetscapeView::AddViewItemsToPopup(CMenu * pMenu, MWContext *pContex, LO_Element * pElement)
{
if(GetContext()->IsGridCell())
{
pMenu->AppendMenu(MF_SEPARATOR);
pMenu->AppendMenu(
MF_ENABLED,
ID_VIEW_FRAME_SOURCE, szLoadString(IDS_VIEWFRAMESOURCE));
pMenu->AppendMenu(MF_ENABLED, ID_VIEW_FRAME_INFO, szLoadString(IDS_VIEWFRAMEINFO));
}
else
{
pMenu->AppendMenu(MF_SEPARATOR);
pMenu->AppendMenu(
MF_ENABLED,
ID_FILE_VIEWSOURCE, szLoadString(IDS_VIEWSOURCE));
pMenu->AppendMenu(MF_ENABLED, ID_FILE_DOCINFO, szLoadString(IDS_VIEWINFO));
}
CString csURL, csEntry;
// Make sure we have an image to begin with
csURL = m_csRBImage;
if(!csURL.IsEmpty())
{
MWContextType contentType = GetContext()->GetContext()->type;
if (contentType != MWContextDialog) {
// Allow them to view the image by itself in a separate window
csEntry.LoadString(IDS_POPUP_LOAD_IMAGE);
csEntry += ' ';
// Tack the name of the URL on to the end, but shorten it to something
// reasonable first
LPSTR lpszSuggested =
#ifdef MOZ_MAIL_NEWS
MimeGuessURLContentName(GetContext()->GetContext(), csURL);
#else
NULL;
#endif /* MOZ_MAIL_NEWS */
if (lpszSuggested) {
csEntry += "(";
csEntry += lpszSuggested;
csEntry += ")";
XP_FREE(lpszSuggested);
} else {
WFE_CondenseURL(csURL, 25);
csEntry += csURL;
}
pMenu->AppendMenu(MF_ENABLED, ID_POPUP_LOADIMAGE, csEntry);
}
}
pMenu->AppendMenu(MF_SEPARATOR);
}
//
// Add the entries to create the right mouse menu over a web
// browser window
//
void CNetscapeView::CreateWebPopup(CMenu * pMenu, LO_Element * pElement, CL_Layer *layer)
{
// Start adding relevant items to the menu.
MWContext *pContext = GetContext()->GetContext();
// If editor view-source window, don't show any popup menu.
if (pContext->edit_view_source_hack)
return;
// Don't do anything else if we're in kiosk mode.
if(!theApp.m_bKioskMode) {
//
// If we are over a link add the appropriate elements
//
if(AddLinkToPopup(pMenu, pElement, TRUE))
pMenu->AppendMenu(MF_SEPARATOR);
AddNavigateItemsToPopup(pMenu, pElement, layer);
AddViewItemsToPopup(pMenu, pContext, pElement);
AddBrowserItemsToPopup(pMenu, pElement, layer);
// Add save image and link items
AddSaveItemsToPopup(pMenu, pElement, layer, TRUE);
//
// If we are over an embedded object add the appropriate elements
//
AddEmbedToPopup(pMenu, pElement, layer, TRUE);
// Allow the user to copy URLs to the clipboard if appropriate
AddClipboardToPopup(pMenu, pElement, TRUE);
}
}
//
// Add the entries to create the right mouse menu over a news message
//
class CTestCmdUI: public CCmdUI {
public:
BOOL m_bEnabled;
CTestCmdUI() { m_bEnabled = FALSE; }
virtual void Enable(BOOL bOn = TRUE) { m_bEnabled = bOn; }
virtual void SetCheck(int nCheck = 1) {}
virtual void SetRadio(BOOL bOn = TRUE) {}
virtual void SetText(LPCSTR lpszText) {}
};
void CNetscapeView::CreateMessagePopup(CMenu * pMenu, LO_Element * pElement, CL_Layer *layer,
MWContext *pContext)
{
BOOL bAddSeparator = FALSE;
//
// If we are over a link add the appropriate elements to the list
//
bAddSeparator = AddLinkToPopup(pMenu, pElement, FALSE);
// Add Save Items
bAddSeparator = AddSaveItemsToPopup(pMenu, pElement, layer, bAddSeparator);
//
// If we are over an embedded object add the appropriate elements to the list
//
bAddSeparator = AddEmbedToPopup(pMenu, pElement, layer, bAddSeparator);
// Allow the user to copy URLs to the clipboard if appropriate
bAddSeparator = AddClipboardToPopup(pMenu, pElement, bAddSeparator);
if(bAddSeparator)
pMenu->AppendMenu(MF_SEPARATOR);
// Start adding relevant items to the menu.
// Test to see if "Post Reply" is enabled
// If so, we're in a news message
CTestCmdUI cmdUI;
cmdUI.m_nID = ID_MESSAGE_POSTREPLY;
cmdUI.DoUpdate( GetParentFrame(), FALSE );
BOOL bNews = cmdUI.m_bEnabled;
#ifdef MOZ_MAIL_NEWS
WFE_MSGBuildMessagePopup( pMenu->m_hMenu, bNews, FALSE, pContext );
#endif /* MOZ_MAIL_NEWS */
}
#ifndef MOZ_NGLAYOUT
void CNetscapeView::OnRButtonDown(UINT uFlags, CPoint cpPoint) {
// Purpose: Bring up the popup menu.
// Arguments: uFlags What meta keys are currently pressed, ignored.
// cpPoint The point at which the mouse was clicked in relative to the upper left corner of the window.
// Returns: void
// Comments: Saves the point in a class member, so other handling can occur through messages generated in the popup.
// Revision History:
// 01-20-94 rewritten GAB
//
// Call the base class to handle the click.
CGenericView::OnRButtonDown(uFlags, cpPoint);
MWContext *pContext = GetContext()->GetContext();
if (!pContext->compositor)
OnRButtonDownForLayer(uFlags, cpPoint,
(long)cpPoint.x, (long)cpPoint.y,
NULL);
}
#endif /* MOZ_NGLAYOUT */
BOOL CNetscapeView::OnRButtonDownForLayer(UINT uFlags, CPoint& cpPoint,
long lX, long lY, CL_Layer *layer) {
#ifdef MOZ_NGLAYOUT
XP_ASSERT(0);
#else
LO_Element *pElement;
HDC pDC = GetContextDC();
MWContext *pContext = GetContext()->GetContext();
if(pDC)
pElement = LO_XYToElement(ABSTRACTCX(pContext)->GetDocumentContext(), lX, lY, layer);
else
pElement = NULL;
m_pLayer = layer;
// Save the point of the click.
m_ptRBDown = cpPoint;
m_csRBLink = GetAnchorHref(pElement);
m_csRBImage = GetImageHref(pElement);
m_csRBEmbed = GetEmbedHref(pElement);
m_pRBElement = pElement;
// Create the popup.
CMenu cmPopup;
if(cmPopup.CreatePopupMenu() == 0) {
return FALSE;
}
switch(GetContext()->GetContext()->type) {
case MWContextMailMsg:
case MWContextMail:
// These two shouldn't occur
case MWContextNewsMsg:
case MWContextNews:
CreateMessagePopup(&cmPopup, pElement, layer, GetContext()->GetContext());
break;
default:
// just fall through and show the browser popup even though it
// will probably be useless
case MWContextBrowser:
CreateWebPopup(&cmPopup, pElement, layer);
break;
}
// Track the popup now.
ClientToScreen(&cpPoint);
// Certain types of contexts should not do this.
if(
GetFrame() &&
GetFrame()->GetMainContext() &&
GetFrame()->GetMainContext()->GetContext()->type != MWContextDialog) {
cmPopup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cpPoint.x, cpPoint.y,
GetParentFrame(), NULL);
}
#endif /* MOZ_NGLAYOUT */
return TRUE;
}
void CNetscapeView::GetLogicalPoint(CPoint cpPoint, long *pLX, long *pLY)
{
// Get the device context, and figure out the logical point.
HDC pDC = GetContextDC();
if(pDC) {
CPoint cpLogical = cpPoint;
::DPtoLP(pDC, &cpLogical, 1);
// Adjust the point further in context.
// Go to longs, as ints will wrap since we're in twips.
MWContext *pContext = GetContext()->GetContext();
*pLX = (long)cpLogical.x + (long)WINCX(pContext)->GetOriginX();
*pLY = (long)cpLogical.y + (long)WINCX(pContext)->GetOriginY();
}
else {
*pLX = (long)cpPoint.x;
*pLY = (long)cpPoint.y;
}
}
LO_Element *CNetscapeView::GetLayoutElement(CPoint cpPoint, CL_Layer *layer) {
#ifdef MOZ_NGLAYOUT
XP_ASSERT(0);
return NULL;
#else
// Purpose: Return the layout element under the device point.
// Arguments: cpPoint The device point.
// Returns: LO_Element * The layout element under the point, or NULL if over nothing.
// Comments: General utility function.
// Revision History:
// 01-20-95 created GAB
//
// Get the device context, and figure out the logical point.
HDC pDC = GetContextDC();
if(pDC) {
long lX, lY;
MWContext *pContext = GetContext()->GetContext();
XP_Rect bbox;
GetLogicalPoint(cpPoint, &lX, &lY);
CL_GetLayerBbox(layer, &bbox);
lX -= bbox.left;
lY -= bbox.top;
// Return the element that layout reports at this coordinate.
return(LO_XYToElement(ABSTRACTCX(pContext)->GetDocumentContext(), lX, lY, layer));
}
else {
return(NULL);
}
#endif /* MOZ_NGLAYOUT */
}
CString CNetscapeView::GetAnchorHref(LO_Element *pElement) {
// Purpose: Obtain the HREF to a layout element.
// Arguments: pElement The abstract layout element, can be NULL.
// Returns: CString The anchor, in full.
// Comments: Should handle other anchor cases as they become evident.
// Revision History:
// 01-20-95 created
//
CString csRetval;
#ifdef MOZ_NGLAYOUT
XP_ASSERT(0);
#else
if(pElement != NULL) {
switch(pElement->type) {
case LO_TEXT: {
LO_TextStruct *pText = (LO_TextStruct *)pElement;
if(pText->anchor_href && pText->anchor_href->anchor) {
csRetval = (char *)pText->anchor_href->anchor;
}
break;
}
case LO_IMAGE: {
LO_ImageStruct *pImage = (LO_ImageStruct *)pElement;
if(pImage->image_attr->usemap_name != NULL) {
CPoint cpUsemap = m_ptRBDown;
MWContext *pContext = GetContext()->GetContext();
HDC pDC = GetContextDC();
::DPtoLP(pDC, &cpUsemap, 1);
cpUsemap.x -= (int)(pImage->x + pImage->x_offset + pImage->border_width - WINCX(pContext)->GetOriginX());
cpUsemap.y -= (int)(pImage->y + pImage->y_offset + pImage->border_width - WINCX(pContext)->GetOriginY());
::LPtoDP(pDC, &cpUsemap, 1);
LO_AnchorData *pAnchorData = LO_MapXYToAreaAnchor(ABSTRACTCX(pContext)->GetDocumentContext(),
pImage, cpUsemap.x, cpUsemap.y);
if(pAnchorData != NULL && pAnchorData->anchor != NULL) {
csRetval = (char *)pAnchorData->anchor;
}
}
else if(pImage->anchor_href && pImage->anchor_href->anchor) {
csRetval = (char *)pImage->anchor_href->anchor;
// Handle ismaps
if(pImage->image_attr->attrmask & LO_ATTR_ISMAP) {
MWContext *pContext = GetContext()->GetContext();
CPoint cpIsmap = m_ptRBDown;
HDC pDC = GetContextDC();
char aNumBuf[16];
::DPtoLP(pDC, &cpIsmap, 1);
cpIsmap.x -= (int)(pImage->x + pImage->x_offset + pImage->border_width - WINCX(pContext)->GetOriginX());
cpIsmap.y -= (int)(pImage->y + pImage->y_offset + pImage->border_width - WINCX(pContext)->GetOriginY());
::LPtoDP(pDC, &cpIsmap, 1);
csRetval += '?';
_itoa(cpIsmap.x, aNumBuf, 10);
csRetval += aNumBuf;
csRetval += ',';
_itoa(cpIsmap.y, aNumBuf, 10);
csRetval += aNumBuf;
}
}
break;
}
}
}
#endif /* MOZ_NGLAYOUT */
return(csRetval);
}
CString CNetscapeView::GetImageHref(LO_Element *pElement) {
// Purpose: Obtain the HREF to a layout element.
// Arguments: pElement The abstract layout element, can be NULL.
// Returns: CString The image anchor, in full.
// Comments:
// Revision History:
// 01-20-95 created
//
CString csRetval;
if(pElement != NULL) {
switch(pElement->type) {
case LO_IMAGE: {
LO_ImageStruct *pImage = (LO_ImageStruct *)pElement;
if(pImage->image_url != NULL) {
// Check for that funky internal-external-reconnect jazz.
char *Weird = "internal-external-reconnect:";
int iWeirdLen = strlen(Weird);
if(strncmp((char *)pImage->image_url, Weird, iWeirdLen) == 0) {
// Use everything after "internal-external-reconnect:"
csRetval = ((char *) pImage->image_url) + iWeirdLen;
}
else {
csRetval = (char *)pImage->image_url;
}
}
break;
}
}
}
return(csRetval);
}
CString CNetscapeView::GetEmbedHref(LO_Element *pElement) {
// Purpose: Obtain the HREF to a layout element.
// Arguments: pElement The abstract layout element, can be NULL.
// Returns: CString The embed anchor, in full.
// Comments:
// Revision History:
// 03-05-95 created
//
CString csRetval;
if(pElement != NULL) {
switch(pElement->type) {
case LO_EMBED: {
LO_EmbedStruct *pEmbed = (LO_EmbedStruct *)pElement;
if(pEmbed->embed_src != NULL) {
csRetval = (char *)pEmbed->embed_src;
}
break;
}
}
}
return(csRetval);
}
void WFE_CondenseURL(CString& csURL, UINT uLength, BOOL bParens) {
// Purpose: Condense a URL to a given length.
// Arguments: csURL The URL to condense.
// uLength The maximum length.
// bParens Wether or not use parenthesis to surround the condesed form.
// Also specifies wether or not we need to only extract the file name.
// Returns: void
// Comments:
// Revision History:
// 01-20-95 created GAB
// 01-28-95 Modified to only take the filename off, previously left protocol and right of the URL.
// 09-24-95 Well, now we're going back to cutting out the middle....
// Parens code will only get the filename ending.
//
char *pSlash;
if(bParens == FALSE) {
pSlash = (char *)(const char *)csURL;
}
else {
// Make it two shorter right now for the ().
uLength -= 2;
// Find out if we have a forward slash in the URL, backwards.
pSlash = strrchr(csURL, '/');
if(pSlash != NULL) {
// Make sure that this isn't just one character long (directory).
if(strlen(pSlash) == 1) {
// this is a directory, attempt to use the whole URL, I guess.
pSlash = (char *)(const char *)csURL;
}
}
if(pSlash == NULL) {
// If there's no slash, attempt a : from the start (don't want to only show a port #!)
pSlash = strchr(csURL, ':');
}
if(pSlash != NULL) {
// Go one past what we've found, only if we're not at the start of the URL.
if(pSlash != (char *)(const char *)csURL) {
pSlash++;
}
}
else {
pSlash = (char *)(const char *)csURL;
}
}
// See if what we've found is longer than what we need.
if(strlen(pSlash) <= uLength) {
// No need to modify, just return what we have.
CString csTemp;
if(bParens == TRUE) {
csTemp += "(";
}
csTemp += pSlash;
if(bParens == TRUE) {
csTemp += ")";
}
csURL = csTemp;
return;
}
// Currently, we cannot do multilingual Menu, so use just treat all the menu
// is in the resource csid.
int16 guicsid = INTL_CharSetNameToID(INTL_ResourceCharSet());
char truncated[120];
if(uLength > 120)
uLength = 120;
INTL_MidTruncateString(guicsid, pSlash, truncated, uLength);
if(bParens)
{
csURL = "(";
csURL += truncated;
csURL += ")";
}
else
{
csURL = truncated;
}
}
#ifndef MOZ_NGLAYOUT
void CNetscapeView::OnPopupLoadLink() {
// Purpose: Load the link
// Arguments: void
// Returns: void
// Comments: Never get's called unless actually over a link.
// Revision History:
// 01-21-95 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
// 13-Feb-95 modified to just call builtin load function - chouck
//
MWContext * context = GetContext()->GetContext();
History_entry *he = SHIST_GetCurrent (&context->hist);
m_pContext->NormalGetUrl(m_csRBLink, (he ? he->address : NULL));
}
void CNetscapeView::OnPopupLoadLinkNewWindow() {
// Purpose: Load a link into a new window.
// Arguments: void
// Returns: void
// Comments: Never gets called, unless actually over an image.
// Need to handle image maps also.
// Revision History:
// 01-21-95 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
// 05-Jun-95 send the referred field too - chouck
//
MWContext * context = GetContext()->GetContext();
History_entry *he = SHIST_GetCurrent(&context->hist);
// Create the URL to load, assign a referrer field.
URL_Struct *pUrl = NET_CreateURLStruct(m_csRBLink, NET_DONT_RELOAD);
if(he->address != NULL) {
pUrl->referer = XP_STRDUP(he->address);
}
// Always set the window_target for a new window.
pUrl->window_target = XP_STRDUP("");
#ifdef EDITOR
// Question: Does it matter if referer and window_target are set
// if we are creating a new context?
if ( EDT_IS_EDITOR(context) ) {
if ( pUrl ) {
// Must clear this to correctly load URL into new context
pUrl->fe_data = NULL;
// Create new Context
CFE_CreateNewDocWindow(NULL, pUrl);
}
} else
#endif
CFE_CreateNewDocWindow(GetContext()->GetContext(), pUrl);
}
void CNetscapeView::OnPopupLoadFrameNewWindow()
{
MWContext *context = GetContext()->GetContext();
History_entry *he = SHIST_GetCurrent(&context->hist);
URL_Struct *pUrl;
// Create the URL to load, assign a referrer field.
if(he->address != NULL)
{
pUrl = NET_CreateURLStruct(he->address, NET_NORMAL_RELOAD);
}
// Always set the window_target for a new window.
pUrl->window_target = XP_STRDUP("");
#ifdef EDITOR
// Question: Does it matter if referer and window_target are set
// if we are creating a new context?
if ( EDT_IS_EDITOR(context) ) {
if ( pUrl ) {
// Must clear this to correctly load URL into new context
pUrl->fe_data = NULL;
// Create new Context
CFE_CreateNewDocWindow(NULL, pUrl);
}
} else
#endif
if(pUrl)
CFE_CreateNewDocWindow(GetContext()->GetContext(), pUrl);
}
#ifdef EDITOR
// Load link location in a Composer window
void CNetscapeView::OnPopupLoadLinkInEditor()
{
MWContext *pMWContext = GetContext()->GetContext();
if( pMWContext && !m_csRBLink.IsEmpty() )
{
char *pURL = (char*)LPCSTR(m_csRBLink);
// Jump to internal Target tag within Composer if possible,
// else edit link in Composer window
if( !EDT_IS_EDITOR(pMWContext) || !EDT_ScrollToTarget(pMWContext, pURL) )
FE_LoadUrl(pURL, LOAD_URL_COMPOSER);
}
}
// Load image in user-specified editor
void CNetscapeView::OnPopupEditImage()
{
if ( GetContext()->GetContext() && !m_csRBImage.IsEmpty() ) {
EditImage((char*)LPCSTR(m_csRBImage));
}
}
#endif
void CNetscapeView::OnPopupSaveLinkContentsAs() {
// Purpose: Save a link.
// Arguments: void
// Returns: void
// Comments:
// Revision History:
// 01-22-95 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
//
CSaveCX::SaveAnchorObject(m_csRBLink, NULL);
}
void CNetscapeView::OnPopupCopyLinkToClipboard() {
// Purpose: Copy a link to the clipboard.
// Arguments: void
// Returns: void
// Comments: Don't free the handle.
// Revision History:
// 01-22-95 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
//
CopyLinkToClipboard(m_hWnd, m_csRBLink);
}
#endif /* MOZ_NGLAYOUT */
void CNetscapeView::CopyLinkToClipboard(HWND hWnd, CString url)
{
CString csHref = url;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, csHref.GetLength() + 1);
char *pCopy = (char *)GlobalLock(hData);
strcpy(pCopy, csHref);
GlobalUnlock(hData);
// Also copy bookmark-formatted data so we can paste full link,
// not just text, into the Editor or bookmark window
::OpenClipboard(hWnd);
::EmptyClipboard();
::SetClipboardData(CF_TEXT, hData);
hData = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, sizeof(BOOKMARKITEM));
if(hData){
LPBOOKMARKITEM pBookmark = (LPBOOKMARKITEM)GlobalLock(hData);
PR_snprintf(pBookmark->szAnchor, sizeof(pBookmark->szAnchor), "%s",
LPCSTR(csHref));
PR_snprintf(pBookmark->szText, sizeof(pBookmark->szText), "%s",
LPCSTR(csHref));
GlobalUnlock(hData);
::SetClipboardData(RegisterClipboardFormat(NETSCAPE_BOOKMARK_FORMAT), hData);
}
::CloseClipboard();
}
#ifndef MOZ_NGLAYOUT
void CNetscapeView::OnPopupLoadImage() {
// Purpose: Load an image inline that was delayed.
// Arguments: void
// Returns: void
// Comments:
// Revision History:
// 01-22-95 created GAB
// 13-Feb-95 modified to just call builtin load function - chouck
if(GetContext()) {
MWContext * context = GetContext()->GetContext();
History_entry *he = SHIST_GetCurrent (&context->hist);
// Go up to the parent context.
CAbstractCX *pCX = ABSTRACTCX(context);
while(pCX && pCX->IsGridCell()) {
pCX = ABSTRACTCX(pCX->GetParentContext());
}
if(pCX && pCX->IsFrameContext()) {
pCX->NormalGetUrl(m_csRBImage, (he ? he->address : NULL));
}
}
}
void CNetscapeView::OnPopupLoadImageInline() {
// Purpose: Load an image inline that was delayed.
// Arguments: void
// Returns: void
// Comments:
// Revision History:
// 01-22-95 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
//
const char *pURL = m_csRBImage;
// Tell layout which image is to be force loaded.
LO_SetForceLoadImage((char*)pURL, FALSE);
m_pContext->ExplicitlyLoadThisImage(m_csRBImage);
}
void CNetscapeView::OnPopupSaveImageAs() {
// Purpose: Save the image we're over to a file.
// Arguments: void
// Returns: void
// Comments:
// Revision History:
// 01-22-94 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
//
CSaveCX::SaveAnchorObject(m_csRBImage, NULL);
}
void CNetscapeView::OnPopupSetAsWallpaper()
{
ASSERT(m_pRBElement && m_pRBElement->type == LO_IMAGE);
if (m_pRBElement->type == LO_IMAGE) {
char szFileName[_MAX_PATH + 25];
// We need to create a .BMP file in the Windows directory
GetWindowsDirectory(szFileName, sizeof(szFileName));
#ifdef XP_WIN32
strcat(szFileName, "\\Netscape Wallpaper.bmp");
#else
strcat(szFileName, "\\Netscape.bmp");
#endif
// Go ahead and write out the file
if (GetContext()->WriteBitmapFile(szFileName, &m_pRBElement->lo_image)) {
// Now ask Windows to change the wallpaper
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szFileName, SPIF_UPDATEINIFILE);
}
}
}
void CNetscapeView::OnPopupCopyImageLocationToClipboard() {
// Purpose: Copy the image's URL to the clipboard.
// Arguments: void
// Returns: void
// Comments: Don't free the handle.
// Revision History:
// 01-22-95 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
//
CString csHref = m_csRBImage;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, csHref.GetLength() + 1);
char *pCopy = (char *)GlobalLock(hData);
strcpy(pCopy, csHref);
GlobalUnlock(hData);
#ifdef EDITOR
// Also copy all data for pasting into Editor - just like drag and drop
HGLOBAL hImageData = NULL;
if ( GetContext() ) {
hImageData = WFE_CreateCopyImageData(GetContext()->GetContext(),
GetContext()->m_pLastImageObject);
}
GetContext()->m_pLastImageObject = NULL;
#endif
OpenClipboard();
::EmptyClipboard();
::SetClipboardData(CF_TEXT, hData);
#ifdef EDITOR
if (hImageData ) {
::SetClipboardData(RegisterClipboardFormat(NETSCAPE_IMAGE_FORMAT), hImageData);
}
#endif
::CloseClipboard();
}
void CNetscapeView::OnPopupActivateEmbed() {
// Purpose: Activate an embedded item.
// Arguments: void
// Returns: void
// Comments: Just about the same code as OnLButtonDblClk
// Revision History:
// 03-06-95 created GAB
CPoint cpPoint = m_ptRBDown;
// See if we are already selected in this area.
// If not, then we need to deselect any currently selected item.
CWinCX *pWinCX = GetContext();
if(pWinCX && pWinCX->m_pSelected) {
// Figure out the rect that the item covers.
long lLeft = pWinCX->m_pSelected->objTag.x + pWinCX->m_pSelected->objTag.y_offset - pWinCX->GetOriginX();
long lRight = lLeft + pWinCX->m_pSelected->objTag.width;
long lTop = pWinCX->m_pSelected->objTag.y + pWinCX->m_pSelected->objTag.y_offset - pWinCX->GetOriginY();
long lBottom = lTop + pWinCX->m_pSelected->objTag.height;
HDC pDC = pWinCX->GetContextDC();
RECT crBounds;
::SetRect(&crBounds, CASTINT(lLeft), CASTINT(lRight), CASTINT(lTop), CASTINT(lBottom));
::LPtoDP(pDC, (POINT*)&crBounds, 2);
if(FALSE == ::PtInRect(&crBounds, cpPoint)) {
OnDeactivateEmbed();
}
else {
// Same item. Don't do anything.
return;
}
}
if(m_pRBElement != NULL) {
if(m_pRBElement->type == LO_EMBED) {
LO_EmbedStruct *pLayoutData = (LO_EmbedStruct *)m_pRBElement;
NPEmbeddedApp *pPluginShim = (NPEmbeddedApp *)pLayoutData->objTag.FE_Data;
if(pPluginShim != NULL && wfe_IsTypePlugin(pPluginShim) == FALSE) {
CNetscapeCntrItem *pItem = (CNetscapeCntrItem *)pPluginShim->fe_data;
// Make sure we can load this.
if(pItem->m_bBroken == FALSE && pItem->m_bDelayed == FALSE && pItem->m_bLoading == FALSE) {
// We have an active selection.
pWinCX->m_pSelected = pLayoutData;
long lVerb = OLEIVERB_PRIMARY;
BeginWaitCursor();
pItem->Activate(lVerb, this);
EndWaitCursor();
// If it's not in place active, then we don't care about it, as it's UI is being
// handled elsewhere.
if(pItem->IsInPlaceActive() == FALSE) {
pWinCX->m_pSelected = NULL;
}
}
}
}
}
}
void CNetscapeView::OnPopupSaveEmbedAs() {
// Purpose: Save the embed we're over to a file.
// Arguments: void
// Returns: void
// Comments:
// Revision History:
// 01-22-94 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
// 02-06-95 modified to handle embeds.
//
CSaveCX::SaveAnchorObject(m_csRBEmbed, NULL);
}
void CNetscapeView::OnPopupCopyEmbedLocationToClipboard() {
// Purpose: Copy the embed's URL to the clipboard.
// Arguments: void
// Returns: void
// Comments: Don't free the handle.
// Revision History:
// 01-22-95 created GAB
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
// 02-06-95 modified to handle embeds
//
CString csHref = m_csRBEmbed;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, csHref.GetLength() + 1);
char *pCopy = (char *)GlobalLock(hData);
strcpy(pCopy, csHref);
GlobalUnlock(hData);
OpenClipboard();
::EmptyClipboard();
::SetClipboardData(CF_TEXT, hData);
::CloseClipboard();
}
void CNetscapeView::OnPopupCopyEmbedToClipboard() {
// Purpose: Copy the embed's data to the clipboard.
// Arguments: void
// Returns: void
// Comments:
// Revision History:
// 02-06-95 modified to handle embeds, created GAB
//
if(m_pRBElement != NULL) {
if(m_pRBElement->type == LO_EMBED) {
LO_EmbedStruct *pLayoutData = (LO_EmbedStruct *)m_pRBElement;
NPEmbeddedApp *pPluginShim = (NPEmbeddedApp *)pLayoutData->objTag.FE_Data;
if(pPluginShim != NULL && wfe_IsTypePlugin(pPluginShim) == FALSE) {
CNetscapeCntrItem *pItem = (CNetscapeCntrItem *)pPluginShim->fe_data;
// Make sure we can copy this.
if(pItem->m_bBroken == FALSE && pItem->m_bDelayed == FALSE && pItem->m_bLoading == FALSE) {
// Do it.
pItem->CopyToClipboard(FALSE);
}
}
}
}
}
#endif /* MOZ_NGLAYOUT */
void CNetscapeView::CreateTextAndAnchor(CString &csText, CString &csAnchor)
{
// Purpose: Merge common code from OnPopupAddLinkToBookmarks and OnPopupInternetShortCut
//
//
// Revision History:
// 02-11-96 created
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
//
// See if we are over some text that is a link
LO_TextStruct * text_struct = (LO_TextStruct *) m_pRBElement;
LO_ImageStruct * image_struct = (LO_ImageStruct *) m_pRBElement;
CString csAppend = m_csRBLink;
if(text_struct && text_struct->type == LO_TEXT && text_struct->anchor_href)
{
csText = (char *)text_struct->text;
csAnchor = m_csRBLink;
}
else if(image_struct && image_struct->type == LO_IMAGE && image_struct->anchor_href)
{
WFE_CondenseURL(csAppend,25);
csText = csAppend;
csAnchor = m_csRBLink;
}
else
{
MWContext *context = GetContext()->GetContext();
History_entry *h = SHIST_GetCurrent (&context->hist);
URL_Struct *url = SHIST_CreateURLStructFromHistoryEntry (context, h);
if ((h != NULL) && (url != NULL))
{
csText = h->title;
csAnchor = url->address;
} /* end if */
}
if (!csText.GetLength() )
{
csText = csAnchor;
WFE_CondenseURL(csText,25);
}
}
#ifndef MOZ_NGLAYOUT
void CNetscapeView::OnPopupAddLinkToBookmarks()
{
// Purpose: Add the link we're under to the bookmarks.
// Arguments: void
// Returns: void
// Comments: Never gets called, unless actually over a link.
// The bookmark is not going in the correct place
// Revision History:
// 01-21-95 created
// 01-24-95 modified to not query layout again for the element, in case a load occured in between.
//
CString csText, csAnchor;
CreateTextAndAnchor(csText, csAnchor);
if (csAnchor.GetLength()) {
HT_AddBookmark((char*)(const char*)csAnchor, (char*)(const char*)csText);
}
}
void CNetscapeView::OnPopupInternetShortcut() {
CString csText, csAnchor;
CreateTextAndAnchor(csText, csAnchor);
if (csAnchor.GetLength()) {
const char * szText = (const char *) csText;
const char * szAnchor = (const char *) csAnchor;
CShortcutDialog ShortcutDialog ( this, (char *)szText, (char *)szAnchor );
if ( ShortcutDialog.DoModal ( ) == IDOK )
{
CInternetShortcut InternetShortcut (
ShortcutDialog.GetDescription ( ),
(char *)szAnchor );
}
}
}
void CNetscapeView::OnPopupMailTo() {
// Pass this off to the context for handling.
if(GetContext()) {
GetContext()->MailDocument();
}
}
#endif /* MOZ_NGLAYOUT */