/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Business Objects nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* IntellicutPanel.java
* Creation date: (16/04/01 2:03:41 PM)
* By: Michael Cheng
*/
package org.openquark.gems.client;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import org.openquark.cal.services.GemEntity;
import org.openquark.gems.client.Gem.PartConnectable;
import org.openquark.gems.client.IntellicutListModelAdapter.IntellicutListEntry;
import org.openquark.gems.client.IntellicutListModelAdapter.PartConnectableAdapter;
import org.openquark.gems.client.IntellicutManager.IntellicutMode;
import org.openquark.gems.client.utilities.ExtendedUndoableEditSupport;
import org.openquark.util.Messages;
/**
* The GemCutter adapter for the IntellicutListPanel. It handles creating the panel, connecting the
* selected gem and placing it on the table top.
* @author Michael Cheng
*/
public class IntellicutPanelAdapter implements IntellicutPanelOwner {
/** The IntellicutPanel this adapter is for. */
private final IntellicutPanel intellicutPanel;
/**
* The part input intellicut is being performed on.
* This is null if intellicut is taking place for the table top.
*/
private final PartConnectable intellicutPart;
/** The GemCutter that is using this adapter. */
private final GemCutter gemCutter;
/** The table top location at which the new gem should appear. */
private final Point location;
/** The component that invoked Intellicut and should receive focus when intellicut completes. */
private final JComponent invoker;
/** The popup menu that appears when right-clicking on the IntelilcutList */
private IntellicutPopupMenu intellicutPopupMenu = null;
/**
* This class implements the popup menu for the IntellicutPanel that is displayed when the user right-clicks
* on an item in the IntellicutList. The menu allows you to connect the gem or view the gem properties.
* @author Ken Wong
*/
private class IntellicutPopupMenu extends JPopupMenu implements ActionListener {
private static final long serialVersionUID = 1136769591841746425L;
/** Menu Item that represents the connect Gem option */
private final JMenuItem connectGem;
/** Menu Item that represents the view properties option */
private final JMenuItem viewProperties;
/**
* Default constructor for IntellicutPopupMenu
*/
IntellicutPopupMenu() {
connectGem = new JMenuItem(GemCutter.getResourceString("IPM_Connect_Gem"));
connectGem.addActionListener(this);
viewProperties = new JMenuItem(GemCutter.getResourceString("IPM_View_Properties"));
viewProperties.addActionListener(this);
add(connectGem);
add(viewProperties);
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
if (e.getSource() == connectGem) {
connectSelectedGem();
} else if (e.getSource() == viewProperties) {
IntellicutListEntry item = (IntellicutListEntry) intellicutPanel.getIntellicutList().getSelectedValue();
if (item.getData() instanceof GemEntity) {
GemEntity gemEntity = (GemEntity) item.getData();
gemCutter.getNavigatorOwner().displayMetadata(gemEntity, true);
}
}
}
/**
* Enable and disable submenus depending on what intellicut item is selected.
*/
public void update() {
Object selectedItem = intellicutPanel.getIntellicutList().getSelected().getData();
viewProperties.setEnabled(selectedItem instanceof GemEntity);
if (intellicutPart == null) {
connectGem.setText(GemCutter.getResourceString("IPM_Add_Gem"));
} else {
connectGem.setText(GemCutter.getResourceString("IPM_Connect_Gem"));
}
}
}
/**
* IntellicutPanelAdapter constructor.
* @param intellicutPart the part that intellicut was invoked for (this can be null)
* @param gemCutter the GemCutter this adapter is used by
* @param location the table top location where the new gem should appear
*/
public IntellicutPanelAdapter(Gem.PartConnectable intellicutPart, GemCutter gemCutter, Point location, JComponent invoker) {
this.invoker = invoker;
this.gemCutter = gemCutter;
this.location = location;
this.intellicutPart = intellicutPart;
PartConnectableAdapter adapter = new PartConnectableAdapter(intellicutPart,
gemCutter.getPerspective(),
gemCutter.getTypeCheckInfo());
Color typeColor = intellicutPart != null ? gemCutter.getTypeColourManager().getTypeColour(intellicutPart.getType()) : null;
IntellicutMode mode = gemCutter.getIntellicutManager().getIntellicutMode();
this.intellicutPanel = new IntellicutPanel(this, adapter, typeColor, mode);
}
/**
* @return the IntellicutPanel managed by this adapter.
*/
public IntellicutPanel getIntellicutPanel() {
return intellicutPanel;
}
/**
* Drops the currently selected item in the IntellicutList onto onto the table top and connects
* it to the intellicut part, if there is an intellicut part. If there is no selected item it will
* stop the intellicut panel.
*/
public void connectSelectedGem() {
if (intellicutPanel.getIntellicutListModel().getSize() == 0 ||
intellicutPanel.getIntellicutList().getSelectedValue() == null) {
stopIntellicutPanel();
return;
}
// Increment the update level for the edit undo. This will aggregate any gem addition, connection, and burnings..
ExtendedUndoableEditSupport tableTopUndoableEditSupport = gemCutter.getTableTop().getUndoableEditSupport();
tableTopUndoableEditSupport.beginUpdate();
// Get a new displayed gem.
Object selectedItem = ((IntellicutListEntry) intellicutPanel.getIntellicutList().getSelectedValue()).getData();
DisplayedGem newDisplayedGem = getDisplayedGem(selectedItem, location);
// Connect the gem.
gemCutter.getIntellicutManager().attemptIntellicutAutoConnect(newDisplayedGem);
gemCutter.getIntellicutManager().stopIntellicut();
tableTopUndoableEditSupport.endUpdate();
// Move the new gem into view and repaint the table top.
gemCutter.getTableTopPanel().scrollRectToVisible(newDisplayedGem.getBounds());
gemCutter.getTableTopPanel().repaint();
invoker.requestFocusInWindow();
}
/**
* Get a displayed gem for the selected item in the intellicut list.
* This will either create a new displayed gem or move an existing one to the correct location.
* @return DisplayedGem
*/
private DisplayedGem getDisplayedGem(Object selectedItem, Point location) {
// Check if we have to reposition the new gem.
boolean needToReposition = false;
if (location == null) {
location = new Point(1, 1);
needToReposition = true;
}
// Check what kind of entry is selected and if we have to create a new gem or
// if we can reuse an existing one that is already on the table top.
DisplayedGem newGem = null;
boolean needToAddGem = true;
TableTop tableTop = gemCutter.getTableTop();
if (selectedItem instanceof GemEntity) {
newGem = tableTop.createDisplayedFunctionalAgentGem(location, (GemEntity)selectedItem);
} else if (selectedItem instanceof CollectorGem) {
if (intellicutPart == null || intellicutPart instanceof Gem.PartInput) {
newGem = tableTop.createDisplayedReflectorGem(location, (CollectorGem)selectedItem);
} else {
newGem = gemCutter.getTableTop().getDisplayedGem((Gem) selectedItem);
needToAddGem = false;
}
} else {
throw new IllegalArgumentException("item type not supported");
}
// Add the gem to the table top if needed.
if (needToAddGem) {
if (needToReposition) {
location = gemCutter.getTableTop().findAvailableDisplayedGemLocation(newGem);
}
gemCutter.getTableTop().getUndoableEditSupport().setEditName(GemCutterMessages.getString("UndoText_Add", newGem.getDisplayText()));
gemCutter.getTableTop().doAddGemUserAction(newGem, location);
}
gemCutter.getTableTop().selectDisplayedGem(newGem, true);
gemCutter.getTableTop().setFocusedDisplayedGem(newGem);
return newGem;
}
/**
* @return the intellicut popup menu (creates a new one if none exists).
*/
public JPopupMenu getIntellicutPopupMenu() {
if (intellicutPopupMenu == null) {
intellicutPopupMenu = new IntellicutPopupMenu();
}
intellicutPopupMenu.update();
return intellicutPopupMenu;
}
/**
* @see org.openquark.gems.client.IntellicutPanelOwner#stopIntellicutPanel()
*/
public void stopIntellicutPanel() {
gemCutter.getIntellicutManager().stopIntellicut();
invoker.requestFocusInWindow();
}
/**
* @see org.openquark.gems.client.IntellicutPanelOwner#getMessages()
*/
public Messages getMessages() {
return GemCutterMessages.instance;
}
}