Mozilla/mozilla/cmd/xfe/src/FolderView.cpp
dmose%mozilla.org 83e38c06cc updated license boilerplate to xPL v1.1
git-svn-id: svn://10.0.0.236/trunk@52594 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-02 22:43:10 +00:00

2211 lines
58 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
FolderView.cpp -- presents view of mail folders and newsgroups/hosts.
Created: Chris Toshok <toshok@netscape.com>, 7-Aug-96.
*/
#include "rosetta.h"
#include "FolderView.h"
#include "SubscribeDialog.h" /* for fe_showSubscribeDialog */
#include "ThreadFrame.h" /* for fe_showMessages */
#if defined(USE_MOTIF_DND)
#include "ThreadView.h"
#endif /* USE_MOTIF_DND */
#include "ViewGlue.h"
#include "Outliner.h"
#if defined(USE_MOTIF_DND)
#include "OutlinerDrop.h"
#endif /* USE_MOTIF_DND */
#include "MozillaApp.h"
#include "NewsServerDialog.h"
#include "xfe.h"
#include "icondata.h"
#include "msgcom.h"
#include "felocale.h" /* for fe_ConvertToLocalEncoding */
#include "xp_mem.h"
#include "Xfe/Xfe.h"
#include "NewsServerPropDialog.h"
#include "NewsgroupPropDialog.h"
#include "MailFolderPropDialog.h"
#include "MNSearchFrame.h"
#include "LdapSearchFrame.h"
#include "MailFilterDlg.h"
#include "prefs.h"
#ifdef DEBUG_toshok
#define D(x) x
#else
#define D(x)
#endif
#ifdef DEBUG_dora
#define DD(x) x
#else
#define DD(x)
#endif
#define FOLDER_OUTLINER_GEOMETRY_PREF "mail.folderpane.outliner_geometry"
// bloody entrails dragging behind.... weighing me down...
extern "C" void fe_sec_logo_cb (Widget, XtPointer, XtPointer);
const char *XFE_FolderView::folderSelected = "XFE_FolderView::folderSelected";
const char *XFE_FolderView::folderDblClicked = "XFE_FolderView::folderDblClicked";
const char *XFE_FolderView::folderAltDblClicked = "XFE_FolderView::folderAltDblClicked";
const int XFE_FolderView::OUTLINER_COLUMN_NAME = 0;
const int XFE_FolderView::OUTLINER_COLUMN_UNREAD = 1;
const int XFE_FolderView::OUTLINER_COLUMN_TOTAL = 2;
#include "xpgetstr.h"
extern int XFE_FOLDER_OUTLINER_COLUMN_NAME;
extern int XFE_FOLDER_OUTLINER_COLUMN_TOTAL;
extern int XFE_FOLDER_OUTLINER_COLUMN_UNREAD;
extern int XFE_DND_MESSAGE_ERROR;
MenuSpec XFE_FolderView::mailserver_popup_menu[] = {
#if 0
{ xfeCmdUpdateMessageCount, PUSHBUTTON },
#endif
{ xfeCmdNewFolder, PUSHBUTTON },
{ xfeCmdViewProperties, PUSHBUTTON },
{ NULL }
};
MenuSpec XFE_FolderView::newshost_popup_menu[] = {
// From the spec:
// "Open Discussion Group Server" -- is that xfeCmdGetNewGroups?
{ xfeCmdAddNewsgroup, PUSHBUTTON },
#if 0
{ xfeCmdUpdateMessageCount, PUSHBUTTON },
#endif
{ xfeCmdDeleteFolder, PUSHBUTTON },
{ xfeCmdViewProperties, PUSHBUTTON },
{ NULL }
};
MenuSpec XFE_FolderView::mailfolder_popup_menu[] = {
{ xfeCmdOpenFolder, PUSHBUTTON },
// { xfeCmdOpenFolderInNewWindow, PUSHBUTTON },
MENU_SEPARATOR,
{ xfeCmdNewFolder, PUSHBUTTON },
{ xfeCmdDeleteFolder, PUSHBUTTON },
{ xfeCmdRenameFolder, PUSHBUTTON },
{ xfeCmdCompressFolders, PUSHBUTTON },
{ xfeCmdCompressAllFolders, PUSHBUTTON },
MENU_SEPARATOR,
{ xfeCmdComposeMessage, PUSHBUTTON },
MENU_SEPARATOR,
{ xfeCmdSearch, PUSHBUTTON },
{ xfeCmdViewProperties, PUSHBUTTON },
{ NULL }
};
MenuSpec XFE_FolderView::newsgroup_popup_menu[] = {
{ xfeCmdOpenSelected, PUSHBUTTON },
// open newsgroups in new window should go here
MENU_SEPARATOR,
{ xfeCmdComposeMessage, PUSHBUTTON },
{ xfeCmdMarkAllMessagesRead, PUSHBUTTON },
{ xfeCmdDeleteFolder, PUSHBUTTON },
MENU_SEPARATOR,
{ xfeCmdSearch, PUSHBUTTON },
{ xfeCmdViewProperties, PUSHBUTTON },
{ NULL }
};
XFE_FolderView::XFE_FolderView(XFE_Component *toplevel_component,
Widget parent,
XFE_View *parent_view, MWContext *context,
MSG_Pane *p)
: XFE_MNListView(toplevel_component, parent_view, context, p)
{
// initialize it
m_popup = NULL;
#ifdef USE_3PANE
m_clickTimer = 0;
m_clickData = NULL;
m_cur_selected = NULL;
m_cur_count = 0;
#endif
int num_columns = 3;
static int default_column_widths[] = {30, 10, 10};
toplevel_component->registerInterest(XFE_Component::afterRealizeCallback,
this,
(XFE_FunctionNotification)beforeToplevelShow_cb);
if (!p)
setPane(MSG_CreateFolderPane(m_contextData,
XFE_MNView::m_master));
// create our outliner
m_outliner = new XFE_Outliner("folderList",
this,
getToplevel(),
parent,
False, // constantSize
True, // hasHeadings
num_columns,
3,
default_column_widths,
FOLDER_OUTLINER_GEOMETRY_PREF);
m_outliner->setPipeColumn( OUTLINER_COLUMN_NAME );
m_outliner->setMultiSelectAllowed( True );
m_outliner->setHideColumnsAllowed( True );
#if defined(USE_MOTIF_DND)
m_outliner->enableDragDrop(this,
XFE_FolderView::getDropTargets,
XFE_FolderView::getDragTargets,
XFE_FolderView::getDragIconData,
XFE_FolderView::dragConvert,
XFE_FolderView::processTargets);
#else
m_outliner->setDragType( FE_DND_MAIL_FOLDER, &folderIcon, this,
(fe_dnd_SourceDropFunc)&XFE_FolderView::source_drop_func);
fe_dnd_CreateDrop(m_outliner->getBaseWidget(), drop_func, this);
#endif /* USE_MOTIF_DND */
setBaseWidget(m_outliner->getBaseWidget());
// initialize the icons if they haven't already been
{
Pixel bg_pixel;
XtVaGetValues(m_widget, XmNbackground, &bg_pixel, 0);
initFolderIcons(getToplevel()->getBaseWidget(),
bg_pixel, getToplevel()->getFGPixel());
}
// jump start the folderview's display
FE_ListChangeStarting(m_pane,
FALSE, MSG_NotifyAll, 0, 0);
FE_ListChangeFinished(m_pane,
FALSE, MSG_NotifyAll, 0, 0);
}
XFE_FolderView::~XFE_FolderView()
{
D( printf ("~XFE_FolderView()\n");)
delete m_outliner;
destroyPane();
// destroy popup here
if (m_popup)
delete m_popup;
}
void
XFE_FolderView::initFolderIcons(Widget widget, Pixel bg_pixel, Pixel fg_pixel)
{
static Boolean icons_init_done = False;
if (icons_init_done)
return;
icons_init_done = True;
if (!mailLocalIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&mailLocalIcon,
NULL,
MN_MailLocal.width, MN_MailLocal.height,
MN_MailLocal.mono_bits, MN_MailLocal.color_bits, MN_MailLocal.mask_bits, FALSE);
if (!mailServerIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&mailServerIcon,
NULL,
MN_MailLocal.width, MN_MailLocal.height,
MN_MailLocal.mono_bits, MN_MailLocal.color_bits, MN_MailLocal.mask_bits, FALSE);
if (!inboxIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&inboxIcon,
NULL,
MN_Inbox.width, MN_Inbox.height,
MN_Inbox.mono_bits, MN_Inbox.color_bits, MN_Inbox.mask_bits, FALSE);
if (!inboxOpenIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&inboxOpenIcon,
NULL,
MN_InboxO.width, MN_InboxO.height,
MN_InboxO.mono_bits, MN_InboxO.color_bits, MN_InboxO.mask_bits, FALSE);
if (!draftsIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&draftsIcon,
NULL,
MN_Draft.width, MN_Draft.height,
MN_Draft.mono_bits, MN_Draft.color_bits, MN_Draft.mask_bits, FALSE);
if (!draftsOpenIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&draftsOpenIcon,
NULL,
MN_DraftO.width, MN_DraftO.height,
MN_DraftO.mono_bits, MN_DraftO.color_bits, MN_DraftO.mask_bits, FALSE);
if (!templatesIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&templatesIcon,
NULL,
MN_Template.width, MN_Template.height,
MN_Template.mono_bits, MN_Template.color_bits, MN_Template.mask_bits, FALSE);
if (!templatesOpenIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&templatesOpenIcon,
NULL,
MN_TemplateO.width, MN_TemplateO.height,
MN_TemplateO.mono_bits, MN_TemplateO.color_bits, MN_TemplateO.mask_bits, FALSE);
if (!outboxIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&outboxIcon,
NULL,
MN_Outbox.width, MN_Outbox.height,
MN_Outbox.mono_bits, MN_Outbox.color_bits, MN_Outbox.mask_bits, FALSE);
if (!outboxOpenIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&outboxOpenIcon,
NULL,
MN_OutboxO.width, MN_OutboxO.height,
MN_OutboxO.mono_bits, MN_OutboxO.color_bits, MN_OutboxO.mask_bits, FALSE);
if (!folderIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&folderIcon,
NULL,
MN_Folder.width, MN_Folder.height,
MN_Folder.mono_bits, MN_Folder.color_bits, MN_Folder.mask_bits, FALSE);
if (!folderOpenIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&folderOpenIcon,
NULL,
MN_FolderO.width, MN_FolderO.height,
MN_FolderO.mono_bits, MN_FolderO.color_bits, MN_FolderO.mask_bits, FALSE);
if (!folderServerIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&folderServerIcon,
NULL,
MN_FolderServer.width, MN_FolderServer.height,
MN_FolderServer.mono_bits, MN_FolderServer.color_bits, MN_FolderServer.mask_bits, FALSE);
if (!folderServerOpenIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&folderServerOpenIcon,
NULL,
MN_FolderServerO.width, MN_FolderServerO.height,
MN_FolderServerO.mono_bits, MN_FolderServerO.color_bits, MN_FolderServerO.mask_bits, FALSE);
if (!newsServerIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&newsServerIcon,
NULL,
MN_NewsServer.width, MN_NewsServer.height,
MN_NewsServer.mono_bits, MN_NewsServer.color_bits, MN_NewsServer.mask_bits, FALSE);
HG39875
if (!newsgroupIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&newsgroupIcon,
NULL,
MN_Newsgroup.width, MN_Newsgroup.height,
MN_Newsgroup.mono_bits, MN_Newsgroup.color_bits, MN_Newsgroup.mask_bits, FALSE);
if (!trashIcon.pixmap)
fe_NewMakeIcon(widget,
fg_pixel,
bg_pixel,
&trashIcon,
NULL,
MN_TrashSmall.width, MN_TrashSmall.height,
MN_TrashSmall.mono_bits, MN_TrashSmall.color_bits, MN_TrashSmall.mask_bits, FALSE);
}
void
XFE_FolderView::paneChanged(XP_Bool asynchronous,
MSG_PANE_CHANGED_NOTIFY_CODE code,
int32 value)
{
switch (code)
{
case MSG_PaneNotifySelectNewFolder:
{
/* check value
*/
if (value >=0) {
m_outliner->makeVisible(value);
m_outliner->selectItemExclusive(value);
}/* if */
#if defined(DEBUG_tao)
else {
printf("\nXFE_FolderView::paneChanged, value=%d", value);
XP_ASSERT(value >=0);
}/* else */
#endif
break;
}
case MSG_PaneNotifyFolderDeleted:
XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::folderDeleted,
(void *)value);
break;
default:
break;
}
XFE_MNView::paneChanged(asynchronous, code, value);
}
XFE_CALLBACK_DEFN(XFE_FolderView, beforeToplevelShow)(XFE_NotificationCenter *,
void *, void*)
{
}
void
XFE_FolderView::selectFolder(MSG_FolderInfo *info)
{
MSG_ViewIndex index;
index = MSG_GetFolderIndexForInfo(m_pane, info, TRUE);
if (index != MSG_VIEWINDEXNONE)
{
m_outliner->makeVisible(index);
m_outliner->selectItemExclusive(index);
getToplevel()->notifyInterested(XFE_View::chromeNeedsUpdating);
}
}
Boolean
XFE_FolderView::isCommandEnabled(CommandType cmd, void *call_data, XFE_CommandInfo* info)
{
const int *selected;
int count;
m_outliner->getSelection(&selected, &count);
#define IS_CMD(command) cmd == (command)
if (// from the FolderFrame edit menu.
IS_CMD(xfeCmdFindInObject)
|| IS_CMD(xfeCmdFindAgain))
{
return !XP_IsContextBusy(m_contextData) && count > 0;
}
#ifdef DEBUG_akkana
else if ( IS_CMD(xfeCmdExpand)
|| IS_CMD(xfeCmdExpandAll)
|| IS_CMD(xfeCmdCollapse)
|| IS_CMD(xfeCmdCollapseAll)
)
return True;
#endif
HG07326
else if (IS_CMD(xfeCmdViewProperties))
{
return count == 1;
}
else if (IS_CMD(xfeCmdUpdateMessageCount))
{
return !XP_IsContextBusy(m_contextData);
}
else if (IS_CMD(xfeCmdSearch) )
{
// Find current selected folder, if none, disable this button
if (XP_IsContextBusy(m_contextData) ) return False;
const int *selected;
int count;
m_outliner->getSelection(&selected, &count);
if ( count > 0 )
return True;
else
return False;
}
else if ( IS_CMD(xfeCmdSearchAddress))
{
return !XP_IsContextBusy(m_contextData);
}
else if (IS_CMD(xfeCmdDeleteAny))
{
return XFE_MNListView::isCommandEnabled(xfeCmdDeleteFolder);
}
else if (IS_CMD(xfeCmdEditPreferences) || IS_CMD(xfeCmdNewNewsHost))
{
return True;
}
else if (IS_CMD(xfeCmdEditConfiguration) )
{
MSG_FolderLine line;
if (!MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line))
return False;
return (line.flags & MSG_FOLDER_FLAG_MAIL);
}
else if (IS_CMD(xfeCmdModerateDiscussion) )
{
MSG_FolderLine line;
if (!MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line))
return False;
return (line.flags & MSG_FOLDER_FLAG_NEWSGROUP);
}
else if (IS_CMD(xfeCmdOpenSelected))
{
MSG_FolderLine line;
if (!MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line))
return False;
return ((line.flags & MSG_FOLDER_FLAG_NEWSGROUP)
|| ((line.flags & MSG_FOLDER_FLAG_MAIL)
&& (line.level > 1)));
}
else if (IS_CMD(xfeCmdNewFolder) && count == 1)
{
MSG_FolderLine line;
if (!MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line))
return False;
XP_Bool selectable;
if (line.flags & MSG_FOLDER_FLAG_NEWSGROUP
|| line.flags & MSG_FOLDER_FLAG_NEWS_HOST)
MSG_CommandStatus(m_pane, MSG_NewNewsgroup,
(MSG_ViewIndex*)selected, count,
&selectable, NULL, NULL, NULL);
else
MSG_CommandStatus(m_pane, MSG_NewFolder,
(MSG_ViewIndex*)selected, count,
&selectable, NULL, NULL, NULL);
return selectable;
}
else if (IS_CMD(xfeCmdRenameFolder) && count == 1)
{
MSG_FolderLine line;
if (!MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line))
return False;
XP_Bool selectable;
if (line.flags & MSG_FOLDER_FLAG_MAIL)
MSG_CommandStatus(m_pane, MSG_NewFolder,
(MSG_ViewIndex*)selected, count,
&selectable, NULL, NULL, NULL);
return selectable;
}
else
{
return XFE_MNListView::isCommandEnabled(cmd, call_data, info);
}
#undef IS_CMD
}
Boolean
XFE_FolderView::handlesCommand(CommandType cmd, void *, XFE_CommandInfo*)
{
#define IS_CMD(command) cmd == (command)
if (IS_CMD(xfeCmdOpenSelected)
|| IS_CMD(xfeCmdEditPreferences)
|| IS_CMD(xfeCmdOpenPage)
|| IS_CMD(xfeCmdSaveAs)
|| IS_CMD(xfeCmdNewFolder)
|| IS_CMD(xfeCmdRenameFolder)
|| IS_CMD(xfeCmdEmptyTrash)
|| IS_CMD(xfeCmdCompressFolders)
|| IS_CMD(xfeCmdCompressAllFolders)
|| IS_CMD(xfeCmdAddNewsgroup)
|| IS_CMD(xfeCmdNewNewsHost)
|| IS_CMD(xfeCmdInviteToNewsgroup)
|| IS_CMD(xfeCmdPrintSetup)
|| IS_CMD(xfeCmdPrintPreview)
|| IS_CMD(xfeCmdPrint)
|| IS_CMD(xfeCmdSearch)
|| IS_CMD(xfeCmdSearchAddress)
|| IS_CMD(xfeCmdUndo)
|| IS_CMD(xfeCmdRedo)
|| IS_CMD(xfeCmdCut)
|| IS_CMD(xfeCmdCopy)
|| IS_CMD(xfeCmdPaste)
|| IS_CMD(xfeCmdGetNewMessages)
|| IS_CMD(xfeCmdExpand)
|| IS_CMD(xfeCmdExpandAll)
|| IS_CMD(xfeCmdCollapse)
|| IS_CMD(xfeCmdCollapseAll)
#ifdef DEBUG_akkana
|| IS_CMD(xfeCmdMoveFoldersInto)
#endif
|| IS_CMD(xfeCmdMarkAllMessagesRead)
|| IS_CMD(xfeCmdSendMessagesInOutbox)
|| IS_CMD(xfeCmdDeleteAny)
|| IS_CMD(xfeCmdDeleteFolder)
HG82883
|| IS_CMD(xfeCmdViewProperties)
|| IS_CMD(xfeCmdUpdateMessageCount)
|| IS_CMD(xfeCmdShowPopup))
{
return True;
}
else
{
return XFE_MNListView::handlesCommand(cmd);
}
#undef IS_CMD
}
void
XFE_FolderView::doCommand(CommandType cmd,
void * calldata,
XFE_CommandInfo* info)
{
#define IS_CMD(command) cmd == (command)
const int *selected;
int count;
m_outliner->getSelection(&selected, &count);
D( printf ("in XFE_FolderView::doCommand()\n");)
if (IS_CMD(xfeCmdShowPopup))
{
XP_ASSERT(info);
XEvent *event = (XEvent *)info->event;
int x, y, clickrow;
Widget w = XtWindowToWidget(event->xany.display, event->xany.window);
MSG_FolderLine clickline;
MenuSpec *spec;
int depth;
if (w == NULL) w = m_widget;
/* we create a new popup each time. */
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 */
getToplevel()->notifyInterested(XFE_MNListView::changeFocus, (void*)this);
m_popup = new XFE_PopupMenu("popup",
(XFE_Frame*)m_toplevel, // XXXXXXX
w,
NULL);
m_outliner->translateFromRootCoords(event->xbutton.x_root,
event->xbutton.y_root,
&x, &y);
// figure out which row they clicked in, and choose the
// right popup menu.
clickrow = m_outliner->XYToRow(x, y);
D( printf ("(x,y) = (%d,%d). row is %d\n", x, y, clickrow);)
if (clickrow == -1)
return;
if (! m_outliner->isSelected(clickrow))
m_outliner->selectItemExclusive(clickrow);
acquireLineData(clickrow);
getTreeInfo(NULL, NULL, &depth, NULL);
releaseLineData();
if (!MSG_GetFolderLineByIndex(m_pane, clickrow, 1, &clickline))
return;
if (depth < 1)
{
if (clickline.flags & MSG_FOLDER_FLAG_NEWS_HOST)
spec = newshost_popup_menu;
else
spec = mailserver_popup_menu;
}
else
{
if (clickline.flags & MSG_FOLDER_FLAG_NEWSGROUP)
spec = newsgroup_popup_menu;
else
spec = mailfolder_popup_menu;
}
m_popup->addMenuSpec(spec);
m_popup->position(event);
m_popup->show();
}
else if (IS_CMD(xfeCmdEditPreferences))
{
fe_showMailNewsPreferences(getToplevel(), m_contextData);
}
else if (IS_CMD(xfeCmdOpenSelected))
{
int i;
for (i = 0; i < count; i ++)
{
MSG_FolderLine line;
if (!MSG_GetFolderLineByIndex(m_pane, selected[i], 1, &line)) continue;
if (!(line.level == 1 && line.flags & MSG_FOLDER_FLAG_DIRECTORY))
fe_showMessages(XtParent(getToplevel()->getBaseWidget()),
/* Tao: we might need to check if this returns a
* non-NULL frame
*/
ViewGlue_getFrame(m_contextData),
NULL,
MSG_GetFolderInfo(m_pane, selected[i]),
FALSE, FALSE, MSG_MESSAGEKEYNONE);
}
}
else if (IS_CMD(xfeCmdGetNewMessages))
{
getNewMail();
}
else if (IS_CMD(xfeCmdSendMessagesInOutbox))
{
D( printf ("MSG_FolderPane::sendMessagesInOutbox()\n");)
MSG_Command(m_pane, MSG_DeliverQueuedMessages, (MSG_ViewIndex*)selected, count);
}
else if (IS_CMD(xfeCmdAddNewsgroup))
{
D( printf ("MSG_FolderPane::addNewsgroup()\n");)
MSG_FolderLine line;
MSG_Host *host = NULL;
if (MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line))
{
if (line.flags & MSG_FOLDER_FLAG_NEWS_HOST
|| line.flags & MSG_FOLDER_FLAG_IMAP_SERVER)
{
host = MSG_GetHostFromIndex(m_pane, selected[0]);
#ifdef DEBUG_akkana
if (!host)
printf("Couldn't get host from index\n");
#endif
}
else if (line.flags & MSG_FOLDER_FLAG_NEWSGROUP
|| line.flags & MSG_FOLDER_FLAG_IMAPBOX)
{
MSG_FolderInfo *info = MSG_GetFolderInfo(m_pane, selected[0]);
if (info)
host = MSG_GetHostForFolder(info);
#ifdef DEBUG_akkana
else
printf("Couldn't get folder info\n");
if (info && !host)
printf("Couldn't get host for folder\n");
#endif
}
}
fe_showSubscribeDialog(getToplevel(), getToplevel()->getBaseWidget(), m_contextData, host);
}
else if (IS_CMD(xfeCmdNewFolder))
{
D( printf ("MSG_FolderPane::newFolder()\n");)
MSG_FolderLine line;
if (MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line))
{
if (line.flags & MSG_FOLDER_FLAG_NEWSGROUP
|| line.flags & MSG_FOLDER_FLAG_NEWS_HOST)
MSG_Command(m_pane, MSG_NewNewsgroup, (MSG_ViewIndex*)selected, count);
// fe_showSubscribeDialog(getToplevel(), getToplevel()->getBaseWidget(), m_contextData);
else
{
MSG_Command(m_pane, MSG_NewFolder, (MSG_ViewIndex*)selected, count);
XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::foldersHaveChanged);
}
}
}
else if (IS_CMD(xfeCmdRenameFolder))
{
D( printf ("MSG_FolderPane::renameFolder()\n");)
MSG_Command(m_pane, MSG_DoRenameFolder, (MSG_ViewIndex*)selected, count);
XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::foldersHaveChanged);
}
else if (IS_CMD(xfeCmdEmptyTrash))
{
D( printf ("MSG_FolderPane::emptyTrash()\n");)
MSG_Command(m_pane, MSG_EmptyTrash, (MSG_ViewIndex*)selected, count);
}
else if (IS_CMD(xfeCmdCompressFolders))
{
D( printf ("MSG_FolderPane::compressFolders()\n");)
MSG_Command(m_pane, MSG_CompressFolder, (MSG_ViewIndex*)selected, count);
}
else if (IS_CMD(xfeCmdCompressAllFolders))
{
D( printf ("MSG_FolderPane::compressAllFolders()\n");)
MSG_Command(m_pane, MSG_CompressAllFolders, (MSG_ViewIndex*)selected, count);
}
else if (IS_CMD(xfeCmdDeleteFolder) || IS_CMD(xfeCmdDeleteAny) )
{
D( printf ("MSG_FolderPane::deleteFolder()\n");)
MSG_Command(m_pane, MSG_DeleteFolder, (MSG_ViewIndex*)selected, count);
XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::foldersHaveChanged);
}
HG20388
else if (IS_CMD(xfeCmdEditMailFilterRules))
{
fe_showMailFilterDlg(getToplevel()->getBaseWidget(),
m_contextData,m_pane);
}
else if (IS_CMD(xfeCmdSearchAddress))
{
DD(printf ("searchAddress\n");)
fe_showLdapSearch(XfeAncestorFindApplicationShell(getToplevel()->getBaseWidget()),
/* Tao: we might need to check if this returns a
* non-NULL frame
*/
ViewGlue_getFrame(m_contextData),
(Chrome*)NULL);
}
else if (IS_CMD(xfeCmdViewProperties))
{
MSG_FolderInfo *info = MSG_GetFolderInfo(m_pane, selected[0]);
MSG_FolderLine line;
D(printf("viewProperties\n");)
if (MSG_GetFolderLineById(XFE_MNView::m_master, info, &line))
{
if (line.flags & MSG_FOLDER_FLAG_NEWS_HOST)
{
MSG_NewsHost *host = MSG_GetNewsHostFromIndex(m_pane, selected[0]);
fe_showNewsServerProperties(getToplevel()->getBaseWidget(),
m_contextData,
host);
}
else if (line.flags & MSG_FOLDER_FLAG_NEWSGROUP)
{
fe_showNewsgroupProperties(getToplevel()->getBaseWidget(),
m_contextData,
info);
}
else if (line.flags & MSG_FOLDER_FLAG_MAIL)
{
if (line.level == 1)
fe_showMailServerPreferences(getToplevel(), m_contextData);
else
fe_showMailFolderProperties(getToplevel()->getBaseWidget(),
m_contextData,
m_pane,
info);
}
}
}
else if (IS_CMD(xfeCmdSearch))
{
DD(printf ("searchMailNews\n");)
// Find current selected folder
const int *selected;
int count;
MSG_FolderInfo *folderInfo;
m_outliner->getSelection(&selected, &count);
if ( count > 0 )
{
DD(printf("### Search Selected Folder %d\n", selected[0]);)
folderInfo = MSG_GetFolderInfo(m_pane, (MSG_ViewIndex)(selected[0]));
}
else
{
DD(printf("### Search All Folder\n");)
folderInfo = NULL;
}
// We have to use the parent of the base widget to get
// to the real top level widget. By doing so, when dispatching
// notification, SearchFrame will only get to its registerred
// event this way. in fe_WidgetToContext, there is an intent
// to get to the wrong frame if we don't use the real toplevel
// as the base for the toplevel frames ... dora 12/31/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,
folderInfo);
}
#ifdef DEBUG_akkana
else if (IS_CMD(xfeCmdMoveFoldersInto))
{
MSG_MoveFoldersInto(m_pane, (MSG_ViewIndex*)selected, count,
(MSG_FolderInfo*)info);
XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::foldersHaveChanged);
}
else if (IS_CMD(xfeCmdExpand) || IS_CMD(xfeCmdExpandAll)
|| IS_CMD(xfeCmdCollapse) || IS_CMD(xfeCmdCollapseAll))
{
// Nope, these are the cmds for the thread win, not folder win. :-(
//MSG_CommandType msg_cmd = commandToMsgCmd(cmd);
//MSG_Command(m_pane, msg_cmd, (MSG_ViewIndex*)selected, count);
}
#endif
else if (IS_CMD(xfeCmdNewNewsHost) /* || IS_CMD(xfeCmdAddNewsServer) */)
{
// This code taken out of SubAllView::doCommand():
XFE_NewsServerDialog *d = new XFE_NewsServerDialog(getToplevel()->getBaseWidget(),
"addServer",
/* Tao: we might need to check if this returns a
* non-NULL frame
*/
ViewGlue_getFrame(m_contextData));
XP_Bool ok_pressed = d->post();
if (ok_pressed)
{
const char *serverName = d->getServer();
int serverPort = d->getPort();
XP_Bool isxxx = HG72988;
MSG_NewsHost *host;
host = MSG_CreateNewsHost(XFE_MNView::getMaster(),
serverName,
isxxx,
serverPort);
XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::foldersHaveChanged);
}
delete d;
}
else if (IS_CMD(xfeCmdMarkAllMessagesRead))
{
MSG_Command(m_pane, MSG_MarkAllRead,
(MSG_ViewIndex*)selected, count);
// XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::foldersHaveChanged);
}
else if (IS_CMD(xfeCmdEditConfiguration) ||
IS_CMD(xfeCmdModerateDiscussion) )
{
MSG_CommandType msg_cmd = commandToMsgCmd(cmd);
MSG_Command(m_pane, msg_cmd, (MSG_ViewIndex*)selected, count);
return;
}
/* Do it now
*/
else if ( (cmd == xfeCmdComposeMessage)
|| (cmd == xfeCmdComposeArticle) ) {
if (info) {
CONTEXT_DATA(m_contextData)->stealth_cmd =
((info->event->type == ButtonRelease) &&
(info->event->xkey.state & ShiftMask));
}
MSG_Command(m_pane, commandToMsgCmd(cmd),
(MSG_ViewIndex*)selected, count);
}
else if ( (cmd == xfeCmdComposeMessageHTML)
|| (cmd == xfeCmdComposeArticleHTML) ) {
CONTEXT_DATA(m_contextData)->stealth_cmd =
(fe_globalPrefs.send_html_msg == False);
MSG_Command(m_pane, commandToMsgCmd(cmd),
(MSG_ViewIndex*)selected, count);
}
else if ( (cmd == xfeCmdComposeMessagePlain)
|| (cmd == xfeCmdComposeArticlePlain) ) {
CONTEXT_DATA(m_contextData)->stealth_cmd =
(fe_globalPrefs.send_html_msg == True) ;
MSG_Command(m_pane, commandToMsgCmd(cmd),
(MSG_ViewIndex*)selected, count);
}
/* End of New message
*/
else
{
XFE_MNListView::doCommand(cmd, calldata, info);
return;
}
getToplevel()->notifyInterested(XFE_View::chromeNeedsUpdating);
D( printf ("leaving XFE_FolderView::doCommand()\n");)
#undef IS_CMD
}
char *
XFE_FolderView::commandToString(CommandType cmd, void *calldata, XFE_CommandInfo* info)
{
#define IS_CMD(command) cmd == (command)
const int *selected;
int count;
MSG_FolderLine line;
m_outliner->getSelection(&selected, &count);
// this doesn't handle selections with more than one element in them.
if (IS_CMD(xfeCmdNewFolder))
{
if (count != 1)
return stringFromResource("newFolderCmdString");
MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line);
if (line.flags & MSG_FOLDER_FLAG_NEWSGROUP
|| line.flags & MSG_FOLDER_FLAG_NEWS_HOST)
return stringFromResource("newNewsgroupCmdString");
else /* (line.flags & MSG_FOLDER_FLAG_MAIL) */
if (line.level == 1)
return stringFromResource("newFolderCmdString");
else
return stringFromResource("newSubFolderCmdString");
}
else if (IS_CMD(xfeCmdOpenSelected))
{
if (count != 1)
return stringFromResource("openFolderCmdString");
MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line);
if ((line.flags & MSG_FOLDER_FLAG_NEWSGROUP)
|| (line.flags & MSG_FOLDER_FLAG_NEWS_HOST))
return stringFromResource("openNewsgroupCmdString");
else
return stringFromResource("openFolderCmdString");
}
else if (IS_CMD(xfeCmdDeleteFolder) || IS_CMD(xfeCmdDeleteAny))
{
if (count != 1)
return stringFromResource("deleteFolderCmdString");
MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line);
#if defined(DEBUG_tao)
printf("\n line.flags=%d", line.flags);
#endif
if (line.flags & MSG_FOLDER_FLAG_NEWS_HOST)
return stringFromResource("deleteNewsHostCmdString");
else if (line.flags & MSG_FOLDER_FLAG_NEWSGROUP)
return stringFromResource("unsubscribeNewsgroupCmdString");
else /* (line.flags & MSG_FOLDER_FLAG_MAIL) */
if (line.level == 1)
return stringFromResource("deleteMailHostCmdString");
else
return stringFromResource("deleteFolderCmdString");
}
else if (IS_CMD(xfeCmdViewProperties))
{
if (count != 1)
return stringFromResource("folderPropsCmdString");
MSG_GetFolderLineByIndex(m_pane, selected[0], 1, &line);
if (line.flags & MSG_FOLDER_FLAG_NEWSGROUP)
return stringFromResource("newsgroupPropsCmdString");
else if (line.flags & MSG_FOLDER_FLAG_NEWS_HOST)
return stringFromResource("newsServerPropsCmdString");
else /* mail */
if (line.level == 1)
return stringFromResource("mailServerPropsCmdString");
else
return stringFromResource("folderPropsCmdString");
}
else
{
return XFE_MNListView::commandToString(cmd, calldata, info);
}
#undef IS_CMD
}
fe_icon*
XFE_FolderView::treeInfoToIcon(int depth, int flags, XP_Bool expanded, XP_Bool xxxe)
{
if (depth < 1)
{
if (flags & MSG_FOLDER_FLAG_NEWS_HOST)
return HG17272 &newsServerIcon;
else if (flags & MSG_FOLDER_FLAG_IMAPBOX)
return &mailServerIcon;
else
return &mailLocalIcon;
}
if (flags & MSG_FOLDER_FLAG_NEWSGROUP)
return HG00288 &newsgroupIcon;
else if (flags & MSG_FOLDER_FLAG_INBOX)
return expanded ? &inboxOpenIcon : &inboxIcon;
else if (flags & MSG_FOLDER_FLAG_DRAFTS)
return expanded ? &draftsOpenIcon : &draftsIcon;
else if (flags & MSG_FOLDER_FLAG_TEMPLATES)
return expanded ? &templatesOpenIcon : &templatesIcon;
else if (flags & MSG_FOLDER_FLAG_TRASH)
return &trashIcon;
else if (flags & MSG_FOLDER_FLAG_QUEUE)
return expanded ? &outboxOpenIcon : &outboxIcon;
else if (flags & MSG_FOLDER_FLAG_IMAPBOX)
return expanded ? &folderServerOpenIcon : &folderServerIcon;
else
return expanded ? &folderOpenIcon : &folderIcon;
}
#if defined(USE_MOTIF_DND)
fe_icon_data *
XFE_FolderView::treeInfoToIconData(int depth, int flags, XP_Bool expanded)
{
if (depth < 1)
{
if (flags & MSG_FOLDER_FLAG_NEWS_HOST)
return &MN_NewsServer;
else if (flags & MSG_FOLDER_FLAG_IMAPBOX)
return &MN_MailLocal; /* XXX ? */
else
return &MN_MailLocal;
}
if (flags & MSG_FOLDER_FLAG_NEWSGROUP)
return &MN_Newsgroup;
else if (flags & MSG_FOLDER_FLAG_INBOX)
return expanded ? &MN_InboxO : &MN_Inbox;
else if (flags & MSG_FOLDER_FLAG_DRAFTS)
return expanded ? &MN_DraftO : &MN_Draft;
else if (flags & MSG_FOLDER_FLAG_TEMPLATES)
return expanded ? &MN_TemplateO : &MN_Template;
else if (flags & MSG_FOLDER_FLAG_TRASH)
return &MN_TrashSmall;
else if (flags & MSG_FOLDER_FLAG_QUEUE)
return expanded ? &MN_OutboxO : &MN_Outbox;
else if (flags & MSG_FOLDER_FLAG_IMAPBOX)
return expanded ? &MN_FolderServerO : &MN_FolderServer;
else
return expanded ? &MN_FolderO : &MN_Folder;
}
#endif /* USE_MOTIF_DND */
/* Outlinable interface methods */
char *
XFE_FolderView::getColumnTextByFolderLine(MSG_FolderLine* folderLine,
int column)
{
static char unseen[10];
static char total[10];
switch (column)
{
case OUTLINER_COLUMN_NAME:
{
if (folderLine->prettyName)
return (char*)folderLine->prettyName;
else
return (char*)folderLine->name;
}
case OUTLINER_COLUMN_UNREAD:
{
if (folderLine->level == 1
&& folderLine->flags & MSG_FOLDER_FLAG_DIRECTORY)
{
return "---";
}
else
{
/* if we know how many unseen messages there are,
display the number. otherwise, we put ???'s */
if (folderLine->unseen >= 0)
{
PR_snprintf(unseen, sizeof (unseen), "%d", folderLine->unseen);
return unseen;
}
else
{
return "???";
}
}
}
case OUTLINER_COLUMN_TOTAL:
{
/* if the folder is a directory, just put dashes
for the total messages. */
if (folderLine->level == 1
&& folderLine->flags & MSG_FOLDER_FLAG_DIRECTORY)
{
return "---";
}
else
{
/* if we know how many unseen messages there are,
we also know how many total messages there are.
otherwise, we put ???'s */
if (folderLine->total >= 0)
{
PR_snprintf(total, sizeof (total), "%d", folderLine->total);
return total;
}
else
{
return "???";
}
}
}
default:
XP_ASSERT(0);
return NULL;
}
}
char *XFE_FolderView::getCellTipString(int row, int column)
{
/* returned string will be duplicated by outliner
*/
char *tmp = 0;
if (row < 0) {
/* header
*/
tmp = getColumnHeaderText(column);
}/* if */
else {
/* content
*/
m_ancestorInfo = NULL;
MSG_FolderLine* folderLine =
(MSG_FolderLine *) XP_CALLOC(1, sizeof(MSG_FolderLine));
if (!MSG_GetFolderLineByIndex(m_pane, row, 1, folderLine))
return NULL;
/* static array; do not free
*/
tmp = getColumnTextByFolderLine(folderLine, column);
XP_FREEIF(folderLine);
}/* else */
if (tmp &&
(!m_outliner->isColTextFit(tmp, row, column)))
return tmp;
return NULL;
}
char *XFE_FolderView::getCellDocString(int /* row */, int /* column */)
{
return NULL;
}
void *
XFE_FolderView::ConvFromIndex(int index)
{
return MSG_GetFolderInfo(m_pane, index);
}
int
XFE_FolderView::ConvToIndex(void *item)
{
MSG_ViewIndex index = MSG_GetFolderIndex(m_pane, (MSG_FolderInfo*)item);
if (index == MSG_VIEWINDEXNONE)
return -1;
else
return index;
}
void *
XFE_FolderView::acquireLineData(int line)
{
m_ancestorInfo = NULL;
if (!MSG_GetFolderLineByIndex(m_pane, line, 1, &m_folderLine))
return NULL;
if ( m_folderLine.level > 0 )
{
m_ancestorInfo = new OutlinerAncestorInfo[ m_folderLine.level ];
}
else
{
m_ancestorInfo = new OutlinerAncestorInfo[ 1 ];
}
// ripped straight from the winfe
int i = m_folderLine.level - 1;
int idx = line + 1;
int total_lines = m_outliner->getTotalLines();
while ( i > 0 ) {
if ( idx < total_lines ) {
int level = MSG_GetFolderLevelByIndex(m_pane, idx);
if ( (level - 1) == i ) {
m_ancestorInfo[i].has_prev = TRUE;
m_ancestorInfo[i].has_next = TRUE;
i--;
idx++;
} else if ( (level - 1) < i ) {
m_ancestorInfo[i].has_prev = FALSE;
m_ancestorInfo[i].has_next = FALSE;
i--;
} else {
idx++;
}
} else {
m_ancestorInfo[i].has_prev = FALSE;
m_ancestorInfo[i].has_next = FALSE;
i--;
}
}
m_ancestorInfo[0].has_prev = FALSE;
m_ancestorInfo[0].has_next = FALSE;
return &m_folderLine;
}
void
XFE_FolderView::getTreeInfo(XP_Bool *expandable,
XP_Bool *is_expanded,
int *depth,
OutlinerAncestorInfo **ancestor)
{
XP_Bool is_line_expandable;
XP_Bool is_line_expanded;
is_line_expandable = (m_folderLine.numChildren > 0);
if (is_line_expandable)
{
is_line_expanded = !(m_folderLine.flags & MSG_FOLDER_FLAG_ELIDED);
}
else
{
is_line_expanded = FALSE;
}
if (ancestor)
*ancestor = m_ancestorInfo;
if (depth)
*depth = m_folderLine.level - 1;
if (expandable)
*expandable = is_line_expandable;
if (is_expanded)
*is_expanded = is_line_expanded;
}
EOutlinerTextStyle
XFE_FolderView::getColumnStyle(int /*column*/)
{
return (m_folderLine.unseen > 0) ? OUTLINER_Bold : OUTLINER_Default;
}
#define A_BIG_BUFFER_SIZE 1024 /* I have no idea what the right size is */
char *
XFE_FolderView::getColumnText(int column)
{
static char unseen_a[10]; /* uniquify name for IRIX5.3 */
static char total_a[10];
static char a_line[A_BIG_BUFFER_SIZE];
char *loc;
switch (column)
{
case OUTLINER_COLUMN_NAME:
{
if (m_folderLine.prettyName) {
XP_STRNCPY_SAFE(a_line, m_folderLine.prettyName, sizeof(a_line));
}
else {
XP_STRNCPY_SAFE(a_line, m_folderLine.name, sizeof(a_line));
}
INTL_CONVERT_BUF_TO_LOCALE(a_line, loc);
return a_line;
}
case OUTLINER_COLUMN_UNREAD:
{
if (m_folderLine.level == 1
&& m_folderLine.flags & MSG_FOLDER_FLAG_DIRECTORY)
{
return "---";
}
else
{
/* if we know how many unseen messages there are,
display the number. otherwise, we put ???'s */
#if defined(DEBUG_tao)
if (m_folderLine.unseen < 0)
printf("\n**OUTLINER_COLUMN_UNREAD=%d\n",
m_folderLine.unseen);
#endif
if (m_folderLine.unseen >= 0)
{
PR_snprintf(unseen_a, sizeof (unseen_a), "%d", m_folderLine.unseen);
return unseen_a;
}
else
{
return "???";
}
}
}
case OUTLINER_COLUMN_TOTAL:
{
/* if the folder is a directory, just put dashes
for the total messages. */
if (m_folderLine.level == 1
&& m_folderLine.flags & MSG_FOLDER_FLAG_DIRECTORY)
{
return "---";
}
else
{
/* if we know how many unseen messages there are,
we also know how many total messages there are.
otherwise, we put ???'s */
#if defined(DEBUG_tao)
if (m_folderLine.total < 0)
printf("\n**OUTLINER_COLUMN_TOTAL=%d\n", m_folderLine.total);
#endif
if (m_folderLine.total >= 0)
{
PR_snprintf(total_a, sizeof (total_a), "%d", m_folderLine.total);
return total_a;
}
else
{
return "???";
}
}
}
default:
XP_ASSERT(0);
return NULL;
}
}
fe_icon *
XFE_FolderView::getColumnIcon(int column)
{
XP_Bool expanded;
int depth;
getTreeInfo(NULL, &expanded, &depth, NULL);
if (column == OUTLINER_COLUMN_NAME)
{
XP_Bool xxxe = False;
/* we need to check newshosts */
if (m_folderLine.flags & MSG_FOLDER_FLAG_NEWS_HOST)
{
MSG_NewsHost *host = MSG_GetNewsHostForFolder(m_folderLine.id);
HG82992
}
return treeInfoToIcon(depth, m_folderLine.flags, expanded, xxxe);
}
else
{
return 0;
}
}
char *
XFE_FolderView::getColumnName(int column)
{
switch (column)
{
case OUTLINER_COLUMN_NAME:
return "Name";
case OUTLINER_COLUMN_TOTAL:
return "Total";
case OUTLINER_COLUMN_UNREAD:
return "Unread";
default:
XP_ASSERT(0);
return 0;
}
}
char *
XFE_FolderView::getColumnHeaderText(int column)
{
switch (column)
{
case OUTLINER_COLUMN_NAME:
return XP_GetString(XFE_FOLDER_OUTLINER_COLUMN_NAME);
case OUTLINER_COLUMN_TOTAL:
return XP_GetString(XFE_FOLDER_OUTLINER_COLUMN_TOTAL);
case OUTLINER_COLUMN_UNREAD:
return XP_GetString(XFE_FOLDER_OUTLINER_COLUMN_UNREAD);
default:
XP_ASSERT(0);
return 0;
}
}
fe_icon *
XFE_FolderView::getColumnHeaderIcon(int /*column*/)
{
return 0;
}
EOutlinerTextStyle
XFE_FolderView::getColumnHeaderStyle(int /*column*/)
{
return OUTLINER_Default;
}
void
XFE_FolderView::releaseLineData()
{
delete [] m_ancestorInfo;
m_ancestorInfo = NULL;
}
#ifdef USE_3PANE
static void
click_timer_func(XtPointer closure, XtIntervalId *)
{
XFE_FolderView* fv = (XFE_FolderView*)closure;
DD(printf("---::: Process timer :::---\n");)
if (fv)
fv->processClick();
}
#endif
void
XFE_FolderView::Buttonfunc(const OutlineButtonFuncData *data)
{
MSG_FolderLine line;
// Broadcast to be in focus
getToplevel()->notifyInterested(XFE_MNListView::changeFocus, (void*) this);
if (!MSG_GetFolderLineByIndex(m_pane, data->row, 1, &line)) return;
DD(printf("### times folder clicked %d\n", data->clicks);)
if (data->clicks == 2)
{
#ifdef USE_3PANE
if (m_clickTimer)
XtRemoveTimeOut(m_clickTimer);
m_clickTimer = 0;
DD(printf("---::: Remove timer :::---\n");)
for (int i = 0; i < m_cur_count; i++ )
{
if ( i == 0 )
m_outliner->selectItemExclusive(m_cur_selected[i]);
else
m_outliner->selectItem(m_cur_selected[i]);
}
#else
m_outliner->selectItemExclusive(data->row);
#endif
if (line.level == 1
&& line.flags & MSG_FOLDER_FLAG_DIRECTORY)
{
// they double clicked on a newshost or mail server.
toggleExpansion(data->row);
}
else
{
// ok. we're going to display a folder in a thread frame. what
// is left to do now is determine whether we are going to reuse
// an existing one or pop up another. This is governed by the
// preference reuse_thread_window and whether or not
// the alt button was held during the double click.
fe_showMessages(XtParent(getToplevel()->getBaseWidget()),
/* Tao: we might need to check if this return a
* non-NULL frame
*/
ViewGlue_getFrame(m_contextData),
NULL,
MSG_GetFolderInfo(m_pane, data->row),
(( fe_globalPrefs.reuse_thread_window
&& !data->shift)
|| (!fe_globalPrefs.reuse_thread_window
&& data->shift)),
False,
MSG_MESSAGEKEYNONE);
}
}
else
{
if (data->ctrl)
{
m_outliner->toggleSelected(data->row);
}
else if (data->shift)
{
// select the range.
const int *selected;
int count;
m_outliner->getSelection(&selected, &count);
if (count == 0) /* there wasn't anything selected yet. */
{
m_outliner->selectItemExclusive(data->row);
}
else if (count == 1) /* there was only one, so we select the range from
that item to the new one. */
{
m_outliner->selectRangeByIndices(selected[0], data->row);
}
else /* we had a range of items selected, so let's do something really
nice with them. */
{
m_outliner->trimOrExpandSelection(data->row);
}
}
else
{
#ifdef USE_3PANE
const int *selected;
int count;
m_outliner->getSelection(&selected, &count);
m_cur_selected= (int *)XP_CALLOC(count, sizeof(int));
for ( int i =0; i < count; i++ )
m_cur_selected[i] = selected[i];
m_cur_count = count;
m_outliner->selectItemExclusive(data->row);
m_clickData = (XtPointer)data;
if (m_clickTimer)
XtRemoveTimeOut(m_clickTimer);
m_clickTimer = XtAppAddTimeOut(fe_XtAppContext, 650,
click_timer_func, this);
DD(printf("### ---::: Install timer :::--- ###\n");)
#else
m_outliner->selectItemExclusive(data->row);
notifyInterested(folderSelected, MSG_GetFolderInfo(m_pane, data->row));
#endif
}
getToplevel()->notifyInterested(XFE_View::chromeNeedsUpdating);
}
}
#ifdef USE_3PANE
// This is the routine that will select a folder for single click.
void
XFE_FolderView::processClick()
{
OutlineButtonFuncData *data = (OutlineButtonFuncData *)m_clickData;
MSG_FolderInfo *info = MSG_GetFolderInfo(m_pane, data->row);
XFE_ThreadFrame *theFrame = XFE_ThreadFrame::frameForInfo(info);
if ( theFrame)
{
// if the frame exists, then, single click perform the
// same way as the double click mode by bringing the existing
// frame to the foreground
#if 0
for (int i = 0; i < m_cur_count; i++ )
m_outliner->selectItemExclusive(m_cur_selected[i]);
#endif
fe_showMessages(XtParent(getToplevel()->getBaseWidget()),
/* Tao: we might need to check if this return a
* non-NULL frame
*/
ViewGlue_getFrame(m_contextData),
NULL,
MSG_GetFolderInfo(m_pane, data->row),
(( fe_globalPrefs.reuse_thread_window
&& !data->shift)
|| (!fe_globalPrefs.reuse_thread_window
&& data->shift)),
False,
MSG_MESSAGEKEYNONE);
}
else
{
m_outliner->selectItemExclusive(data->row);
notifyInterested(folderSelected, info);
}
m_clickTimer = 0;
XP_FREEIF(m_cur_selected);
m_cur_selected = NULL;
m_cur_count = 0 ;
}
#endif
void
XFE_FolderView::toggleExpansion(int row)
{
int delta;
XP_Bool selection_needs_bubbling = False;
delta = MSG_ExpansionDelta(m_pane, row);
if (delta == 0)
return;
/* we're not selected and we're being collapsed.
check if any of our children are selected, and if
so we select this row. */
if (!m_outliner->isSelected(row)
&& delta < 0)
{
int num_children = -1 * delta;
int i;
for (i = row + 1; i <= row + num_children; i ++)
if (m_outliner->isSelected(i))
{
selection_needs_bubbling = True;
}
}
MSG_ToggleExpansion(m_pane, row, NULL);
if (selection_needs_bubbling)
m_outliner->selectItem(row);
getToplevel()->notifyInterested(XFE_View::chromeNeedsUpdating);
}
void
XFE_FolderView::Flippyfunc(const OutlineFlippyFuncData *data)
{
toggleExpansion(data->row);
}
#if !defined(USE_MOTIF_DND)
void
XFE_FolderView::dropfunc(Widget /*dropw*/, fe_dnd_Event type,
fe_dnd_Source *source, XEvent *event)
{
int row = -1;
int x, y;
/* we only understand these targets -- well, we only understand the last 3,
and the outliner understands the first one. */
if (source->type != FE_DND_COLUMN &&
source->type != FE_DND_MAIL_MESSAGE &&
source->type != FE_DND_NEWS_MESSAGE &&
source->type != FE_DND_MAIL_FOLDER)
{
return;
}
if (source->type == FE_DND_COLUMN)
{
m_outliner->handleDragEvent(event, type, source);
return;
}
/* we've got to have a sourcedropfunc to drop things in a folder view,
since the work must really be done by the source. */
if (source->func == NULL)
{
return;
}
m_outliner->translateFromRootCoords(event->xbutton.x_root, event->xbutton.y_root, &x, &y);
row = m_outliner->XYToRow(x, y);
if (row >= 0)
{
MSG_FolderLine folder;
if (!MSG_GetFolderLineByIndex(m_pane,
row, 1, &folder))
row = -1;
}
switch (type)
{
case FE_DND_START:
DD(printf("### DRAG> button press = %d\n", ((event->xany.type == ButtonPress)? 1: 0 ) );)
DD(printf("### DRAG> button release = %d\n", ((event->xany.type == ButtonRelease)? 1: 0 ) );)
DD(printf("### DRAG> alt key state = %d\n", ((event->xkey.state &Mod1Mask)? 1: 0 ) );)
/* ### In outliner, we set ignoreevent to true when the event
type is ButtonPress; therefore, we won't be getting
button press event here. We cannot perform stealth command
at button press time when drag take place. We can only
perform stealth command at button release time. Need
to find out why we set "ignoreevnt" to true in outliner. ### */
#if 0
CONTEXT_DATA(m_contextData)->stealth_cmd =
((event->xany.type == ButtonPress) &&
(event->xkey.state & Mod1Mask));
#endif
break;
case FE_DND_DRAG:
m_outliner->outlineLine(row);
break;
case FE_DND_DROP:
DD(printf("### DROP> button press = %d\n", ((event->xany.type == ButtonPress)? 1: 0 ) );)
DD(printf("### DROP> button release = %d\n", ((event->xany.type == ButtonRelease)? 1: 0 ) );)
DD(printf("### DROP> alt key state = %d\n", ((event->xkey.state &Mod1Mask)? 1: 0 ) );)
CONTEXT_DATA(m_contextData)->stealth_cmd =
((event->xany.type == ButtonRelease) &&
(event->xkey.state & Mod1Mask));
if (row >= 0)
{
MSG_FolderInfo *drop_info = MSG_GetFolderInfo(m_pane, row);
if (drop_info)
{
fe_dnd_Message msg;
if ( source->type == FE_DND_NEWS_MESSAGE )
{
DD(printf("### FolderView::dropfunc: NEWS MESSAGE_COPY ******\n");)
msg = FE_DND_MESSAGE_COPY;
}
else if (( source->type == FE_DND_MAIL_MESSAGE) &&
(CONTEXT_DATA(m_contextData)->stealth_cmd ))
{
DD(printf("### FolderView::dropfunc: MAIL MESSAGE_COPY ******\n");)
msg = FE_DND_MESSAGE_COPY;
}
else
{
DD(printf("### FolderView::dropfunc: MAIL MESSAGE_MOVE ******\n");)
msg = FE_DND_MESSAGE_MOVE;
}
(*source->func)(source, msg, (void*)drop_info);
}
D(printf ("Outlining line -1\n");)
m_outliner->outlineLine(-1); // to clear the drag feedback
}
}
}
void
XFE_FolderView::drop_func(Widget dropw, void *closure, fe_dnd_Event type,
fe_dnd_Source *source, XEvent* event)
{
XFE_FolderView *obj = (XFE_FolderView*)closure;
obj->dropfunc(dropw, type, source, event);
}
void
XFE_FolderView::sourcedropfunc(fe_dnd_Source *, fe_dnd_Message msg, void *closure)
{
// folders can be moved or deleted. The closure to this function will always
// be a MSG_FolderInfo*.
// XXX assume that nothing could have changed the selected between the time
// we started dragging and now... don't know how smart this is...
MSG_FolderInfo *info = (MSG_FolderInfo*)closure;
const int *indices;
int count;
DD(printf("### Enter XFE_FolderView::sourcedropfunc()\n");)
m_outliner->getSelection(&indices, &count);
MSG_DragEffect requireEffect = MSG_Default_Drag;
MSG_DragEffect effect = MSG_DragFoldersIntoStatus(m_pane,
(MSG_ViewIndex*)indices, count,
info, requireEffect);
if (msg == FE_DND_MESSAGE_MOVE )
{
DD(printf("### XFE_FolderView::sourcedropfunc:: FE_DND_MESSAGE_MOVE ##\n");)
if (effect == MSG_Require_Move)
{
DD(printf("## XFE_FolderView::sourcedropfunc:: Move FOLDER REQUIRED ##\n");)
MSG_MoveFoldersInto(m_pane, (MSG_ViewIndex*)indices, count, info);
XFE_MozillaApp::theApp()->notifyInterested(XFE_MNView::foldersHaveChanged);
}
else if ( effect == MSG_Drag_Not_Allowed )
{
DD(printf("### Drag NOT allowed : DROP SITE \n");)
char tmp[128];
XP_SAFE_SPRINTF(tmp, sizeof(tmp),
"%s",
XP_GetString(XFE_DND_MESSAGE_ERROR));
XFE_Progress (m_contextData, tmp);
}
else
XP_ASSERT(0);
}
else if (msg == FE_DND_MESSAGE_DELETE)
{
// do something spiffy here, like unsubscribe if it's a newsgroup,
// and move to the trash if it's a mail folder.
}
}
void
XFE_FolderView::source_drop_func(fe_dnd_Source *src, fe_dnd_Message msg, void *closure)
{
XFE_FolderView *obj = (XFE_FolderView*)src->closure;
obj->sourcedropfunc(src, msg,closure);
}
#else
fe_icon_data *
XFE_FolderView::GetDragIconData(int row, int column)
{
D(printf("XFE_FolderView::GetDragIconData()\n");)
XP_Bool expanded;
int depth;
if (row == -1) return &MN_Folder;
else
{
acquireLineData(row);
getTreeInfo(NULL, &expanded, &depth, NULL);
releaseLineData();
return treeInfoToIconData(depth, m_folderLine.flags, expanded);
}
}
fe_icon_data *
XFE_FolderView::getDragIconData(void *this_ptr,
int row,
int column)
{
D(printf("XFE_FolderView::getDragIconData()\n");)
XFE_FolderView *folder_view = (XFE_FolderView*)this_ptr;
return folder_view->GetDragIconData(row, column);
}
void
XFE_FolderView::GetDragTargets(int row, int column,
Atom **targets,
int *num_targets)
{
D(printf("XFE_FolderView::GetDragTargets()\n");)
int depth;
int flags;
XP_ASSERT(row > -1);
if (row == -1)
{
*targets = NULL;
*num_targets = 0;
}
else
{
if (!m_outliner->isSelected(row))
m_outliner->selectItemExclusive(row);
acquireLineData(row);
getTreeInfo(NULL, NULL, &depth, NULL);
flags = m_folderLine.flags;
releaseLineData();
*num_targets = 3;
*targets = new Atom[ *num_targets ];
(*targets)[1] = XFE_DragBase::_XA_NETSCAPE_URL;
(*targets)[2] = XA_STRING;
if (depth < 1)
{
if (flags & MSG_FOLDER_FLAG_NEWS_HOST)
(*targets)[0] = XFE_OutlinerDrop::_XA_NETSCAPE_NEWS_SERVER;
else
(*targets)[0] = XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_SERVER;
}
else if (flags & MSG_FOLDER_FLAG_NEWSGROUP)
(*targets)[0] = XFE_OutlinerDrop::_XA_NETSCAPE_NEWSGROUP;
else
(*targets)[0] = XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_FOLDER;
}
}
void
XFE_FolderView::getDragTargets(void *this_ptr,
int row,
int column,
Atom **targets,
int *num_targets)
{
D(printf("XFE_FolderView::getDragTargets()\n");)
XFE_FolderView *folder_view = (XFE_FolderView*)this_ptr;
folder_view->GetDragTargets(row, column, targets, num_targets);
}
void
XFE_FolderView::getDropTargets(void */*this_ptr*/,
Atom **targets,
int *num_targets)
{
D(printf("XFE_FolderView::getDropTargets()\n");)
*num_targets = 7;
*targets = new Atom[ *num_targets ];
(*targets)[0] = XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_FOLDER;
(*targets)[1] = XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_MESSAGE;
(*targets)[2] = XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_SERVER;
(*targets)[3] = XFE_OutlinerDrop::_XA_NETSCAPE_NEWSGROUP;
(*targets)[4] = XFE_OutlinerDrop::_XA_NETSCAPE_NEWS_MESSAGE;
(*targets)[5] = XFE_OutlinerDrop::_XA_NETSCAPE_NEWS_SERVER;
(*targets)[6] = XFE_OutlinerDrop::_XA_NETSCAPE_URL; /* a specialized class of urls are allowed. */
}
char *
XFE_FolderView::DragConvert(Atom atom)
{
if (atom == XFE_DragBase::_XA_NETSCAPE_URL)
{
// translate drag data to NetscapeURL format
XFE_URLDesktopType urlData;
char *result;
const int *selection;
int count;
int i;
m_outliner->getSelection(&selection, &count);
urlData.createItemList(1);
for (i = 0; i < count; i ++)
{
MSG_FolderInfo* info = MSG_GetFolderInfo(m_pane, selection[i]);
URL_Struct *url = MSG_ConstructUrlForFolder(m_pane,
info);
urlData.url(i,url->address);
NET_FreeURLStruct(url);
}
result = XtNewString(urlData.getString());
return result;
}
else if (atom == XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_FOLDER
|| atom == XFE_OutlinerDrop::_XA_NETSCAPE_NEWSGROUP
|| atom == XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_SERVER
|| atom == XFE_OutlinerDrop::_XA_NETSCAPE_NEWS_SERVER)
{
/* for now we use a hack -- only transfer the index of the dragged
folder. */
char buf[100];
const int *selection;
int count;
m_outliner->getSelection(&selection, &count);
PR_snprintf(buf, 100, "%d",
selection[0]);
return (char*)XtNewString(buf);
}
else
{
return (char*)XtNewString("");
}
}
char *
XFE_FolderView::dragConvert(void *this_ptr,
Atom atom)
{
XFE_FolderView *folder_view = (XFE_FolderView*)this_ptr;
return folder_view->DragConvert(atom);
}
int
XFE_FolderView::ProcessTargets(int row, int col,
Atom *targets,
const char **data,
int numItems)
{
int i;
D(printf("XFE_FolderView::ProcessTargets()\n");)
for (i = 0; i<numItems; i ++)
{
if (targets[i]==None || data[i]==NULL || strlen(data[i])==0)
continue;
D((" [%d] %s: \"%s\"\n",i,XmGetAtomName(XtDisplay(m_widget),targets[i]),data[i]));
if (targets[i] == XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_FOLDER
|| targets[i] == XFE_OutlinerDrop::_XA_NETSCAPE_NEWSGROUP)
{
MSG_ViewIndex index = (MSG_ViewIndex)atoi(data[i]);
MSG_FolderInfo *info = MSG_GetFolderInfo(m_pane, row);
if (info)
{
MSG_MoveFoldersInto(m_pane, &index, 1, info);
return TRUE;
}
else
return FALSE;
}
else if (targets[i] == XFE_OutlinerDrop::_XA_NETSCAPE_MAIL_MESSAGE
|| targets[i] == XFE_OutlinerDrop::_XA_NETSCAPE_NEWS_MESSAGE)
{
return TRUE;
}
else if (targets[i] == XFE_OutlinerDrop::_XA_NETSCAPE_URL)
{
MSG_FolderInfo *dest_info = MSG_GetFolderInfo(m_pane, row);
XFE_URLDesktopType urlData(data[i]);
MSG_ViewIndex *indices;
int num_indices = 0;
if (dest_info == NULL) return FALSE;
indices = new MSG_ViewIndex[ urlData.numItems() ];
for (i = 0; i < urlData.numItems(); i ++)
{
const char *url = urlData.url(i);
if (MSG_PaneTypeForURL(url) != MSG_FOLDERPANE)
continue;
else
{
MSG_FolderInfo *info = MSG_GetFolderInfoFromURL(m_master,
url,FALSE);
MSG_ViewIndex new_index;
if (!info)
continue;
new_index = MSG_GetFolderIndexForInfo(m_pane,
info, TRUE);
if (new_index != MSG_VIEWINDEXNONE)
indices[num_indices ++] = new_index;
}
}
if (num_indices > 0)
MSG_MoveFoldersInto(m_pane, indices, num_indices, dest_info);
delete [] indices;
return num_indices > 0;
}
}
return FALSE;
}
int
XFE_FolderView::processTargets(void *this_ptr,
int row, int col,
Atom *targets,
const char **data,
int numItems)
{
XFE_FolderView *folder_view = (XFE_FolderView*)this_ptr;
return folder_view->ProcessTargets(row, col, targets, data, numItems);
}
#endif /* USE_MOTIF_DND */