mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 12:37:37 +00:00
1326 lines
36 KiB
C++
1326 lines
36 KiB
C++
/* -*- 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.
|
|
*/
|
|
/*
|
|
MsgView.cpp -- class for displaying the actual text (well, html) of a message.
|
|
Created: Chris Toshok <toshok@netscape.com>, 7-Aug-96.
|
|
*/
|
|
|
|
|
|
|
|
#include "MsgView.h"
|
|
#include "FolderMenu.h"
|
|
#include "xpassert.h"
|
|
#include "xfe.h"
|
|
#include "msgcom.h"
|
|
#include "xpgetstr.h"
|
|
#include "prefapi.h"
|
|
|
|
#if defined(USE_ABCOM)
|
|
#include "ABListSearchView.h"
|
|
#endif
|
|
|
|
#include "ViewGlue.h"
|
|
#include "MNSearchFrame.h"
|
|
#include "ThreadFrame.h"
|
|
#include "ThreadView.h"
|
|
#include "ThreePaneView.h"
|
|
#include "MozillaApp.h" // to get the MsgFrame
|
|
#include "Xfe/Xfe.h"
|
|
#include <intl_csi.h> /* to get/set doc_csid/win_csid */
|
|
|
|
#include "prefs.h"
|
|
|
|
#include <Xm/Label.h>
|
|
|
|
#ifdef DEBUG_toshok
|
|
#define D(x) x
|
|
#else
|
|
#define D(x)
|
|
#endif
|
|
|
|
extern int MK_MSG_CANCEL_MESSAGE;
|
|
|
|
extern "C"
|
|
{
|
|
void fe_print_cb (Widget widget, XtPointer closure, XtPointer call_data);
|
|
}
|
|
|
|
MenuSpec XFE_MsgView::separator_spec[] = {
|
|
MENU_SEPARATOR,
|
|
{ NULL }
|
|
};
|
|
|
|
MenuSpec XFE_MsgView::repl_spec[] = {
|
|
// Setting the call data to non-null is a signal to commandToString
|
|
// not to reset the menu string
|
|
{ xfeCmdReplyToSender, PUSHBUTTON, NULL, NULL, False, "reply-to-sender" },
|
|
{ xfeCmdReplyToAll, PUSHBUTTON, NULL, NULL, False, "reply-to-all" },
|
|
{ xfeCmdForwardMessage, PUSHBUTTON },
|
|
{ xfeCmdForwardMessageQuoted, PUSHBUTTON },
|
|
{ xfeCmdForwardMessageInLine, PUSHBUTTON },
|
|
{ NULL }
|
|
};
|
|
|
|
MenuSpec XFE_MsgView::addr_spec[] = {
|
|
{ "addToAddrBkSubmenu", CASCADEBUTTON, (MenuSpec*)&addToAddrbk_submenu_spec },
|
|
{ NULL }
|
|
};
|
|
|
|
MenuSpec XFE_MsgView::filemsg_spec[] = {
|
|
{ "fileSubmenu", DYNA_CASCADEBUTTON, NULL, NULL, False, (void*)xfeCmdMoveMessage, XFE_FolderMenu::generate },
|
|
{ xfeCmdDeleteMessage, PUSHBUTTON },
|
|
{ xfeCmdSaveMessagesAs, PUSHBUTTON },
|
|
{ xfeCmdPrint, PUSHBUTTON },
|
|
{ NULL }
|
|
};
|
|
|
|
MenuSpec XFE_MsgView::openLinkNew_spec[] = {
|
|
{ xfeCmdOpenLinkNew , PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::openLinkEdit_spec[] = {
|
|
{ xfeCmdOpenLinkEdit, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::showImage_spec[] = {
|
|
{ xfeCmdShowImage, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::stopLoading_spec[] = {
|
|
{ xfeCmdStopLoading, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::openImage_spec[] = {
|
|
{ xfeCmdOpenImage, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::saveLink_spec[] = {
|
|
{ xfeCmdSaveLink, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::saveImage_spec[] = {
|
|
{ xfeCmdSaveImage, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::copy_spec[] = {
|
|
{ xfeCmdCopy, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::copyLink_spec[] = {
|
|
{ xfeCmdCopyLink, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
MenuSpec XFE_MsgView::copyImage_spec[] = {
|
|
{ xfeCmdCopyImage, PUSHBUTTON },
|
|
{ NULL },
|
|
};
|
|
|
|
|
|
MenuSpec XFE_MsgView::addToAddrbk_submenu_spec[] = {
|
|
{ xfeCmdAddSenderToAddressBook, PUSHBUTTON },
|
|
{ xfeCmdAddAllToAddressBook, PUSHBUTTON },
|
|
{ NULL }
|
|
};
|
|
|
|
const char *XFE_MsgView::messageHasChanged = "XFE_MsgView::messageHasChanged";
|
|
const char *XFE_MsgView::lastMsgDeleted = "XFE_MsgView::lastMsgDeleted";
|
|
const char *XFE_MsgView::spacebarAtMsgBottom = "XFE_MsgView::spacebarAtMsgBottom";
|
|
|
|
XFE_MsgView::XFE_MsgView(XFE_Component *toplevel_component,
|
|
Widget parent,
|
|
XFE_View *parent_view,
|
|
MWContext *context,
|
|
MSG_Pane *p)
|
|
: XFE_MNView(toplevel_component, parent_view, context, p)
|
|
{
|
|
|
|
m_frameDeleted = False;
|
|
m_updateThread = False;
|
|
|
|
// create common parent for pane and attachment panel
|
|
Widget panedW=XmCreatePanedWindow(parent,"msgViewPane",NULL,0);
|
|
XtVaSetValues(panedW,
|
|
XmNshadowThickness,0,
|
|
XmNmarginWidth,0,
|
|
XmNmarginHeight,0,
|
|
NULL);
|
|
|
|
|
|
m_htmlView = new XFE_HTMLView(toplevel_component, panedW, this, m_contextData);
|
|
addView(m_htmlView);
|
|
|
|
// create attachment panel
|
|
m_attachApplHeight=0;
|
|
m_attachUserHeight=0;
|
|
m_attachPanel = new XFE_ReadAttachPanel(m_contextData);
|
|
m_attachPanel->createWidgets(panedW);
|
|
XtVaSetValues(m_attachPanel->getBaseWidget(),XmNskipAdjust,TRUE,NULL);
|
|
m_attachPanel->setPaneHeight(1);
|
|
|
|
/* test frame type
|
|
*/
|
|
XFE_Frame *frame = (XFE_Frame*)m_toplevel;
|
|
if (frame &&
|
|
FRAME_MAILNEWS_MSG == frame->getType()) {
|
|
/* standalone frame
|
|
*/
|
|
frame->registerInterest(XFE_Frame::allConnectionsCompleteCallback,
|
|
this,
|
|
(XFE_FunctionNotification)allConnectionsComplete_cb);
|
|
}/* if */
|
|
|
|
m_htmlView->registerInterest(XFE_HTMLView::spacebarAtPageBottom,
|
|
this,
|
|
(XFE_FunctionNotification)spaceAtMsgEnd_cb);
|
|
|
|
m_htmlView->registerInterest(XFE_HTMLView::popupNeedsShowing,
|
|
this,
|
|
(XFE_FunctionNotification)showPopup_cb);
|
|
|
|
XFE_MozillaApp::theApp()->registerInterest(XFE_MozillaApp::refreshMsgWindow,
|
|
this,
|
|
(XFE_FunctionNotification)refresh_cb);
|
|
|
|
if (!p)
|
|
setPane(MSG_CreateMessagePane(m_contextData,
|
|
XFE_MNView::getMaster()));
|
|
|
|
m_folderInfo = NULL;
|
|
m_messageKey = MSG_MESSAGEKEYNONE;
|
|
|
|
m_popup = NULL;
|
|
|
|
m_htmlView->show();
|
|
|
|
#if defined(USE_ABCOM)
|
|
int error =
|
|
AB_SetShowPropertySheetForEntryFunc((MSG_Pane *) m_pane,
|
|
&XFE_ABListSearchView::ShowPropertySheetForEntryFunc);
|
|
#endif /* USE_ABCOM */
|
|
|
|
setBaseWidget(panedW);
|
|
}
|
|
|
|
XFE_MsgView::~XFE_MsgView()
|
|
{
|
|
|
|
if (m_attachPanel) {
|
|
delete m_attachPanel;
|
|
m_attachPanel=NULL;
|
|
}
|
|
|
|
if (m_popup)
|
|
delete m_popup;
|
|
|
|
/* unregister from frame
|
|
*/
|
|
/* test frame type
|
|
*/
|
|
XFE_Frame *frame = (XFE_Frame*)m_toplevel;
|
|
if (frame &&
|
|
FRAME_MAILNEWS_MSG == frame->getType()) {
|
|
/* standalone frame
|
|
*/
|
|
frame->unregisterInterest(XFE_Frame::allConnectionsCompleteCallback,
|
|
this,
|
|
(XFE_FunctionNotification)allConnectionsComplete_cb);
|
|
}/* if */
|
|
|
|
m_htmlView->unregisterInterest(XFE_HTMLView::spacebarAtPageBottom,
|
|
this,
|
|
(XFE_FunctionNotification)spaceAtMsgEnd_cb);
|
|
|
|
m_htmlView->unregisterInterest(XFE_HTMLView::popupNeedsShowing,
|
|
this,
|
|
(XFE_FunctionNotification)showPopup_cb);
|
|
|
|
XFE_MozillaApp::theApp()->unregisterInterest(XFE_MozillaApp::refreshMsgWindow,
|
|
this,
|
|
(XFE_FunctionNotification)refresh_cb);
|
|
|
|
destroyPane();
|
|
|
|
// XFE_View destroys m_htmlView for us.
|
|
}
|
|
|
|
XFE_CALLBACK_DEFN(XFE_MsgView, allConnectionsComplete)(XFE_NotificationCenter *,
|
|
void *,
|
|
void *)
|
|
{
|
|
/* 1. check if deleted/filed
|
|
*/
|
|
if (m_updateThread) {
|
|
/* 2. get threadframe with
|
|
* XFE_ThreadFrame::frameForInfo(MSG_FolderInfo *info)
|
|
*/
|
|
MSG_FolderInfo *folderInfo = MSG_GetCurFolder(m_pane);
|
|
XFE_ThreadFrame *tFrame =
|
|
XFE_ThreadFrame::frameForInfo(folderInfo);
|
|
if (tFrame) {
|
|
/* 3. urge to update msg line and body
|
|
*/
|
|
#ifdef USE_3PANE
|
|
XFE_ThreadView *tview = 0;
|
|
XFE_ThreePaneView* tpview = (XFE_ThreePaneView*)tFrame->getView();
|
|
if (tpview)
|
|
tview = (XFE_ThreadView*)tpview->getThreadView();
|
|
#else
|
|
XFE_ThreadView *tview =
|
|
(XFE_ThreadView *) tFrame->getView();
|
|
#endif
|
|
if (tview)
|
|
tview->processCmdQueue();
|
|
}/* if tFrame */
|
|
m_updateThread = False;
|
|
}/* if */
|
|
}
|
|
|
|
void
|
|
XFE_MsgView::loadMessage(MSG_FolderInfo *info,
|
|
MessageKey key)
|
|
{
|
|
|
|
MSG_FolderLine folderLine;
|
|
|
|
m_folderInfo = info;
|
|
m_messageKey = key;
|
|
|
|
MSG_GetFolderLineById(XFE_MNView::getMaster(), m_folderInfo, &folderLine);
|
|
|
|
if (folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP
|
|
|| folderLine.flags & MSG_FOLDER_FLAG_CATEGORY)
|
|
m_displayingNewsgroup = TRUE;
|
|
else
|
|
m_displayingNewsgroup = FALSE;
|
|
|
|
|
|
MSG_LoadMessage(m_pane, info, MSG_MESSAGEKEYNONE);
|
|
|
|
// set up attachment notify callback
|
|
static MSG_MessagePaneCallbacks attachmentCb = {
|
|
XFE_MsgView::AttachmentCountCb,
|
|
XFE_MsgView::ToggleAttachmentPanelCb
|
|
};
|
|
MSG_SetMessagePaneCallbacks(m_pane,&attachmentCb,(void*)this);
|
|
|
|
// remove previous message's attachments before displaying next message
|
|
if (m_attachPanel) {
|
|
m_attachPanel->removeAllAttachments();
|
|
m_attachPanel->setPaneHeight(1);
|
|
}
|
|
|
|
// reset panel height memory for next message
|
|
m_attachApplHeight=0;
|
|
m_attachUserHeight=0;
|
|
|
|
MSG_LoadMessage(m_pane, info, key);
|
|
|
|
}
|
|
|
|
|
|
// called as each attachment is processed
|
|
void
|
|
XFE_MsgView::AttachmentCountCb(MSG_Pane*,void *closure,int32 count,XP_Bool done)
|
|
{
|
|
if (closure) {
|
|
XFE_MsgView *m=(XFE_MsgView*)closure;
|
|
m->attachmentCountCb(count,done);
|
|
}
|
|
}
|
|
|
|
|
|
// show panel as soon as we detect attachments, display attachment icons when
|
|
// all attachments have been loaded.
|
|
void
|
|
XFE_MsgView::attachmentCountCb(int32 count,XP_Bool done)
|
|
{
|
|
if (count>0) {
|
|
// Prepare to display attachment panel if there is at least 1 attachment
|
|
// The panel will be shown as soon as we detect attachments, but will fill
|
|
// up only when all attachments are loaded. Gives user early-warning of
|
|
// attachments. If we held off managing panel until all attachments
|
|
// are loaded, it will cause unexpected relayout after user has started
|
|
// reading body of message.
|
|
|
|
// erase previous message attachments
|
|
m_attachPanel->removeAllAttachments();
|
|
|
|
// add icons only when all attachments have been loaded
|
|
if (done) {
|
|
MSG_AttachmentData* data;
|
|
done = FALSE;
|
|
MSG_GetViewedAttachments(m_pane, &data, &done);
|
|
XP_ASSERT(done);
|
|
if (data) {
|
|
m_attachPanel->addAttachments(m_pane,data);
|
|
m_attachPanel->updateDisplay();
|
|
}
|
|
|
|
// if user has tried to resize panel blindly, then
|
|
// expand it to the preferred height. This ignores
|
|
// their guess, but they were probably wrong anyway,
|
|
// and should have been more patient. Yeah.
|
|
m_attachApplHeight=0;
|
|
m_attachUserHeight=0;
|
|
if (m_attachPanel->getPaneHeight()<10) {
|
|
// panel effectively closed. make it completely closed for neatness.
|
|
m_attachPanel->setPaneHeight(1);
|
|
}
|
|
else {
|
|
// panel is open, reset height to ideal
|
|
setAttachPrefHeight();
|
|
}
|
|
}
|
|
|
|
// manage attachment panel
|
|
m_attachPanel->show();
|
|
|
|
}
|
|
else {
|
|
// count==0 - either load is in-progress, or there are no attachments
|
|
if (done) {
|
|
// definitely no attachments - hide attachment panel and
|
|
// remove old attachment data
|
|
if (m_attachPanel) {
|
|
m_attachPanel->hide();
|
|
m_attachPanel->removeAllAttachments();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// called when user clicks attachment icon in message header
|
|
void
|
|
XFE_MsgView::ToggleAttachmentPanelCb(MSG_Pane*,void *closure)
|
|
{
|
|
if (closure) {
|
|
XFE_MsgView *m=(XFE_MsgView*)closure;
|
|
m->toggleAttachmentPanelCb();
|
|
}
|
|
}
|
|
|
|
void
|
|
XFE_MsgView::toggleAttachmentPanelCb()
|
|
{
|
|
if (!m_attachPanel)
|
|
return;
|
|
|
|
int currentHeight=m_attachPanel->getPaneHeight();
|
|
|
|
if (currentHeight<10) {
|
|
// expand attachment panel
|
|
// if user hasn't set size, choose size to show all attachments
|
|
if (!m_attachUserHeight)
|
|
setAttachPrefHeight();
|
|
else
|
|
m_attachPanel->setPaneHeight(m_attachUserHeight);
|
|
}
|
|
else {
|
|
// contract attachment panel
|
|
|
|
// if user changed pane size, remember it
|
|
if (!m_attachApplHeight || currentHeight!=m_attachApplHeight)
|
|
m_attachUserHeight=currentHeight;
|
|
|
|
m_attachPanel->setPaneHeight(1);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
XFE_MsgView::setAttachPrefHeight()
|
|
{
|
|
if (!m_attachPanel || !getBaseWidget())
|
|
return;
|
|
|
|
// pick a default height for the attachment panel.
|
|
// Make large enough to view all attachments without
|
|
// scrolling, up to a maximum of 70% of the message
|
|
// pane height - don't want to obscure the attachment
|
|
// show/hide link in the message header.
|
|
|
|
Dimension parentHeight;
|
|
XtVaGetValues(getBaseWidget(),XmNheight,&parentHeight,NULL);
|
|
|
|
int prefHeight=m_attachPanel->getPreferredHeight();
|
|
|
|
if (prefHeight > (7*parentHeight/10))
|
|
prefHeight=(7*parentHeight/10);
|
|
|
|
m_attachApplHeight=prefHeight;
|
|
m_attachPanel->setPaneHeight(m_attachApplHeight);
|
|
}
|
|
|
|
MSG_FolderInfo *
|
|
XFE_MsgView::getFolderInfo()
|
|
{
|
|
return m_folderInfo;
|
|
}
|
|
|
|
MessageKey
|
|
XFE_MsgView::getMessageKey()
|
|
{
|
|
return m_messageKey;
|
|
}
|
|
|
|
void
|
|
XFE_MsgView::paneChanged(XP_Bool asynchronous,
|
|
MSG_PANE_CHANGED_NOTIFY_CODE code,
|
|
int32 value)
|
|
{
|
|
switch (code)
|
|
{
|
|
case MSG_PaneNotifyFolderDeleted:
|
|
{
|
|
#ifndef USE_3PANE
|
|
/* test frame type
|
|
*/
|
|
XFE_Frame *frame = (XFE_Frame*)m_toplevel;
|
|
if (frame &&
|
|
FRAME_MAILNEWS_MSG == frame->getType()) {
|
|
/* standalone frame
|
|
*/
|
|
if (!m_frameDeleted) {
|
|
frame->delete_response();
|
|
m_frameDeleted = True;
|
|
}/* if */
|
|
|
|
}/* if */
|
|
#endif
|
|
}
|
|
/* shall we update banner or simply return? NO
|
|
*/
|
|
return;
|
|
|
|
case MSG_PaneNotifyMessageLoaded:
|
|
notifyInterested(messageHasChanged, (void*)value);
|
|
|
|
{
|
|
MSG_FolderInfo *folderInfo = MSG_GetCurFolder(m_pane);
|
|
|
|
/* We need to update this to reflect what the real folderInfo is
|
|
*/
|
|
m_folderInfo = folderInfo;
|
|
|
|
MessageKey key = (MessageKey) value;
|
|
|
|
if (MSG_GetBacktrackState(m_pane) == MSG_BacktrackIdle)
|
|
MSG_AddBacktrackMessage(m_pane, folderInfo, key);
|
|
else
|
|
MSG_SetBacktrackState(m_pane, MSG_BacktrackIdle);
|
|
}
|
|
break;
|
|
case MSG_PaneNotifyLastMessageDeleted:
|
|
notifyInterested(lastMsgDeleted, (void*)value);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
XFE_MNView::paneChanged(asynchronous, code, value);
|
|
}
|
|
|
|
Boolean
|
|
XFE_MsgView::isCommandSelected( CommandType cmd, void *calldata, XFE_CommandInfo*)
|
|
{
|
|
MSG_CommandType msg_cmd;
|
|
XP_Bool selectable = False;;
|
|
|
|
msg_cmd = commandToMsgCmd(cmd);
|
|
|
|
if (msg_cmd != (MSG_CommandType)~0)
|
|
{
|
|
|
|
if ( MSG_GetToggleStatus(m_pane, msg_cmd, NULL, 0 ) == MSG_Checked)
|
|
selectable = True;
|
|
return (Boolean)selectable;
|
|
}
|
|
return XFE_MNView::isCommandSelected(cmd, calldata);
|
|
}
|
|
|
|
Boolean
|
|
XFE_MsgView::isCommandEnabled(CommandType cmd, void *calldata, XFE_CommandInfo*)
|
|
{
|
|
#define IS_CMD(command) cmd == (command)
|
|
|
|
XP_Bool selectable = FALSE;
|
|
|
|
// DeleteMessage stands for CancelMessage in the ThreadView,
|
|
// so intercept it early:
|
|
if ( (IS_CMD(xfeCmdDeleteMessage) || IS_CMD(xfeCmdCancelMessages))
|
|
&& isDisplayingNews() )
|
|
{
|
|
MSG_CommandStatus(m_pane, MSG_CancelMessage,
|
|
NULL, 0,
|
|
&selectable, NULL, NULL, NULL);
|
|
return selectable;
|
|
}
|
|
#if defined(USE_ABCOM)
|
|
if (IS_CMD(xfeCmdAddSenderToAddressBook)||
|
|
IS_CMD(xfeCmdAddAllToAddressBook)) {
|
|
|
|
XP_List *abList = AB_AcquireAddressBookContainers(m_contextData);
|
|
XP_ASSERT(abList);
|
|
int nDirs = XP_ListCount(abList);
|
|
|
|
XP_Bool selectable = False;
|
|
if (!nDirs)
|
|
return selectable;
|
|
|
|
/* XFE always returns the first one
|
|
*/
|
|
AB_ContainerInfo *destAB =
|
|
(AB_ContainerInfo *) XP_ListGetObjectNum(abList,1);
|
|
XP_ASSERT(destAB);
|
|
|
|
int error = MSG_AddToAddressBookStatus(m_pane,
|
|
commandToMsgCmd(cmd),
|
|
NULL,
|
|
0,
|
|
&selectable, NULL, NULL, NULL,
|
|
destAB);
|
|
error = AB_ReleaseContainersList(abList);
|
|
|
|
return selectable;
|
|
}/* if */
|
|
#endif /* USE_ABCOM */
|
|
|
|
MSG_MotionType nav_cmd;
|
|
MSG_CommandType msg_cmd;
|
|
|
|
nav_cmd = commandToMsgNav(cmd);
|
|
|
|
if (IS_CMD(xfeCmdSetPriorityHighest)
|
|
|| IS_CMD(xfeCmdSetPriorityHigh)
|
|
|| IS_CMD(xfeCmdSetPriorityNormal)
|
|
|| IS_CMD(xfeCmdSetPriorityLow)
|
|
|| IS_CMD(xfeCmdSetPriorityLowest)
|
|
|| IS_CMD(xfeCmdSetPriorityNone)
|
|
|| IS_CMD(xfeCmdPrint)
|
|
|| IS_CMD(xfeCmdCopyMessage)
|
|
|| IS_CMD(xfeCmdMoveMessage)
|
|
|| IS_CMD(xfeCmdIgnoreThread)
|
|
|| IS_CMD(xfeCmdWatchThread)
|
|
|| IS_CMD(xfeCmdMarkMessageByDate))
|
|
{
|
|
MSG_ViewIndex index;
|
|
MessageKey key;
|
|
MSG_FolderInfo *info;
|
|
|
|
MSG_GetCurMessage(m_pane, &info, &key, &index);
|
|
|
|
return (key != MSG_MESSAGEKEYNONE);
|
|
}
|
|
else if (IS_CMD(xfeCmdMommy)
|
|
|| IS_CMD(xfeCmdNewFolder)
|
|
|| IS_CMD(xfeCmdRenameFolder)
|
|
|| IS_CMD(xfeCmdEmptyTrash)
|
|
|| IS_CMD(xfeCmdAddNewsgroup)
|
|
|| IS_CMD(xfeCmdUpdateMessageCount)
|
|
|| IS_CMD(xfeCmdPrintSetup)
|
|
|| IS_CMD(xfeCmdPrintPreview))
|
|
|
|
{
|
|
return True;
|
|
}
|
|
else if (IS_CMD(xfeCmdEditPreferences) ||
|
|
IS_CMD(xfeCmdWrapLongLines) )
|
|
{
|
|
return True;
|
|
}
|
|
else if ( IS_CMD(xfeCmdEditConfiguration) )
|
|
{
|
|
MSG_ViewIndex index ;
|
|
MessageKey key;
|
|
MSG_FolderInfo *info;
|
|
XP_Bool selectable = FALSE;
|
|
MSG_CommandType msg_cmd = commandToMsgCmd(cmd);
|
|
|
|
|
|
MSG_GetCurMessage(m_pane, &info, &key, &index);
|
|
MSG_CommandStatus(m_pane, msg_cmd,
|
|
&index, 1,
|
|
&selectable, NULL, NULL, NULL);
|
|
|
|
return (selectable && !(isDisplayingNews()) );
|
|
}
|
|
else if ( IS_CMD(xfeCmdModerateDiscussion) )
|
|
{
|
|
MSG_ViewIndex index ;
|
|
MessageKey key;
|
|
MSG_FolderInfo *info;
|
|
XP_Bool selectable = FALSE;
|
|
MSG_CommandType msg_cmd = commandToMsgCmd(cmd);
|
|
|
|
|
|
MSG_GetCurMessage(m_pane, &info, &key, &index);
|
|
MSG_CommandStatus(m_pane, msg_cmd,
|
|
&index, 1,
|
|
&selectable, NULL, NULL, NULL);
|
|
|
|
return (selectable && (isDisplayingNews()) );
|
|
}
|
|
else if (IS_CMD(xfeCmdGetNextNNewMsgs))
|
|
{
|
|
return m_displayingNewsgroup;
|
|
}
|
|
#ifdef DEBUG_akkana
|
|
else if (IS_CMD(xfeCmdEditMessage))
|
|
{
|
|
return !m_displayingNewsgroup;
|
|
}
|
|
#endif
|
|
else if (nav_cmd != (MSG_MotionType)~0)
|
|
{
|
|
MSG_ViewIndex index;
|
|
MessageKey key;
|
|
MSG_FolderInfo *info;
|
|
|
|
MSG_GetCurMessage(m_pane, &info, &key, &index);
|
|
|
|
if (MSG_NavigateStatus(m_pane, nav_cmd, index, &selectable, NULL) < 0)
|
|
selectable = FALSE;
|
|
|
|
return selectable;
|
|
}
|
|
else
|
|
{
|
|
msg_cmd = commandToMsgCmd(cmd);
|
|
|
|
if (msg_cmd != (MSG_CommandType)~0)
|
|
{
|
|
|
|
if (IS_CMD(xfeCmdGetNewMessages)) {
|
|
int num_inboxes = MSG_GetFoldersWithFlag(XFE_MNView::getMaster(),
|
|
MSG_FOLDER_FLAG_INBOX,
|
|
NULL, 0);
|
|
if ((num_inboxes > 0) ||
|
|
(MSG_CommandStatus(m_pane,
|
|
msg_cmd, NULL, 0,
|
|
&selectable, NULL, NULL, NULL) < 0)) {
|
|
selectable = FALSE;
|
|
}/* if */
|
|
}/* else */
|
|
else if (MSG_CommandStatus(m_pane, msg_cmd, NULL, 0, &selectable, NULL, NULL, NULL) < 0)
|
|
selectable = FALSE;
|
|
|
|
return selectable;
|
|
}
|
|
}
|
|
|
|
return XFE_MNView::isCommandEnabled(cmd, calldata);
|
|
#undef IS_CMD
|
|
}
|
|
|
|
void
|
|
XFE_MsgView::doCommand(CommandType cmd,
|
|
void *calldata, XFE_CommandInfo* info)
|
|
{
|
|
#define IS_CMD(command) cmd == (command)
|
|
|
|
if (IS_CMD(xfeCmdMommy))
|
|
{
|
|
fe_showMessages(XtParent(getToplevel()->getBaseWidget()),
|
|
/* Tao: we might need to check if this returns a
|
|
* non-NULL frame
|
|
*/
|
|
ViewGlue_getFrame(m_contextData),
|
|
NULL,
|
|
m_folderInfo,
|
|
fe_globalPrefs.reuse_thread_window,
|
|
False, MSG_MESSAGEKEYNONE);
|
|
}
|
|
#if defined(USE_ABCOM)
|
|
else if (IS_CMD(xfeCmdAddSenderToAddressBook)||
|
|
IS_CMD(xfeCmdAddAllToAddressBook)) {
|
|
|
|
XP_List *abList = AB_AcquireAddressBookContainers(m_contextData);
|
|
XP_ASSERT(abList);
|
|
int nDirs = XP_ListCount(abList);
|
|
|
|
if (nDirs) {
|
|
/* XFE always returns the first one
|
|
*/
|
|
AB_ContainerInfo *destAB =
|
|
(AB_ContainerInfo *) XP_ListGetObjectNum(abList,1);
|
|
XP_ASSERT(destAB);
|
|
|
|
int error = MSG_AddToAddressBook(m_pane,
|
|
commandToMsgCmd(cmd),
|
|
NULL,
|
|
0,
|
|
destAB);
|
|
error = AB_ReleaseContainersList(abList);
|
|
}/* if */
|
|
}/* if */
|
|
#endif /* USE_ABCOM */
|
|
else if (IS_CMD(xfeCmdGetNewMessages))
|
|
{
|
|
getNewMail();
|
|
}
|
|
else if (IS_CMD(xfeCmdGetNextNNewMsgs))
|
|
{
|
|
getNewNews();
|
|
}
|
|
else if (IS_CMD(xfeCmdMarkMessageByDate))
|
|
{
|
|
markReadByDate();
|
|
}
|
|
else if (IS_CMD(xfeCmdEditPreferences))
|
|
{
|
|
fe_showMailNewsPreferences(getToplevel(), m_contextData);
|
|
}
|
|
else if (IS_CMD(xfeCmdPrint))
|
|
{
|
|
fe_print_cb (CONTEXT_WIDGET (m_contextData),
|
|
(XtPointer) m_contextData, NULL);
|
|
|
|
getToplevel()->notifyInterested(XFE_View::chromeNeedsUpdating);
|
|
|
|
}
|
|
else if (IS_CMD(xfeCmdSearch))
|
|
{
|
|
// We don't need to call XtParent on the base widget because
|
|
// the base widget is the real toplevel widget already...dora 12/31/96
|
|
// Grabbed this from ThreadView.cpp -slamm 2/19/96
|
|
fe_showMNSearch(XfeAncestorFindApplicationShell(getToplevel()->getBaseWidget()),
|
|
/* Tao: we might need to check if this returns a
|
|
* non-NULL frame
|
|
*/
|
|
ViewGlue_getFrame(m_contextData),
|
|
NULL, this, m_folderInfo);
|
|
}
|
|
else if (IS_CMD(xfeCmdSetPriorityHighest)
|
|
|| IS_CMD(xfeCmdSetPriorityHigh)
|
|
|| IS_CMD(xfeCmdSetPriorityNormal)
|
|
|| IS_CMD(xfeCmdSetPriorityLow)
|
|
|| IS_CMD(xfeCmdSetPriorityLowest)
|
|
|| IS_CMD(xfeCmdSetPriorityNone))
|
|
{
|
|
MSG_PRIORITY priority = commandToPriority(cmd);
|
|
|
|
MSG_SetPriority(m_pane, m_messageKey, priority);
|
|
}
|
|
else if (IS_CMD(xfeCmdGetNewMessages))
|
|
{
|
|
getNewMail();
|
|
}
|
|
else if ( IS_CMD(xfeCmdEditConfiguration) ||
|
|
IS_CMD(xfeCmdModerateDiscussion) )
|
|
{
|
|
MSG_ViewIndex index ;
|
|
MessageKey key;
|
|
MSG_FolderInfo *info;
|
|
MSG_CommandType msg_cmd = commandToMsgCmd(cmd);
|
|
|
|
MSG_GetCurMessage(m_pane, &info, &key, &index);
|
|
|
|
MSG_Command(m_pane, msg_cmd, &index, 1);
|
|
}
|
|
else if (isDisplayingNews()
|
|
&& (IS_CMD(xfeCmdDeleteMessage) || IS_CMD(xfeCmdCancelMessages)))
|
|
{
|
|
// If this is a news article, then Delete Message
|
|
// is really Cancel Message:
|
|
MSG_Command(m_pane, MSG_CancelMessage, NULL, 0);
|
|
m_updateThread = True;
|
|
}
|
|
else if (IS_CMD(xfeCmdMoveMessage))
|
|
{
|
|
MSG_FolderInfo *info = (MSG_FolderInfo*)calldata;
|
|
MSG_ViewIndex index;
|
|
MSG_FolderInfo *curFolderInfo;
|
|
MessageKey key;
|
|
MSG_GetCurMessage(m_pane, &curFolderInfo, &key, &index);
|
|
|
|
if (index && info) {
|
|
MSG_MoveMessagesIntoFolder(m_pane, &index, 1, info);
|
|
m_updateThread = True;
|
|
}/* if */
|
|
}
|
|
else if (cmd == xfeCmdChangeDocumentEncoding)
|
|
{
|
|
int/*16*/ new_doc_csid = (int/*16*/)calldata;
|
|
INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(m_contextData);
|
|
|
|
if (new_doc_csid != m_contextData->fe.data->xfe_doc_csid)
|
|
{
|
|
/*
|
|
* Somebody is setting the doc_csid to a non-zero
|
|
* value, thereby screwing up our GetDefaultDocCSID
|
|
* routine. Make sure it gets set to zero here
|
|
* in the mail and news cases. Don't want to set
|
|
* it to zero in the Browser case, since it is
|
|
* legitimate there when the HTTP charset has been
|
|
* set. We override the charset in the mail and
|
|
* news cases.
|
|
*/
|
|
INTL_SetCSIDocCSID(c, new_doc_csid);
|
|
m_contextData->fe.data->xfe_doc_csid = new_doc_csid;
|
|
INTL_SetCSIWinCSID(c,
|
|
INTL_DocToWinCharSetID(new_doc_csid));
|
|
// now let our observers know that the encoding
|
|
// for this window needs to be changed.
|
|
getToplevel()->notifyInterested(XFE_Frame::encodingChanged, calldata);
|
|
MSG_SetFolderCSID(m_folderInfo, m_contextData->fe.data->xfe_doc_csid);
|
|
}
|
|
}
|
|
else if (cmd == xfeCmdSetDefaultDocumentEncoding)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
MSG_CommandType msg_cmd = commandToMsgCmd(cmd);
|
|
MSG_MotionType nav_cmd = commandToMsgNav(cmd);
|
|
|
|
if (info) {
|
|
CONTEXT_DATA(m_contextData)->stealth_cmd =
|
|
((info->event->type == ButtonRelease) &&
|
|
(info->event->xkey.state & ShiftMask));
|
|
}
|
|
|
|
if (nav_cmd == (MSG_MotionType)~0)
|
|
{
|
|
if ((msg_cmd == (MSG_CommandType)~0) ||
|
|
(msg_cmd == MSG_MailNew) ||
|
|
(msg_cmd == MSG_PostNew) )
|
|
{
|
|
XFE_MNView::doCommand(cmd, calldata, info);
|
|
}
|
|
else
|
|
{
|
|
if (msg_cmd == MSG_DeleteMessage)
|
|
/* stop loading since we are deleting this message:
|
|
* shall we check if it is stopable?
|
|
*/
|
|
XP_InterruptContext(m_contextData);
|
|
|
|
MSG_Command(m_pane, msg_cmd, NULL, 0);
|
|
|
|
if (msg_cmd == MSG_DeleteMessage ||
|
|
msg_cmd == MSG_CancelMessage) {
|
|
m_updateThread = True;
|
|
}/* if */
|
|
|
|
|
|
/* stand alone msgpane
|
|
*/
|
|
if (IS_CMD(xfeCmdUndo)
|
|
|| IS_CMD(xfeCmdRedo)) {
|
|
MessageKey key = MSG_MESSAGEKEYNONE;
|
|
MSG_FolderInfo *folder = NULL;
|
|
|
|
if ( UndoComplete == MSG_GetUndoStatus(m_pane) ) {
|
|
if (MSG_GetUndoMessageKey(m_pane, &folder, &key) && folder)
|
|
loadMessage(folder, key);
|
|
}/* if */
|
|
}/* if */
|
|
|
|
XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::folderChromeNeedsUpdating, getFolderInfo());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MSG_ViewIndex index, threadIndex;
|
|
MessageKey key;
|
|
MessageKey resultId;
|
|
MSG_FolderInfo *info;
|
|
|
|
MSG_GetCurMessage(m_pane, &info, &key, &index);
|
|
|
|
// MsgView might be invoked from Search Dialog
|
|
// In this circumstances, m_folderInfo was
|
|
// not initialized. Therefore, we will see a crash when one
|
|
// tries to do Next Msg.
|
|
// We try to initialize m_folderInfo here base on current msg
|
|
// msg folder info.
|
|
|
|
// The above comment is not valid if we set m_folderInfo when MessageLoad
|
|
// notification arrives
|
|
//
|
|
if (!m_folderInfo)
|
|
m_folderInfo = info;
|
|
|
|
MSG_FolderInfo *curInfo = info;
|
|
MSG_ViewNavigate(m_pane, nav_cmd, index,
|
|
&resultId, &index, &threadIndex,
|
|
&info);
|
|
|
|
// ViewNavigate gives a NULL folderinfo if the folder
|
|
// info won't be changing.
|
|
if (!info) {
|
|
int idx = (int) index;
|
|
if (idx >= 0) {
|
|
info = m_folderInfo;
|
|
loadMessage(info, resultId);
|
|
}/* if */
|
|
}/* if */
|
|
else if (curInfo != info) {
|
|
/* folder changed
|
|
*/
|
|
/* get parent view
|
|
*/
|
|
XFE_ThreadView *threadView = (XFE_ThreadView *)getParent();
|
|
|
|
/* load new folder
|
|
*/
|
|
if (threadView) {
|
|
/* in thread win
|
|
*/
|
|
threadView->loadFolder(info);
|
|
threadView->setPendingCmdSelByKey(selectByKey, resultId);
|
|
}/* if */
|
|
else {
|
|
/* in message win
|
|
*/
|
|
MWContext *thrContext = fe_showMessages(XtParent(getToplevel()->getBaseWidget()),
|
|
/* Tao: we might need to check if this returns a
|
|
* non-NULL frame
|
|
*/
|
|
ViewGlue_getFrame(m_contextData),
|
|
NULL,
|
|
info,
|
|
fe_globalPrefs.reuse_thread_window,
|
|
False, resultId);
|
|
if (thrContext) {
|
|
XFE_ThreadFrame *tFrame = (XFE_ThreadFrame *) ViewGlue_getFrame(thrContext);
|
|
XP_ASSERT(tFrame);
|
|
threadView = (XFE_ThreadView *) tFrame->getView();
|
|
if (threadView) {
|
|
switch (nav_cmd) {
|
|
case MSG_NextMessage:
|
|
threadView->setPendingCmdSelByKey(selectFirstUnread, resultId);
|
|
}/* switch */
|
|
}/* if */
|
|
}/* if */
|
|
|
|
/* load myself
|
|
*/
|
|
}/* else */
|
|
}/* else if */
|
|
|
|
}
|
|
}
|
|
#undef IS_CMD
|
|
}
|
|
|
|
Boolean
|
|
XFE_MsgView::handlesCommand(CommandType cmd, void *calldata, XFE_CommandInfo*)
|
|
{
|
|
#define IS_CMD(command) cmd == (command)
|
|
|
|
if ( IS_CMD(xfeCmdSaveAs)
|
|
|| IS_CMD(xfeCmdSaveMessagesAs)
|
|
|| IS_CMD(xfeCmdSaveAsTemplate)
|
|
|
|
|| IS_CMD(xfeCmdAddSenderToAddressBook)
|
|
|| IS_CMD(xfeCmdAddAllToAddressBook)
|
|
|
|
|| IS_CMD(xfeCmdGetNewMessages)
|
|
|| IS_CMD(xfeCmdGetNextNNewMsgs)
|
|
|| IS_CMD(xfeCmdPrint)
|
|
|
|
|| IS_CMD(xfeCmdSendMessagesInOutbox)
|
|
|
|
|| IS_CMD(xfeCmdNextUnreadMessage)
|
|
|| IS_CMD(xfeCmdPreviousUnreadMessage)
|
|
|| IS_CMD(xfeCmdNextMessage)
|
|
|| IS_CMD(xfeCmdPreviousMessage)
|
|
|| IS_CMD(xfeCmdNextUnreadThread)
|
|
|| IS_CMD(xfeCmdNextCollection)
|
|
|| IS_CMD(xfeCmdNextUnreadCollection)
|
|
|| IS_CMD(xfeCmdFirstUnreadMessage)
|
|
|| IS_CMD(xfeCmdFirstFlaggedMessage)
|
|
|| IS_CMD(xfeCmdPreviousFlaggedMessage)
|
|
|| IS_CMD(xfeCmdNextFlaggedMessage)
|
|
|
|
|| IS_CMD(xfeCmdUndo)
|
|
|| IS_CMD(xfeCmdRedo)
|
|
|| IS_CMD(xfeCmdSearch)
|
|
|
|
|| IS_CMD(xfeCmdDeleteMessage)
|
|
|| IS_CMD(xfeCmdEditPreferences)
|
|
|
|
|| IS_CMD(xfeCmdMarkMessageRead)
|
|
|| IS_CMD(xfeCmdMarkMessageUnread)
|
|
|| IS_CMD(xfeCmdMarkMessageByDate)
|
|
|| IS_CMD(xfeCmdMarkAllMessagesRead)
|
|
|| IS_CMD(xfeCmdMarkThreadRead)
|
|
|| IS_CMD(xfeCmdMarkMessageForLater)
|
|
|| IS_CMD(xfeCmdMarkMessage)
|
|
|
|
|| IS_CMD(xfeCmdReplyToSender)
|
|
|| IS_CMD(xfeCmdReplyToAll)
|
|
|| IS_CMD(xfeCmdReplyToNewsgroup)
|
|
|| IS_CMD(xfeCmdReplyToSenderAndNewsgroup)
|
|
|| IS_CMD(xfeCmdForwardMessage)
|
|
|| IS_CMD(xfeCmdForwardMessageQuoted)
|
|
|| IS_CMD(xfeCmdForwardMessageInLine)
|
|
|| IS_CMD(xfeCmdShowAllHeaders)
|
|
|| IS_CMD(xfeCmdShowNormalHeaders)
|
|
|| IS_CMD(xfeCmdShowBriefHeaders)
|
|
|| IS_CMD(xfeCmdViewAttachmentsInline)
|
|
|| IS_CMD(xfeCmdViewAttachmentsAsLinks)
|
|
|| IS_CMD(xfeCmdRot13Message)
|
|
|| IS_CMD(xfeCmdMoveMessage)
|
|
|| IS_CMD(xfeCmdCopyMessage)
|
|
|
|
|| IS_CMD(xfeCmdNewFolder)
|
|
|| IS_CMD(xfeCmdRenameFolder)
|
|
|| IS_CMD(xfeCmdEmptyTrash)
|
|
|| IS_CMD(xfeCmdCompressAllFolders)
|
|
|| IS_CMD(xfeCmdAddNewsgroup)
|
|
|| IS_CMD(xfeCmdUpdateMessageCount)
|
|
|| IS_CMD(xfeCmdPrintSetup)
|
|
|| IS_CMD(xfeCmdPrintPreview)
|
|
|| IS_CMD(xfeCmdEditMessage)
|
|
|
|
|| IS_CMD(xfeCmdToggleThreadKilled)
|
|
|| IS_CMD(xfeCmdToggleThreadWatched)
|
|
|
|
/* priorities. */
|
|
|| IS_CMD(xfeCmdSetPriorityHighest)
|
|
|| IS_CMD(xfeCmdSetPriorityHigh)
|
|
|| IS_CMD(xfeCmdSetPriorityNormal)
|
|
|| IS_CMD(xfeCmdSetPriorityLow)
|
|
|| IS_CMD(xfeCmdSetPriorityLowest)
|
|
|| IS_CMD(xfeCmdSetPriorityNone)
|
|
|
|
|| IS_CMD(xfeCmdIgnoreThread)
|
|
|| IS_CMD(xfeCmdWatchThread)
|
|
|| IS_CMD(xfeCmdModerateDiscussion)
|
|
|
|
|| IS_CMD(xfeCmdWrapLongLines)
|
|
|| IS_CMD(xfeCmdMommy))
|
|
{
|
|
return True;
|
|
}
|
|
else
|
|
{
|
|
return XFE_MNView::handlesCommand(cmd, calldata);
|
|
}
|
|
#undef IS_CMD
|
|
}
|
|
|
|
char*
|
|
XFE_MsgView::commandToString(CommandType cmd, void * calldata, XFE_CommandInfo* info)
|
|
{
|
|
#define IS_CMD(command) cmd == (command)
|
|
|
|
if ( (IS_CMD(xfeCmdDeleteMessage) || IS_CMD(xfeCmdCancelMessages))
|
|
&& isDisplayingNews() )
|
|
return XP_GetString(MK_MSG_CANCEL_MESSAGE);
|
|
else if ( calldata &&
|
|
(IS_CMD(xfeCmdReplyToSender) || IS_CMD(xfeCmdReplyToAll)
|
|
|| IS_CMD(xfeCmdReplyToNewsgroup)
|
|
|| IS_CMD(xfeCmdReplyToSenderAndNewsgroup) ) )
|
|
{
|
|
// if calldata is non-null for a Reply button,
|
|
// that's a signal not to change the
|
|
// widget name in the resources file:
|
|
return 0;
|
|
}
|
|
|
|
MSG_CommandType msg_cmd = commandToMsgCmd(cmd);
|
|
MSG_MotionType msg_nav = commandToMsgNav(cmd);
|
|
const char *display_string = NULL;
|
|
|
|
if (msg_cmd != (MSG_CommandType)~0)
|
|
{
|
|
if (IS_CMD(xfeCmdGetNewMessages)) {
|
|
int num_inboxes = MSG_GetFoldersWithFlag(XFE_MNView::getMaster(),
|
|
MSG_FOLDER_FLAG_INBOX,
|
|
NULL, 0);
|
|
if ((num_inboxes >0) ||
|
|
(MSG_CommandStatus(m_pane, msg_cmd,
|
|
NULL, 0, NULL, NULL,
|
|
(const char **)&display_string, NULL) < 0)) {
|
|
return NULL;
|
|
}/* if */
|
|
return (char*)display_string;
|
|
}/* if */
|
|
else if (MSG_CommandStatus(m_pane, msg_cmd,
|
|
NULL, 0, NULL, NULL,
|
|
(const char **)&display_string, NULL) < 0)
|
|
return NULL;
|
|
else
|
|
{
|
|
if ( (cmd == xfeCmdComposeMessageHTML ) ||
|
|
( cmd == xfeCmdComposeMessagePlain) ||
|
|
( cmd == xfeCmdComposeArticleHTML) ||
|
|
( cmd == xfeCmdComposeArticlePlain) )
|
|
{
|
|
return NULL;
|
|
}
|
|
else
|
|
return (char*)display_string;
|
|
}
|
|
|
|
}
|
|
else if (msg_cmd != (MSG_MotionType)~0)
|
|
{
|
|
MessageKey key;
|
|
MSG_ViewIndex index;
|
|
MSG_FolderInfo *info;
|
|
|
|
MSG_GetCurMessage(m_pane, &info, &key, &index);
|
|
|
|
if (index == MSG_VIEWINDEXNONE
|
|
|| MSG_NavigateStatus(m_pane, msg_nav,
|
|
(MSG_ViewIndex)index,
|
|
NULL, (const char **)&display_string) < 0)
|
|
return NULL;
|
|
else
|
|
{
|
|
if ( (cmd == xfeCmdComposeMessageHTML ) ||
|
|
( cmd == xfeCmdComposeMessagePlain) ||
|
|
( cmd == xfeCmdComposeArticleHTML) ||
|
|
( cmd == xfeCmdComposeArticlePlain) )
|
|
{
|
|
return NULL;
|
|
}
|
|
else
|
|
return (char*)display_string;
|
|
}
|
|
}
|
|
else if (IS_CMD(xfeCmdFindInObject))
|
|
{
|
|
/* short circuit HTMLView's "Find in Page/Frame" and keep
|
|
our "Find in Message." */
|
|
return NULL;
|
|
}
|
|
else
|
|
return XFE_MNView::commandToString(cmd, calldata, info);
|
|
#undef IS_CMD
|
|
}
|
|
|
|
XFE_CALLBACK_DEFN(XFE_MsgView, showPopup)(XFE_NotificationCenter *,
|
|
void *, void *calldata)
|
|
{
|
|
D(printf("XFE_MsgView::showPopup()\n");)
|
|
XEvent *event = (XEvent *)calldata;
|
|
|
|
URL_Struct *url_under_mouse = m_htmlView->URLUnderMouse();
|
|
URL_Struct *image_under_mouse = m_htmlView->ImageUnderMouse();
|
|
URL_Struct *background_under_mouse = m_htmlView->BackgroundUnderMouse();
|
|
|
|
XP_Bool isBrowserLink = FALSE;
|
|
XP_Bool isAttachmentLink = FALSE;
|
|
XP_Bool isLink = url_under_mouse != NULL;
|
|
XP_Bool isImage = image_under_mouse != NULL;
|
|
XP_Bool needSeparator = FALSE;
|
|
XP_Bool haveAddedItems = FALSE;
|
|
|
|
if (m_popup)
|
|
delete m_popup;
|
|
|
|
/* Need to switch focus for the popup menu so that menu items can be enabled in
|
|
the three pane world */
|
|
XFE_ThreadView *threadView = (XFE_ThreadView *)getParent(); /* returns the thread view */
|
|
if (threadView)
|
|
getToplevel()->notifyInterested(XFE_MNListView::changeFocus, (void*) threadView);
|
|
|
|
m_popup = new XFE_PopupMenu("popup",(XFE_Frame*)m_toplevel,
|
|
XfeAncestorFindApplicationShell(m_widget));
|
|
|
|
if (url_under_mouse != NULL
|
|
&& XP_STRNCMP ("mailto:", url_under_mouse->address, 7) != 0
|
|
&& XP_STRNCMP ("telnet:", url_under_mouse->address, 7) != 0
|
|
&& XP_STRNCMP ("tn3270:", url_under_mouse->address, 7) != 0
|
|
&& XP_STRNCMP ("rlogin:", url_under_mouse->address, 7) != 0
|
|
&& XP_STRNCMP ("addbook:", url_under_mouse->address, 8) != 0)
|
|
{
|
|
isBrowserLink = TRUE;
|
|
}
|
|
|
|
if (url_under_mouse != NULL
|
|
&& XP_STRNCASECMP ("mailbox:", url_under_mouse->address, 8) != 0
|
|
&& XP_STRSTR(url_under_mouse->address, "part?"))
|
|
{
|
|
isAttachmentLink = TRUE;
|
|
}
|
|
|
|
/* turn off everything if the user right clicks on the paperclip icon */
|
|
if (url_under_mouse != NULL
|
|
&& XP_STRCMP ("mailbox:displayattachments", url_under_mouse->address) == 0)
|
|
{
|
|
isBrowserLink = FALSE;
|
|
isAttachmentLink = FALSE;
|
|
isImage = FALSE;
|
|
}
|
|
|
|
#define ADD_MENU_SEPARATOR { \
|
|
if (haveAddedItems) { \
|
|
needSeparator = TRUE; \
|
|
haveAddedItems = FALSE; \
|
|
} \
|
|
}
|
|
|
|
#define ADD_SPEC(theSpec) { \
|
|
if (needSeparator) \
|
|
m_popup->addMenuSpec(separator_spec); \
|
|
m_popup->addMenuSpec(theSpec); \
|
|
needSeparator = FALSE; \
|
|
haveAddedItems = TRUE; \
|
|
}
|
|
|
|
if (isBrowserLink) ADD_SPEC ( openLinkNew_spec );
|
|
#ifdef EDITOR
|
|
if (isBrowserLink) ADD_SPEC ( openLinkEdit_spec );
|
|
#endif
|
|
|
|
ADD_MENU_SEPARATOR;
|
|
|
|
ADD_SPEC ( repl_spec );
|
|
|
|
ADD_MENU_SEPARATOR;
|
|
|
|
ADD_SPEC ( addr_spec );
|
|
|
|
ADD_MENU_SEPARATOR;
|
|
|
|
ADD_SPEC ( filemsg_spec );
|
|
|
|
if (isCommandEnabled(xfeCmdStopLoading)) ADD_SPEC ( stopLoading_spec );
|
|
ADD_MENU_SEPARATOR;
|
|
if (isImage) ADD_SPEC ( openImage_spec );
|
|
ADD_MENU_SEPARATOR;
|
|
if (isBrowserLink) ADD_SPEC ( saveLink_spec );
|
|
if (isImage) ADD_SPEC ( saveImage_spec );
|
|
ADD_MENU_SEPARATOR;
|
|
if (isCommandEnabled(xfeCmdCopy)) ADD_SPEC ( copy_spec );
|
|
if (isLink) ADD_SPEC ( copyLink_spec );
|
|
if (isImage) ADD_SPEC ( copyImage_spec );
|
|
|
|
// Finish up the popup
|
|
m_popup->position (event);
|
|
m_popup->show();
|
|
}
|
|
|
|
XFE_CALLBACK_DEFN(XFE_MsgView, spaceAtMsgEnd)(XFE_NotificationCenter *,
|
|
void *, void */*callData*/)
|
|
{
|
|
notifyInterested(spacebarAtMsgBottom);
|
|
}
|
|
|
|
XFE_CALLBACK_DEFN(XFE_MsgView, refresh)(XFE_NotificationCenter *,
|
|
void *, void */*callData*/)
|
|
{
|
|
m_htmlView->doCommand(xfeCmdRefresh);
|
|
}
|