/*
* EnhancedMenu.java - jEdit menu
* :tabSize=4:indentSize=4:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 2001, 2003 Slava Pestov
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.gjt.sp.jedit.menu;
//{{{ Imports
import javax.swing.event.*;
import javax.swing.*;
import java.util.StringTokenizer;
import org.gjt.sp.jedit.EditBus.EBHandler;
import org.gjt.sp.jedit.msg.*;
import org.gjt.sp.jedit.*;
//}}}
public class EnhancedMenu extends JMenu implements MenuListener
{
//{{{ EnhancedMenu constructor
public EnhancedMenu(String name)
{
this(name,jEdit.getProperty(name.concat(".label")),
jEdit.getActionContext());
} //}}}
//{{{ EnhancedMenu constructor
public EnhancedMenu(String name, String label)
{
this(name,label,jEdit.getActionContext());
} //}}}
//{{{ EnhancedMenu constructor
public EnhancedMenu(String name, String label, ActionContext context)
{
this.context = context;
if(label == null)
label = name;
char mnemonic;
int index = label.indexOf('$');
if(index != -1 && label.length() - index > 1)
{
mnemonic = Character.toLowerCase(label.charAt(index + 1));
label = label.substring(0,index).concat(label.substring(++index));
}
else
mnemonic = '\0';
setText(label);
if(!OperatingSystem.isMacOS())
setMnemonic(mnemonic);
String menuItems = jEdit.getProperty(name);
if(menuItems != null)
{
StringTokenizer st = new StringTokenizer(menuItems);
while(st.hasMoreTokens())
{
String menuItemName = st.nextToken();
if(menuItemName.equals("-"))
addSeparator();
else
add(GUIUtilities.loadMenuItem(context,menuItemName,true));
}
}
initialComponentCount = getMenuComponentCount();
providerCode = jEdit.getProperty(name + ".code");
ebStub = new EditBusStub(name);
ebStub.menuOutOfDate = true;
addMenuListener(this);
if(providerCode != null)
EditBus.addToBus(ebStub);
} //}}}
//{{{ menuSelected() method
public void menuSelected(MenuEvent evt)
{
init();
} //}}}
public void menuDeselected(MenuEvent e) {}
public void menuCanceled(MenuEvent e) {}
//{{{ init() method
public void init()
{
if(providerCode == null)
return;
if(provider == null)
{
Object obj = BeanShell.eval(null,
BeanShell.getNameSpace(),
providerCode);
provider = (DynamicMenuProvider)obj;
}
if(provider == null)
{
// error
providerCode = null;
return;
}
if(ebStub.menuOutOfDate || provider.updateEveryTime())
{
ebStub.menuOutOfDate = false;
while(getMenuComponentCount() != initialComponentCount)
remove(getMenuComponentCount() - 1);
if(provider != null)
provider.update(this);
}
} //}}}
//{{{ Protected members
protected int initialComponentCount;
protected ActionContext context;
protected String providerCode;
protected DynamicMenuProvider provider;
protected EditBusStub ebStub;
//{{{ finalize() method
protected void finalize() throws Exception
{
if(ebStub != null)
EditBus.removeFromBus(ebStub);
} //}}}
//}}}
//{{{ EditBusStub class
/* EnhancedMenu has a reference to EditBusStub, but not the other
* way around. So when the EnhancedMenu is being garbage collected
* its finalize() method removes the EditBusStub from the edit bus. */
public static class EditBusStub
{
String name;
boolean menuOutOfDate;
EditBusStub(String name)
{
this.name = name;
menuOutOfDate = true;
}
@EBHandler
public void handleDynamicMenuChanged(DynamicMenuChanged msg)
{
if (name.equals(msg.getMenuName()))
menuOutOfDate = true;
}
@EBHandler
public void handlePropertiesChanged(PropertiesChanged msg)
{
// while this might be questionable, some
// menus depend on properties
menuOutOfDate = true;
}
} //}}}
}