/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo 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 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo 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 OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.components.widget;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import org.openflexo.components.widget.AbstractSelectorPanel.AbstractSelectorPanelOwner;
import org.openflexo.fib.controller.FIBController;
import org.openflexo.fib.model.FIBCustom;
import org.openflexo.fib.model.FIBCustom.FIBCustomComponent;
import org.openflexo.foundation.FlexoEditor;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.rm.FlexoProject;
import org.openflexo.swing.TextFieldCustomPopup;
/**
* Widget allowing to select a object while browsing in a project browser
*
* @author sguerin
*
*/
public abstract class AbstractBrowserSelector<T extends FlexoModelObject> extends TextFieldCustomPopup<T> implements
AbstractSelectorPanelOwner<T>, FIBCustomComponent<T, TextFieldCustomPopup<T>> {
static final Logger logger = Logger.getLogger(AbstractBrowserSelector.class.getPackage().getName());
FlexoProject _project;
FlexoModelObject _rootObject = null;
private T _revertValue;
Class<T> _selectableClass;
protected KeyAdapter completionListKeyAdapter;
protected AbstractSelectorPanel<T> _selectorPanel;
private FlexoEditor _editor;
private Integer defaultWidth = null;
private Integer defaultHeight = null;
public AbstractBrowserSelector(FlexoProject project, T editedObject, Class<T> selectableClass) {
this(project, editedObject, selectableClass, -1);
}
public AbstractBrowserSelector(FlexoProject project, T editedObject, Class<T> selectableClass, int cols) {
super(editedObject, cols);
_project = project;
_revertValue = editedObject;
_selectableClass = selectableClass;
setFocusable(true);
getTextField().setFocusable(true);
getTextField().setEditable(true);
getTextField().addMouseWheelListener(new BrowserSelectorMouseWheelListener());
completionListKeyAdapter = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
// logger.info("Hop "+e);
if (_selectorPanel != null) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
_selectorPanel.processEnterPressed();
e.consume();
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
_selectorPanel.processTabPressed();
e.consume();
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
_selectorPanel.processUpPressed();
e.consume();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
_selectorPanel.processDownPressed();
e.consume();
}
} else if (!e.isActionKey() && e.getKeyCode() != KeyEvent.VK_SHIFT && e.getKeyCode() != KeyEvent.VK_ENTER
&& e.getKeyCode() != KeyEvent.VK_CONTROL && e.getKeyCode() != KeyEvent.VK_META && e.getKeyCode() != KeyEvent.VK_TAB) {
// if command-key is pressed, do not open popup
if (e.isAltDown() || e.isAltGraphDown() || e.isControlDown() || e.isMetaDown()) {
return;
}
boolean requestFocus = getTextField().hasFocus();
final int selectionStart = getTextField().getSelectionStart() + 1;
final int selectionEnd = getTextField().getSelectionEnd() + 1;
getCustomPanel();
_selectorPanel._completionListModel.textWasChanged();
if (requestFocus) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getTextField().requestFocusInWindow();
getTextField().select(selectionStart, selectionEnd);
}
});
}
/*getCustomPanel();
_selectorPanel._completionListModel.textWasChanged();
getTextField().select(selectionStart, selectionEnd);*/
}
}
};
getTextField().addKeyListener(completionListKeyAdapter);
_downButton.addMouseWheelListener(new BrowserSelectorMouseWheelListener());
}
@Override
public void delete() {
super.delete();
setProject(null);
_rootObject = null;
_editor = null;
}
@Override
public Class<T> getRepresentedType() {
return _selectableClass;
}
@Override
public TextFieldCustomPopup<T> getJComponent() {
return this;
}
public void setText(String text) {
getTextField().setText(text);
getCustomPanel();
_selectorPanel._completionListModel.textWasChanged();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
_popup.requestFocusInWindow();
getTextField().requestFocusInWindow();
}
});
}
@Override
public void setRevertValue(T oldValue) {
_revertValue = oldValue;
}
@Override
public T getRevertValue() {
return _revertValue;
}
@Override
public FlexoProject getProject() {
return _project;
}
public void setProject(FlexoProject project) {
_project = project;
}
@Override
protected ResizablePanel createCustomPanel(T editedObject) {
_selectorPanel = makeCustomPanel(editedObject);
_selectorPanel.setRootObject(_rootObject);
_selectorPanel.init();
return _selectorPanel;
}
@Override
public FlexoModelObject getRootObject() {
return _rootObject;
}
public void setRootObject(FlexoModelObject aRootObject) {
_rootObject = aRootObject;
if (_selectorPanel != null) {
_selectorPanel.setRootObject(_rootObject);
}
}
protected abstract AbstractSelectorPanel<T> makeCustomPanel(T editedObject);
@Override
public void updateCustomPanel(T editedObject) {
if (_selectorPanel != null) {
_selectorPanel.update();
_selectorPanel.hideCompletionList();
}
}
@Override
public abstract String renderedString(T editedObject);
public FlexoModelObject getSelectedObject() {
if (_selectorPanel != null) {
return _selectorPanel.getSelectedObject();
}
return null;
}
@Override
public boolean isSelectable(FlexoModelObject object) {
return _selectableClass.isAssignableFrom(object.getClass());
}
private class BrowserSelectorMouseWheelListener implements MouseWheelListener {
/**
*
*/
protected BrowserSelectorMouseWheelListener() {
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (_selectorPanel == null) {
return;
}
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
if (_selectorPanel._browserView.getTreeScrollPane().getVerticalScrollBar() != null) {
_selectorPanel._browserView
.getTreeScrollPane()
.getVerticalScrollBar()
.setValue(
_selectorPanel._browserView.getTreeScrollPane().getVerticalScrollBar().getValue()
+ e.getUnitsToScroll());
}
} else {
if (_selectorPanel._browserView.getTreeScrollPane().getVerticalScrollBar() != null) {
_selectorPanel._browserView
.getTreeScrollPane()
.getVerticalScrollBar()
.setValue(
_selectorPanel._browserView.getTreeScrollPane().getVerticalScrollBar().getValue()
+ e.getWheelRotation()
* _selectorPanel._browserView.getTreeScrollPane().getVerticalScrollBar().getBlockIncrement());
}
}
}
}
@Override
public void apply() {
_revertValue = getEditedObject();
closePopup();
super.apply();
}
@Override
public void cancel() {
setEditedObject(_revertValue);
closePopup();
super.cancel();
}
@Override
public void openPopup() {
super.openPopup();
getTextField().requestFocusInWindow();
}
@Override
public void closePopup() {
super.closePopup();
deletePopup();
}
@Override
protected void deletePopup() {
if (_selectorPanel != null) {
_selectorPanel.delete();
}
_selectorPanel = null;
super.deletePopup();
}
@Override
protected void pointerLeavesPopup() {
cancel();
}
public AbstractSelectorPanel<T> getSelectorPanel() {
return _selectorPanel;
}
@Override
public FlexoEditor getEditor() {
return _editor;
}
/**
* Sets an editor if you want FlexoAction available on browser
*
* @param editor
*/
public void setEditor(FlexoEditor editor) {
_editor = editor;
}
@Override
public KeyAdapter getCompletionListKeyAdapter() {
return completionListKeyAdapter;
}
@Override
public Integer getDefaultWidth() {
return defaultWidth;
}
@Override
public Integer getDefaultHeight() {
return defaultHeight;
}
public void setDefaultWidth(Integer defaultWidth) {
this.defaultWidth = defaultWidth;
}
public void setDefaultHeight(Integer defaultHeight) {
this.defaultHeight = defaultHeight;
}
@Override
public void init(FIBCustom component, FIBController controller) {
// TODO Auto-generated method stub
}
}