/* Copyright (C) 2006 Christian Schneider
*
* This file is part of Nomad.
*
* Nomad 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
* (at your option) any later version.
*
* Nomad 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 Nomad; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Created on May 13, 2006
*/
package net.sf.nmedit.nomad.core.swing.document;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.sf.nmedit.nomad.core.Nomad;
import net.sf.nmedit.nomad.core.swing.tabs.FFTabBarUI;
import net.sf.nmedit.nomad.core.swing.tabs.JTabbedPane2;
public class DefaultDocumentManager extends JTabbedPane2 implements DocumentManager, PropertyChangeListener
{
/**
*
*/
private static final long serialVersionUID = 8346940412067775776L;
private List<Document> documentList = new ArrayList<Document>();
final JTabbedPane2 container = this;
public DefaultDocumentManager()
{
container.setOpaque(true);
container.addTabBarChangeListener(new TabChangeListener());
container.setBorder(null);
container.getTabBar().addPropertyChangeListener(this);
}
public int indexOf(Document d)
{
return container.indexOfComponent(d.getComponent());
}
protected void fireDocumentAdded(Document doc)
{
if (getDocumentCount()==1)
setSelection(doc);
DocumentEvent documentEvent = null;
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==DocumentListener.class) {
// Lazily create the event:
if (documentEvent == null)
documentEvent = new DocumentEvent(DocumentEvent.DOCUMENT_ADDED, doc);
((DocumentListener)listeners[i+1]).documentAdded(documentEvent);
}
}
}
protected void fireDocumentRemoved(Document doc)
{
if (getDocumentCount()==0)
setSelection(null);
DocumentEvent documentEvent = null;
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==DocumentListener.class) {
// Lazily create the event:
if (documentEvent == null)
documentEvent = new DocumentEvent(DocumentEvent.DOCUMENT_REMOVED, doc);
((DocumentListener)listeners[i+1]).documentRemoved(documentEvent);
}
}
}
protected void fireDocumentSelected(Document doc)
{
DocumentEvent documentEvent = null;
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==DocumentListener.class) {
// Lazily create the event:
if (documentEvent == null)
documentEvent = new DocumentEvent(DocumentEvent.DOCUMENT_SELECTED, doc);
((DocumentListener)listeners[i+1]).documentSelected(documentEvent);
}
}
}
public void addListener(DocumentListener l)
{
listenerList.add(DocumentListener.class, l);
}
public void removeListener(DocumentListener l)
{
listenerList.remove(DocumentListener.class, l);
}
public Container getContainer()
{
return this;
}
public boolean add( Document d )
{
if (documentList.add(d))
{
addToContainer(d);
return true;
}
return false;
}
public boolean remove( Document d )
{
if (documentList.remove(d))
{
removeFromContainer(d);
return true;
}
return false;
}
private void addToContainer(Document d)
{
Icon icon = d.getIcon();
if (icon == null)
icon = FFTabBarUI.defaultIcon;
container.addTab(d.getTitleExtended(), icon, d.getComponent());
fireDocumentAdded(d);
}
private void removeFromContainer(Document d)
{
container.removeTabAt(container.indexOfComponent(d.getComponent()));
fireDocumentRemoved(d);
d.dispose();
}
;
public int getDocumentCount()
{
return documentList.size();
}
public Document[] getDocuments()
{
return documentList.toArray(new Document[documentList.size()]);
}
public boolean contains( Document d )
{
return documentList.contains(d);
}
public Document getSelection()
{
Component sel = container.getSelectedComponent();
for (Document d : documentList)
if (d.getComponent()==sel)
return d;
return null ;
}
public void setSelection( Document d )
{
container.setSelectedComponent(d==null?null:d.getComponent());
}
private class TabChangeListener implements ChangeListener
{
public void stateChanged( ChangeEvent e )
{
fireDocumentSelected(getSelection());
}
}
public void updateTitle( Document document )
{
for (int i=getTabCount()-1;i>=0;i--)
{
if (document.getComponent() == getComponentAt(i))
{
setTitleAt( i, document.getTitleExtended() );
return;
}
}
}
public void propertyChange(PropertyChangeEvent evt)
{
if ("ask-remove".equals(evt.getPropertyName()))
{
int index = (Integer) evt.getNewValue();
closeDocument(documentList.get(index));
// remove(documentList.get(index));
return;
}
if ("show-context-menu".equals(evt.getPropertyName()))
{
MouseEvent e = (MouseEvent) evt.getOldValue();
int tabIndex = (Integer) evt.getNewValue();
JPopupMenu popup = new JPopupMenu();
popup.add(new ContextMenuAction(container, tabIndex, ContextMenuAction.CLOSE));
popup.show(container.getTabBar(), e.getX(), e.getY());
}
}
public boolean closeDocument(Document d) {
if (d != null) {
if (d.isModified()) {
Nomad n = Nomad.sharedInstance();
int result = JOptionPane.showConfirmDialog(n.getWindow().getRootPane(), "Are you sure you want to close " + d.getTitle() + " ?",
"", JOptionPane.OK_CANCEL_OPTION);
if (result != JOptionPane.OK_OPTION)
return false;
}
remove(d);
d.dispose();
}
return true;
}
private static class ContextMenuAction extends AbstractAction
{
/**
*
*/
private static final long serialVersionUID = -5802320514699863654L;
public static final String CLOSE = "Close Tab";
private JTabbedPane2 tabs;
private int tabIndex;
public ContextMenuAction(JTabbedPane2 tabs, int tabIndex, String command)
{
putValue(NAME, command);
putValue(ACTION_COMMAND_KEY, command);
this.tabs = tabs;
this.tabIndex = tabIndex;
}
public void actionPerformed(ActionEvent e)
{
if (!isEnabled())
return;
if (e.getActionCommand() == CLOSE)
{
tabs.getTabBar().askRemove(tabIndex);
setEnabled(false);
}
}
}
}