home *** CD-ROM | disk | FTP | other *** search
- /* -*- 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.
- */
- /*
- Folder.cpp -- class for doing the dynamic folder menus
- Created: Chris Toshok <toshok@netscape.com>, 19-Dec-1996.
- */
-
-
-
- #include "FolderMenu.h"
- #include "MNView.h"
- #include "MozillaApp.h"
- #include "felocale.h"
-
- #include <Xm/LabelG.h>
- #include <Xm/SeparatoG.h>
- #include <Xfe/Xfe.h>
-
-
-
- #include "xpgetstr.h"
- extern int XFE_FOLDER_MENU_FILE_HERE;
-
- #define MORE_BUTTON_NAME "mailNewsMoreButton"
- #define MORE_PULLDOWN_NAME "mailNewsMorePulldown"
-
- typedef struct FolderCons {
- XFE_FolderMenu *menu;
- MSG_FolderInfo *info;
- } FolderCons;
-
- XFE_FolderMenu::XFE_FolderMenu(CommandType cmd, Widget w, XFE_Frame *frame)
- {
- m_cascade = w;
- m_parentFrame = frame;
- m_cmd = cmd;
-
- XtAddCallback(m_cascade, XmNdestroyCallback, destroy_cb, this);
-
- XtVaGetValues(m_cascade,
- XmNsubMenuId, &m_submenu,
- NULL);
-
- XtVaGetValues(m_submenu,
- XmNnumChildren, &m_firstslot,
- NULL);
-
- XP_ASSERT(m_submenu);
-
- XFE_MozillaApp::theApp()->registerInterest(XFE_MNView::foldersHaveChanged,
- this,
- (XFE_FunctionNotification)foldersHaveChanged_cb);
-
- // make sure we initially install an update callback
- foldersHaveChanged(NULL, NULL, NULL);
- }
-
- XFE_FolderMenu::~XFE_FolderMenu()
- {
- XFE_MozillaApp::theApp()->unregisterInterest(XFE_MNView::foldersHaveChanged,
- this,
- (XFE_FunctionNotification)foldersHaveChanged_cb);
- }
-
- void
- XFE_FolderMenu::generate(Widget cascade, XtPointer clientData, XFE_Frame *frame)
- {
- XFE_FolderMenu *obj;
- CommandType cmd = Command::intern((char*)clientData);
-
- obj = new XFE_FolderMenu(cmd, cascade, frame);
- }
-
- void
- XFE_FolderMenu::activate_cb(Widget, XtPointer cd, XtPointer)
- {
- FolderCons *cons = (FolderCons*)cd;
- XFE_FolderMenu *obj = cons->menu;
- MSG_FolderInfo *info = cons->info;
-
- XP_ASSERT(info);
-
- if (obj->m_parentFrame->handlesCommand(obj->m_cmd, (void*)info))
- obj->m_parentFrame->doCommand(obj->m_cmd, (void*)info);
- }
-
- void
- XFE_FolderMenu::add_folder_menu_items(Widget menu,
- MSG_FolderInfo *info,
- XP_Bool filing_allowed_here)
- {
- int32 count;
- Arg av [20];
- int ac;
-
-
- if (filing_allowed_here)
- {
- Widget button;
- FolderCons *cons = XP_NEW_ZAP(FolderCons);
- char buf[500];
- XmString xmname;
- char *folderFileName, *folderName;
-
- folderName = (char*)MSG_GetFolderNameFromID(info);
- if (strrchr(folderName, '/'))
- folderFileName = strrchr(folderName, '/') + 1;
- else
- folderFileName = folderName;
-
- PR_snprintf(buf, sizeof(buf), XP_GetString(XFE_FOLDER_MENU_FILE_HERE), folderFileName);
-
- xmname = XmStringCreate(buf, XmFONTLIST_DEFAULT_TAG);
-
- cons->menu = this;
- cons->info = info;
-
- ac = 0;
- XtSetArg(av[ac], XmNuserData, NULL); ac ++;
- XtSetArg (av[ac], XmNlabelString, xmname); ac++;
-
- button = XmCreatePushButtonGadget(menu, Command::getString(m_cmd), av, ac);
-
- XmStringFree(xmname);
-
- XtAddCallback(button, XmNactivateCallback, activate_cb, cons);
- XtAddCallback(button, XmNdestroyCallback, free_cons_cb, cons);
- XtManageChild(button);
- XtVaCreateManagedWidget("sep",
- xmSeparatorGadgetClass,
- menu,
- XmNshadowThickness, 2,
- NULL);
- }
-
- count = MSG_GetFolderChildren(fe_getMNMaster(), info, NULL, 0);
-
- if (count == 0)
- {
- return;
- }
- else
- {
- MSG_FolderInfo **infos = (MSG_FolderInfo**)XP_CALLOC(count, sizeof(MSG_FolderInfo*));
- int i;
-
- MSG_GetFolderChildren(fe_getMNMaster(), info, infos, count);
-
- for (i = 0; i < count; i ++)
- {
- XmString xmname;
- FolderCons *cons = XP_NEW_ZAP(FolderCons);
-
- // Find the last of the "More..." menu panes
- Widget parent = getLastMoreMenu(menu);
-
- XP_ASSERT( XfeIsAlive(parent) );
- XP_ASSERT( XmIsRowColumn(parent) );
-
- cons->menu = this;
- cons->info = infos[i];
-
- if (MSG_GetFolderChildren(fe_getMNMaster(), infos[i], NULL, 0) > 0)
- {
- Visual *v;
- Colormap cmap;
- Cardinal depth;
- Widget button;
- Widget submenu;
- char *folderName;
- char *folderFileName;
-
- XtVaGetValues (XtParent(parent), XtNvisual, &v,
- XtNcolormap, &cmap, XtNdepth, &depth, 0);
-
- ac = 0;
- XtSetArg (av[ac], XmNvisual, v); ac++;
- XtSetArg (av[ac], XmNdepth, depth); ac++;
- XtSetArg (av[ac], XmNcolormap, cmap); ac++;
- submenu = XmCreatePulldownMenu (parent, "folderCascadeMenu",
- av, ac);
-
- folderName = (char*)MSG_GetFolderNameFromID(infos[i]);
- if (strrchr(folderName, '/'))
- folderFileName = strrchr(folderName, '/') + 1;
- else
- folderFileName = folderName;
-
- xmname = XmStringCreate(folderFileName, XmFONTLIST_DEFAULT_TAG);
-
- ac = 0;
- XtSetArg (av[ac], XmNlabelString, xmname); ac++;
- XtSetArg (av[ac], XmNsubMenuId, submenu); ac++;
- XtSetArg (av[ac], XmNuserData, NULL); ac++;
- button = XmCreateCascadeButtonGadget (parent, "folderCascadeButton",
- av, ac);
-
- XtAddCallback(button, XmNcascadingCallback, fillin_menu,
- cons);
- XtAddCallback(button, XmNdestroyCallback, free_cons_cb, cons);
- XtManageChild (button);
- }
- else
- {
- Widget button;
- char *folderName;
- char *folderFileName;
-
- folderName = (char*)MSG_GetFolderNameFromID(infos[i]);
- if (strrchr(folderName, '/'))
- folderFileName = strrchr(folderName, '/') + 1;
- else
- folderFileName = folderName;
-
- xmname = XmStringCreate(folderFileName, XmFONTLIST_DEFAULT_TAG);
-
- ac = 0;
- XtSetArg(av[ac], XmNuserData, NULL); ac ++;
- XtSetArg (av[ac], XmNlabelString, xmname); ac++;
-
- button = XmCreatePushButtonGadget(parent, Command::getString(m_cmd), av, ac);
-
- XtAddCallback(button, XmNactivateCallback, activate_cb, cons);
- XtAddCallback(button, XmNdestroyCallback, free_cons_cb, cons);
- XtManageChild(button);
- }
- XmStringFree(xmname);
- }
-
- XP_FREE(infos);
- }
- }
-
- void
- XFE_FolderMenu::fillin_menu(Widget widget, XtPointer clientData, XtPointer)
- {
- FolderCons *cons = (FolderCons*)clientData;
- XFE_FolderMenu *obj = cons->menu;
- MSG_FolderInfo *info = cons->info;
- Widget menu = 0;
- XtVaGetValues(widget, XmNsubMenuId, &menu, 0);
-
- if (info)
- obj->add_folder_menu_items(menu, info, True);
-
- XtRemoveCallback(widget, XmNcascadingCallback, fillin_menu, cons);
- }
-
- void
- XFE_FolderMenu::update()
- {
- Widget *kids;
- int nkids;
-
- XtVaGetValues (m_submenu, XmNchildren, &kids, XmNnumChildren, &nkids, 0);
-
- if (nkids)
- {
- kids = &(kids[m_firstslot]);
- nkids -= m_firstslot;
-
- XtUnmanageChildren (kids, nkids);
- fe_DestroyWidgetTree(kids, nkids);
- }
-
- {
- MSG_FolderInfo **mailfolderinfos = NULL;
- int num_mailfolderinfos, i;
-
- num_mailfolderinfos = MSG_GetFoldersWithFlag(fe_getMNMaster(), MSG_FOLDER_FLAG_MAIL, NULL, 0);
- if (num_mailfolderinfos > 0)
- {
- mailfolderinfos = (MSG_FolderInfo**)XP_ALLOC(sizeof(MSG_FolderInfo*) * num_mailfolderinfos);
- MSG_GetFoldersWithFlag(fe_getMNMaster(), MSG_FOLDER_FLAG_MAIL, mailfolderinfos, num_mailfolderinfos);
- }
-
- for (i = 0; i < num_mailfolderinfos; i ++)
- {
- MSG_FolderLine line;
-
- if (MSG_GetFolderLineById(fe_getMNMaster(), mailfolderinfos[i], &line))
- {
- if (line.level == 1)
- {
- XmString label_str = XmStringCreate((char*)(line.prettyName
- ? line.prettyName : line.name),
- XmFONTLIST_DEFAULT_TAG);
- XtVaCreateManagedWidget("sep",
- xmSeparatorGadgetClass,
- m_submenu,
- XmNshadowThickness, 2,
- NULL);
- XtVaCreateManagedWidget("label",
- xmLabelGadgetClass,
- m_submenu,
- XmNlabelString, label_str,
- NULL);
- XmStringFree(label_str);
- XtVaCreateManagedWidget("sep",
- xmSeparatorGadgetClass,
- m_submenu,
- XmNshadowThickness, 2,
- NULL);
-
- add_folder_menu_items(m_submenu, mailfolderinfos[i], False);
- }
- }
- }
-
- if (mailfolderinfos)
- XP_FREE(mailfolderinfos);
- }
-
- XtRemoveCallback(m_cascade, XmNcascadingCallback, update_cb, this);
- }
-
- void
- XFE_FolderMenu::update_cb(Widget, XtPointer clientData, XtPointer)
- {
- XFE_FolderMenu *obj = (XFE_FolderMenu*)clientData;
-
- obj->update();
- }
-
- void
- XFE_FolderMenu::destroy_cb(Widget, XtPointer clientData, XtPointer)
- {
- XFE_FolderMenu *obj = (XFE_FolderMenu*)clientData;
-
- delete obj;
- }
-
- void
- XFE_FolderMenu::free_cons_cb(Widget, XtPointer clientData, XtPointer)
- {
- XP_FREE(clientData);
- }
-
- XFE_CALLBACK_DEFN(XFE_FolderMenu, foldersHaveChanged)(XFE_NotificationCenter *,
- void *,
- void *)
- {
- // This may seem stupid, but it keeps us from having more than
- // one reference to this particular callback without having
- // to worry about other cascadingCallbacks.
-
- // remove it if it's already there
- XtRemoveCallback(m_cascade, XmNcascadingCallback, update_cb, this);
-
- // and then add it back.
- XtAddCallback(m_cascade, XmNcascadingCallback, update_cb, this);
- }
-
- Widget
- XFE_FolderMenu::getLastMoreMenu(Widget menu)
- {
- XP_ASSERT( XfeIsAlive(menu) );
- XP_ASSERT( XmIsRowColumn(menu) );
-
- // Find the last more... menu
- Widget last_more_menu = XfeMenuFindLastMoreMenu(menu,MORE_BUTTON_NAME);
-
- XP_ASSERT( XfeIsAlive(last_more_menu) );
-
- // Check if the last menu is full
- if (XfeMenuIsFull(last_more_menu))
- {
- // Look for the More... button for the last menu
- Widget more_button = XfeMenuGetMoreButton(last_more_menu,
- MORE_BUTTON_NAME);
-
- // If no more button, create one plus a submenu
- if (!more_button)
- {
- more_button = createMoreButton(last_more_menu);
-
- XtManageChild(more_button);
- }
-
- // Set the last more menu to the submenu of the new more button
- last_more_menu = XfeCascadeGetSubMenu(more_button);
- }
-
- return last_more_menu;
- }
- //////////////////////////////////////////////////////////////////////////
- Widget
- XFE_FolderMenu::createMoreButton(Widget menu)
- {
- XP_ASSERT( XfeIsAlive(menu) );
- XP_ASSERT( XmIsRowColumn(menu) );
-
- Widget cascade;
- Widget submenu = NULL;
- Arg av[5];
- Cardinal ac = 0;
-
- ac = 0;
- XtSetArg(av[ac],XmNvisual, XfeVisual(menu)); ac++;
- XtSetArg(av[ac],XmNdepth, XfeDepth(menu)); ac++;
- XtSetArg(av[ac],XmNcolormap, XfeColormap(menu)); ac++;
-
- submenu = XmCreatePulldownMenu(menu,MORE_PULLDOWN_NAME,av,ac);
-
- ac = 0;
- XtSetArg(av[ac],XmNsubMenuId, submenu); ac++;
-
- cascade = XmCreateCascadeButtonGadget(menu,MORE_BUTTON_NAME,av,ac);
-
- return cascade;
- }
- //////////////////////////////////////////////////////////////////////////
-