/* -*- 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: A menu class for listing all the xfe windows. // // This class can be used with both XmCascadeButton and // // XfeCascade widgets. // // // // Author: Ramiro Estrugo // // // ////////////////////////////////////////////////////////////////////////// #include "FrameListMenu.h" #include "MozillaApp.h" #include "felocale.h" #include "intl_csi.h" #include #include #include #define MAX_ITEM_WIDTH 40 ////////////////////////////////////////////////////////////////////////// XFE_FrameListMenu::XFE_FrameListMenu(Widget w, XFE_Frame * frame) { m_cascade = w; m_parentFrame = frame; XP_ASSERT( m_parentFrame != NULL ); XtAddCallback(m_cascade, XmNdestroyCallback, &XFE_FrameListMenu::destroy_cb, (XtPointer) this); XtAddCallback(m_cascade, XmNcascadingCallback, &XFE_FrameListMenu::cascading_cb, (XtPointer) this); XtVaGetValues(m_cascade,XmNsubMenuId,&m_submenu,NULL); XtVaGetValues(m_submenu,XmNnumChildren,&m_firstslot,NULL); XP_ASSERT(m_submenu); } ////////////////////////////////////////////////////////////////////////// XFE_FrameListMenu::~XFE_FrameListMenu() { } ////////////////////////////////////////////////////////////////////////// void XFE_FrameListMenu::generate(Widget cascade, XtPointer, XFE_Frame *frame) { XFE_FrameListMenu *obj; obj = new XFE_FrameListMenu(cascade, frame); } ////////////////////////////////////////////////////////////////////////// void XFE_FrameListMenu::cascading() { XP_List * frame_list = getShownFrames(); XFE_Frame * frame; int i; int frame_count = XP_ListCount(frame_list); Cardinal num_children; WidgetList children; int total_slots_needed; int slots_to_add; int count; XfeChildrenGet(m_submenu,&children,&num_children); XP_ASSERT( num_children > 1 ); // Total number of slots needed total_slots_needed = m_firstslot + 1 + frame_count; // Number of slots to add slots_to_add = total_slots_needed - num_children; // Add more slots if needed if (slots_to_add > 0) { for (i = 0; i < slots_to_add; i++) { Widget item = XtVaCreateWidget(xfeCmdFrameListRaiseItem, //xmToggleButtonGadgetClass, xmPushButtonGadgetClass, m_submenu, NULL); XtAddCallback(item, XmNactivateCallback, //XmNvalueChangedCallback, &XFE_FrameListMenu::item_activate_cb, (XtPointer) this); } // Update num_slots, since we added stuff XfeChildrenGet(m_submenu,&children,&num_children); } count = 1; // Configure the items for (i = (int) m_firstslot + 1; i < (int) num_children; i++) { // Get the next frame frame = (XFE_Frame*) XP_ListNextObject(frame_list); // If the frame is valid, add its title to the slot buttons if (frame) { MWContext * context = m_parentFrame->getContext(); INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context); XmFontList font_list; char name[1024]; XP_SPRINTF(name,"%d. %s",count++,frame->getTitle()); INTL_MidTruncateString(INTL_GetCSIWinCSID(c), name, name, MAX_ITEM_WIDTH); XmString label = fe_ConvertToXmString((unsigned char *) name, INTL_GetCSIWinCSID(c), NULL, XmFONT_IS_FONT, &font_list); if (label) { XtVaSetValues(children[i],XmNlabelString,label,NULL); XmStringFree(label); } XtManageChild(children[i]); } // If the frame is not valid, the unmanage the slot button else { XtUnmanageChild(children[i]); } } // Update the display so that the gadget buttons get drawn XmUpdateDisplay(m_submenu); if (frame_list) { XP_ListDestroy(frame_list); } } ////////////////////////////////////////////////////////////////////////// void XFE_FrameListMenu::item_activate(Widget item) { XP_ASSERT( XfeIsAlive(m_submenu) ); int i = XfeChildGetIndex(item) - m_firstslot; XP_ASSERT( i > 0 ); if (i <= 0) { return; } XP_List * frame_list = getShownFrames(); XFE_Frame * frame = (XFE_Frame *) XP_ListGetObjectNum(frame_list,i); XP_ASSERT( frame != NULL ); if (frame) { frame->show(); } XmUpdateDisplay(frame->getBaseWidget()); if (frame_list) { XP_ListDestroy(frame_list); } } ////////////////////////////////////////////////////////////////////////// void XFE_FrameListMenu::destroy_cb(Widget, XtPointer clientData, XtPointer) { XFE_FrameListMenu *obj = (XFE_FrameListMenu*)clientData; delete obj; } ////////////////////////////////////////////////////////////////////////// void XFE_FrameListMenu::cascading_cb(Widget, XtPointer clientData, XtPointer) { XFE_FrameListMenu *obj = (XFE_FrameListMenu*)clientData; obj->cascading(); } ////////////////////////////////////////////////////////////////////////// void XFE_FrameListMenu::item_activate_cb(Widget item, XtPointer clientData, XtPointer) { XFE_FrameListMenu *obj = (XFE_FrameListMenu*)clientData; obj->item_activate(item); } ////////////////////////////////////////////////////////////////////////// XP_List * XFE_FrameListMenu::getShownFrames() { XP_List * frame_list = XFE_MozillaApp::theApp()->getAllFrameList(); Cardinal frame_count = XP_ListCount(frame_list); XP_List * shown_frame_list = NULL; Cardinal i; // Find the shown frames and add them to a list for (i = 0; i < frame_count; i++) { // Get the next frame XFE_Frame * frame = (XFE_Frame*) XP_ListNextObject(frame_list); // Add it to list if valid and shown if (frame && XfeIsAlive(frame->getBaseWidget()) && frame->isShown()) { // Create a new list as soon as we find the first shown item if (!shown_frame_list) { shown_frame_list = XP_ListNew(); } XP_ListAddObject(shown_frame_list,frame); } } return shown_frame_list; } //////////////////////////////////////////////////////////////////////////