/*******************************************************************************
* Copyright (c) 2009, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.aptana.ruby.internal.debug.ui.breakpoints;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.debug.ui.IDetailPane;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartConstants;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.part.EditorActionBarContributor;
import com.aptana.core.logging.IdeLog;
import com.aptana.ruby.debug.ui.RubyDebugUIPlugin;
/**
* Common detail pane function.
*
* @since 1.0
*/
@SuppressWarnings("restriction")
public abstract class AbstractDetailPane implements IDetailPane
{
private String fName;
private String fDescription;
private String fId;
private AbstractRubyBreakpointEditor fEditor;
private Set<Integer> fAutoSaveProperties = new HashSet<Integer>();
private IWorkbenchPartSite fSite;
// property listeners
private ListenerList fListeners = new ListenerList();
private Composite fEditorParent;
/**
* Constructs a detail pane.
*
* @param name
* detail pane name
* @param description
* detail pane description
* @param id
* detail pane ID
*/
public AbstractDetailPane(String name, String description, String id)
{
fName = name;
fDescription = description;
fId = id;
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.IDetailPane3#addPropertyListener(org.eclipse.ui.IPropertyListener)
*/
public void addPropertyListener(IPropertyListener listener)
{
fListeners.add(listener);
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.IDetailPane3#removePropertyListener(org.eclipse.ui.IPropertyListener)
*/
public void removePropertyListener(IPropertyListener listener)
{
fListeners.remove(listener);
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.IDetailPane2#getSelectionProvider()
*/
public ISelectionProvider getSelectionProvider()
{
return null;
}
/**
* Fires a property change to all listeners.
*
* @param property
* the property
*/
protected void firePropertyChange(int property)
{
Object[] listeners = fListeners.getListeners();
for (int i = 0; i < listeners.length; i++)
{
((IPropertyListener) listeners[i]).propertyChanged(this, property);
}
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.IDetailPane#init(org.eclipse.ui.IWorkbenchPartSite)
*/
public void init(IWorkbenchPartSite partSite)
{
fSite = partSite;
}
public String getID()
{
return fId;
}
public String getName()
{
return fName;
}
public String getDescription()
{
return fDescription;
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.IDetailPane#dispose()
*/
public void dispose()
{
fEditor = null;
fSite = null;
fListeners.clear();
fAutoSaveProperties.clear();
fEditorParent.dispose();
}
/**
* Adds the given auto save properties to this detail pain. Whenever one of these properties changes, the detail
* pane editor is immediately saved.
*
* @param autosave
*/
protected void addAutosaveProperties(int[] autosave)
{
for (int i = 0; i < autosave.length; i++)
{
fAutoSaveProperties.add(new Integer(autosave[i]));
}
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.IDetailPane#createControl(org.eclipse.swt.widgets.Composite)
*/
public Control createControl(Composite parent)
{
fEditorParent = SWTFactory.createComposite(parent, 1, 1, GridData.FILL_BOTH);
fEditor = createEditor(fEditorParent);
fEditor.setMnemonics(false);
fEditor.addPropertyListener(new IPropertyListener()
{
public void propertyChanged(Object source, int propId)
{
if (fAutoSaveProperties.contains(new Integer(propId)))
{
try
{
fEditor.doSave();
return;
}
catch (CoreException e)
{
}
}
firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY);
}
});
return fEditor.createControl(fEditorParent);
}
/**
* Creates the detail pane specific editor.
*
* @param parent
* parent composite
* @return editor
*/
protected abstract AbstractRubyBreakpointEditor createEditor(Composite parent);
/*
* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#doSaveAs()
*/
public void doSaveAs()
{
// do nothing
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
*/
public boolean isSaveAsAllowed()
{
return false;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded()
*/
public boolean isSaveOnCloseNeeded()
{
return isDirty() && fEditor.getStatus().isOK();
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.IDetailPane#setFocus()
*/
public boolean setFocus()
{
return false;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
*/
public void doSave(IProgressMonitor monitor)
{
IStatusLineManager statusLine = getStatusLine();
if (statusLine != null)
{
statusLine.setErrorMessage(null);
}
try
{
fEditor.doSave();
}
catch (CoreException e)
{
if (statusLine != null)
{
statusLine.setErrorMessage(e.getMessage());
Display.getCurrent().beep();
}
else
{
IdeLog.logError(RubyDebugUIPlugin.getDefault(), e);
}
}
}
private IStatusLineManager getStatusLine()
{
// we want to show messages globally hence we
// have to go through the active part
if (fSite instanceof IViewSite)
{
IViewSite site = (IViewSite) fSite;
IWorkbenchPage page = site.getPage();
IWorkbenchPart activePart = page.getActivePart();
if (activePart instanceof IViewPart)
{
IViewPart activeViewPart = (IViewPart) activePart;
IViewSite activeViewSite = activeViewPart.getViewSite();
return activeViewSite.getActionBars().getStatusLineManager();
}
if (activePart instanceof IEditorPart)
{
IEditorPart activeEditorPart = (IEditorPart) activePart;
IEditorActionBarContributor contributor = activeEditorPart.getEditorSite().getActionBarContributor();
if (contributor instanceof EditorActionBarContributor)
return ((EditorActionBarContributor) contributor).getActionBars().getStatusLineManager();
}
// no active part
return site.getActionBars().getStatusLineManager();
}
return null;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.ISaveablePart#isDirty()
*/
public boolean isDirty()
{
return fEditor.isDirty();
}
/**
* Returns the editor associated with this detail pane.
*
* @return editor
*/
protected AbstractRubyBreakpointEditor getEditor()
{
return fEditor;
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.IDetailPane#display(org.eclipse.jface.viewers.IStructuredSelection)
*/
public void display(IStructuredSelection selection)
{
// clear status line
IStatusLineManager statusLine = getStatusLine();
if (statusLine != null)
{
statusLine.setErrorMessage(null);
}
AbstractRubyBreakpointEditor editor = getEditor();
Object input = null;
if (selection != null && selection.size() == 1)
{
input = selection.getFirstElement();
// update even if the same in case attributes have changed
}
try
{
editor.setInput(input);
}
catch (CoreException e)
{
IdeLog.logError(RubyDebugUIPlugin.getDefault(), e);
}
}
}