Mozilla/mozilla/cmd/xfe/src/BackForwardMenu.cpp
ltabb 8ed5afe62c Free the lizard
git-svn-id: svn://10.0.0.236/trunk@10 18797224-902f-48f8-a5cc-f745e15eee43
1998-03-28 02:44:41 +00:00

376 lines
9.4 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.
*/
/*---------------------------------------*/
/* */
/* Name: FrameListMenu.cpp */
/* Description: XFE_FrameListMenu component implementation. */
/* These are the menu items that appear at the end of the */
/* */
/* Author: Ramiro Estrugo <ramiro@netscape.com> */
/* Date: Sun Mar 2 01:34:13 PST 1997 */
/* */
/*----------------------------------------------------------------------*/
#include "BackForwardMenu.h"
#include "MozillaApp.h"
#include "View.h"
#include "Frame.h"
#include "felocale.h"
#include "intl_csi.h"
#include <Xm/PushBG.h>
#include <Xfe/Cascade.h>
#include "xpgetstr.h" // for XP_GetString()
#define MAX_MENU_ITEM_LENGTH 40
#define MAX_NUM_HISTORY_MENU_ITEMS 15
extern int XFE_UNTITLED;
//////////////////////////////////////////////////////////////////////////
//
// Used to pass data to the callbacks
//
//////////////////////////////////////////////////////////////////////////
typedef struct
{
XFE_BackForwardMenu * object; // Object
History_entry * entry; // History entry
} _HistoryCallbackStruct;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
XFE_BackForwardMenu::XFE_BackForwardMenu(XFE_Frame * frame,
Widget cascade,
int forward) :
_frame(frame),
_cascade(cascade),
_forward(forward)
{
// Obtain the submenu
XtVaGetValues(_cascade,XmNsubMenuId,&_submenu,NULL);
XP_ASSERT( _submenu != NULL );
XP_ASSERT( XfeIsCascade(_cascade) );
XtAddCallback(_cascade,
XmNdestroyCallback,
&XFE_BackForwardMenu::cascadeDestroyCB,
(XtPointer) this);
XtAddCallback(_cascade,
XmNcascadingCallback,
&XFE_BackForwardMenu::cascadingCB,
(XtPointer) this);
// Make the delay large to get the desired "hold" effect
XtVaSetValues(_cascade,XmNmappingDelay,300,NULL);
}
//////////////////////////////////////////////////////////////////////////
XFE_BackForwardMenu::~XFE_BackForwardMenu()
{
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::generate(Widget cascade,
XtPointer data,
XFE_Frame * frame)
{
XFE_BackForwardMenu * obj;
obj = new XFE_BackForwardMenu(frame,cascade,(int) data);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Cascade callbacks
//
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::cascadeDestroyCB(Widget,XtPointer clientData,XtPointer)
{
XFE_BackForwardMenu * obj = (XFE_BackForwardMenu*)clientData;
XP_ASSERT( obj != NULL );
delete obj;
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::cascadingCB(Widget,XtPointer clientData,XtPointer)
{
XFE_BackForwardMenu *obj = (XFE_BackForwardMenu*)clientData;
XP_ASSERT( obj != NULL );
obj->cascading();
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::cascading()
{
destroyItems();
fillSubmenu(_forward);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::destroyItems()
{
XP_ASSERT( XfeIsAlive(_cascade) );
XfeCascadeDestroyChildren(_cascade);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::addItems(XP_List * list,
XP_Bool forward)
{
int num_items = 0;
while(list)
{
History_entry * entry = (History_entry *) list->object;
XP_ASSERT( entry != NULL );
if (entry && (num_items < MAX_NUM_HISTORY_MENU_ITEMS))
{
addItem(num_items++,entry);
}
if(forward)
{
list = list->next;
}
else
{
list = list->prev;
}
}
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::fillSubmenu(XP_Bool forward)
{
XP_ASSERT( _frame != NULL );
MWContext * context = _frame->getContext();
XP_ASSERT( context != NULL );
if (!_frame || !context)
{
return;
}
// Get the session history list
XP_List* list = SHIST_GetList(context);
// Get the pointer to the current history entry
History_entry * current_entry = context->hist.cur_doc_ptr;
XP_List * current_node = XP_ListFindObject(list, current_entry);
XP_ASSERT( list != NULL );
// Make sure the history list is valid
if (!list)
{
return;
}
list = list->prev;
if (forward)
{
addItems(current_node->next,True);
}
else
{
addItems(current_node->prev,False);
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Menu item callbacks
//
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::itemActivateCB(Widget,XtPointer clientData,XtPointer)
{
_HistoryCallbackStruct * data = (_HistoryCallbackStruct *) clientData;
XP_ASSERT( data != NULL );
XP_ASSERT( data->object != NULL );
data->object->itemActivate(data->entry);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::itemArmCB(Widget,XtPointer clientData,XtPointer)
{
_HistoryCallbackStruct * data = (_HistoryCallbackStruct *) clientData;
XP_ASSERT( data != NULL );
XP_ASSERT( data->object != NULL );
data->object->itemArm(data->entry);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::itemDisarmCB(Widget,XtPointer clientData,XtPointer)
{
_HistoryCallbackStruct * data = (_HistoryCallbackStruct *) clientData;
XP_ASSERT( data != NULL );
XP_ASSERT( data->object != NULL );
data->object->itemDisarm();
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::itemDestroyCB(Widget,XtPointer clientData,XtPointer)
{
_HistoryCallbackStruct * data = (_HistoryCallbackStruct *) clientData;
XP_ASSERT( data != NULL );
XP_FREE(data);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::itemActivate(History_entry * entry)
{
XP_ASSERT( _frame != NULL );
MWContext * context = _frame->getContext();
URL_Struct * url;
url = SHIST_CreateURLStructFromHistoryEntry(context,entry);
if (_frame->handlesCommand(xfeCmdOpenUrl,(void *) url))
{
_frame->doCommand(xfeCmdOpenUrl,(void *) url);
}
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::itemArm(History_entry * entry)
{
XP_ASSERT( _frame != NULL );
_frame->notifyInterested(XFE_View::statusNeedsUpdatingMidTruncated,
(void*) entry->address);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::itemDisarm()
{
XP_ASSERT( _frame != NULL );
_frame->notifyInterested(XFE_View::statusNeedsUpdatingMidTruncated,
(void*) "");
}
//////////////////////////////////////////////////////////////////////////
void
XFE_BackForwardMenu::addItem(int position,
History_entry * entry)
{
XP_ASSERT( entry != NULL );
// Make sure the title is valid
if (!entry)
{
return;
}
char * title = entry->title ? entry->title : XP_GetString(XFE_UNTITLED);
_HistoryCallbackStruct * data;
// Create a new bookmark data structure for the callbacks
data = XP_NEW_ZAP(_HistoryCallbackStruct);
data->object = this;
data->entry = entry;
// Create the new item
Widget item = XtVaCreateManagedWidget(xfeCmdOpenTargetUrl,
xmPushButtonGadgetClass,
_submenu,
NULL);
// Add callbacks to item
XtAddCallback(item,
XmNactivateCallback,
&XFE_BackForwardMenu::itemActivateCB,
(XtPointer) data);
XtAddCallback(item,
XmNarmCallback,
&XFE_BackForwardMenu::itemArmCB,
(XtPointer) data);
XtAddCallback(item,
XmNdisarmCallback,
&XFE_BackForwardMenu::itemDisarmCB,
(XtPointer) data);
// Format the title
char * buffer = PR_smprintf("%2d %s",position + 1,title);
XP_ASSERT( buffer != NULL );
// Truncate the title and install it on the item
if (buffer)
{
MWContext * context = _frame->getContext();
INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context);
XmFontList font_list;
INTL_MidTruncateString(INTL_GetCSIWinCSID(c),
buffer,
buffer,
MAX_MENU_ITEM_LENGTH);
XmString label = fe_ConvertToXmString((unsigned char *) buffer,
INTL_GetCSIWinCSID(c),
NULL,
XmFONT_IS_FONT,
&font_list);
if (label)
{
XtVaSetValues(item,XmNlabelString,label,NULL);
XmStringFree(label);
}
// Free the allocated memory
XP_FREE(buffer);
}
}
//////////////////////////////////////////////////////////////////////////