/*
* (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.ie.view.widget;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import org.openflexo.foundation.DataModification;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.FlexoObservable;
import org.openflexo.foundation.ie.HTMLListDescriptor;
import org.openflexo.foundation.ie.dm.ExcellButtonStateChange;
import org.openflexo.foundation.ie.dm.InnerBlocInserted;
import org.openflexo.foundation.ie.dm.InnerBlocRemoved;
import org.openflexo.foundation.ie.dm.RefreshButtonStateChange;
import org.openflexo.foundation.ie.dm.StyleSheetFolderChanged;
import org.openflexo.foundation.ie.dm.TopComponentRemoved;
import org.openflexo.foundation.ie.operator.RepetitionOperator;
import org.openflexo.foundation.ie.widget.ContentSizeChanged;
import org.openflexo.foundation.ie.widget.IEBlocWidget;
import org.openflexo.foundation.ie.widget.IEWidget;
import org.openflexo.icon.IconLibrary;
import org.openflexo.ie.util.TriggerRepaintDocumentListener;
import org.openflexo.ie.view.DropZoneTopComponent;
import org.openflexo.ie.view.IEContainer;
import org.openflexo.ie.view.IEWOComponentView;
import org.openflexo.ie.view.controller.IEController;
import org.openflexo.ie.view.listener.DoubleClickResponder;
import org.openflexo.localization.FlexoLocalization;
/**
* @author bmangez
*
* To change the template for this generated type comment go to Window - Preferences - Java - Code Generation - Code and Comments
*/
public class IEBlocWidgetView extends IEWidgetView<IEBlocWidget> implements DoubleClickResponder, IEContainer, LabeledWidget {
private static final Logger logger = Logger.getLogger(IEBlocWidgetView.class.getPackage().getName());
// ==========================================================================
// ============================= Variables
// ==================================
// ==========================================================================
private TopTitle _topTitle;
private ButtonPanel _buttonPanel;
private DropTableZone _dropTableZone;
public static final Font BLOC_TITLE_FONT = new Font("SansSerif", Font.BOLD, 10);
// ==========================================================================
// ============================= Constructor
// ================================
// ==========================================================================
public IEBlocWidgetView(IEController ieController, IEBlocWidget model, boolean addDnDSupport, IEWOComponentView componentView) {
super(ieController, model, addDnDSupport, componentView);
setLayout(new BorderLayout());
setDefaultBorder();
new ObserverRegistation(this, model.getWOComponent());
new ObserverRegistation(this, model.getProject());
setBackground(Color.WHITE);
_topTitle = new TopTitle(model);
_buttonPanel = new ButtonPanel(getIEController(), model, _componentView);
_dropTableZone = new DropTableZone(getIEController(), this, _componentView);
if (model.getContent() instanceof FlexoModelObject) {
new ObserverRegistation(this, (FlexoModelObject) model.getContent());
}
add(_topTitle, BorderLayout.NORTH);
add(_buttonPanel, BorderLayout.SOUTH);
add(_dropTableZone, BorderLayout.CENTER);
}
@Override
public void setDefaultBorder() {
setBorder(BorderFactory.createLineBorder(getMainColor()));
}
@Override
public void delete() {
if (getModel().getContent() != null && getModel().getContent() instanceof FlexoModelObject) {
((FlexoModelObject) getModel().getContent()).deleteObserver(this);
}
if (_dropTableZone != null) {
_dropTableZone.delete();
}
_dropTableZone = null;
if (_buttonPanel != null) {
_buttonPanel.delete();
}
_buttonPanel = null;
super.delete();
}
@Override
public void performDoubleClick(JComponent clickedContainer, Point clickedPoint, boolean isShiftDown) {
if (_topTitle.contains(SwingUtilities.convertPoint(clickedContainer, clickedPoint, this))) {
editLabel();
}
}
// ==========================================================================
// ============================= Observer
// ===================================
// ==========================================================================
private void updateInnerBlocInsertion(IEWidget widget) {
IEWidgetView<?> view = _componentView.getViewForWidget(widget, true);
_dropTableZone.add(view, BorderLayout.CENTER);
_dropTableZone.setTableView(view);
revalidate();
repaint();
new ObserverRegistation(this, widget);
handleContentResize();
}
private void updateInnerBlocRemoved(IEWidget widget) {
stopObserving(widget);
if (widget.getParent() != null && widget.getParent() == getModel()) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("updateHTMLTableRemoval");
}
if (_dropTableZone.getTableView() != null) {
_dropTableZone.getTableView().getModel().deleteObserver(_dropTableZone.getTableView());
}
_dropTableZone.removeAll();// (_dropTableZone.getTableView());
_dropTableZone.removeTableView();
revalidate();
repaint();
}
}
/*
* (non-Javadoc)
*
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/
@Override
public void update(FlexoObservable arg0, DataModification modif) {
if (modif instanceof TopComponentRemoved && arg0 == getModel()) {
delete();
} else if (modif instanceof RefreshButtonStateChange && arg0 == getModel()) {
if (((Boolean) modif.newValue()).booleanValue()) {
if (_topTitle.buttonPane == null) {
_topTitle.initButtonPane();
}
_topTitle.buttonPane.add(_topTitle._refreshButton);
} else {
_topTitle.buttonPane.remove(_topTitle._refreshButton);
}
_topTitle.buttonPane.revalidate();
_topTitle.buttonPane.repaint();
} else if (modif instanceof ExcellButtonStateChange && arg0 == getModel()) {
if (((Boolean) modif.newValue()).booleanValue()) {
if (_topTitle.buttonPane == null) {
_topTitle.initButtonPane();
}
_topTitle.buttonPane.add(_topTitle._excelButton);
} else {
_topTitle.buttonPane.remove(_topTitle._excelButton);
}
_topTitle.buttonPane.revalidate();
_topTitle.buttonPane.repaint();
}
if (IEBlocWidget.BLOC_TITLE_ATTRIBUTE_NAME.equals(modif.propertyName())) {
setTitle(getModel().getTitle());
} else if (modif instanceof InnerBlocInserted) {
updateInnerBlocInsertion((IEWidget) modif.newValue());
_topTitle.initButtonPane();
} else if (modif instanceof InnerBlocRemoved) {
updateInnerBlocRemoved((IEWidget) modif.oldValue());
_topTitle.initButtonPane();
} else if (modif instanceof ContentSizeChanged) {
handleContentResize();
} else if (modif instanceof StyleSheetFolderChanged) {
_topTitle.updateColor();
setDefaultBorder();
repaint();
} else {
super.update(arg0, modif);
}
}
public void handleContentResize() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Bloc resize due to content size change.");
}
_dropTableZone.setPreferredSize(new Dimension(_dropTableZone.getPreferredSize().width,
_dropTableZone.getPreferredSize().height + 24));
revalidate();
repaint();
}
public int getColSpan() {
return getModel().getColSpan();
}
private Border getParentBorder() {
return ((JComponent) getParent()).getBorder();
}
private Insets getParentBorderInsets() {
return getParentBorder().getBorderInsets(getParent());
}
private Border getGrandParentBorder() {
if (getParent().getParent() == null) {
return null;
}
return ((JComponent) getParent().getParent()).getBorder();
}
private Insets getGrandParentBorderInsets() {
return getGrandParentBorder().getBorderInsets(getParent().getParent());
}
@Override
public Dimension getPreferredSize() {
// int k = getModel().getParent() instanceof IETDWidget ? 8 : 0;
IESequenceWidgetWidgetView parentSequenceView = null;
if (getParent() instanceof IESequenceWidgetWidgetView) {
parentSequenceView = (IESequenceWidgetWidgetView) getParent();
}
int titleAndButtonPanelHeight = _topTitle.getPreferredSize().height + _buttonPanel.getPreferredSize().height;
if (titleAndButtonPanelHeight < 36) {
titleAndButtonPanelHeight = 36;
}
if (parentSequenceView != null) {
int width = parentSequenceView.getAvailableWidth();
Dimension d = new Dimension(width, _dropTableZone.getComponentCount() > 0 ? new Double(_dropTableZone.getComponent(0)
.getPreferredSize().getHeight()).intValue()
+ titleAndButtonPanelHeight : 24 + titleAndButtonPanelHeight);
return d;
}
int parentInsetsWidth = getParent().getInsets().left + getParent().getInsets().right;
int parentBorderInsetsWidth = getParentBorder() != null ? getParentBorderInsets().left + getParentBorderInsets().right : 0;
int grandParentInsetsWidth = getParent().getParent() == null || getParent().getParent().getInsets() == null ? 0 : getParent()
.getParent().getInsets().left + getParent().getParent().getInsets().right;
int grandParentBorderInsetsWidth = getGrandParentBorder() != null ? getGrandParentBorderInsets().left
+ getGrandParentBorderInsets().right : 0;
int totalWidth = parentInsetsWidth + parentBorderInsetsWidth + grandParentInsetsWidth + grandParentBorderInsetsWidth;
Dimension dim = new Dimension(getDropZoneWith() - totalWidth, _dropTableZone.getComponentCount() > 0 ? new Double(_dropTableZone
.getComponent(0).getPreferredSize().getHeight()).intValue()
+ titleAndButtonPanelHeight : 24 + titleAndButtonPanelHeight);
return dim;
}
private int getDropZoneWith() {
if (getDropZone() != null) {
return getDropZone().getAvailableWidth();
}
return _componentView.getMaxWidth() - IESequenceWidgetWidgetView.LAYOUT_GAP * 2;
}
private DropZoneTopComponent getDropZone() {
Container c = getParent();
while (c != null && !(c instanceof DropZoneTopComponent)) {
c = c.getParent();
}
return (DropZoneTopComponent) c;
}
public String getTitle() {
return getModel().getTitle();
}
private void setTitle(String s) {
_topTitle.setText(s.toUpperCase());
}
protected JTextField _jLabelTextField = null;
protected boolean labelEditing = false;
private JLabel topTitleLabel() {
return _topTitle._label;
}
@Override
public void editLabel() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Edit ie bloc label");
}
labelEditing = true;
_jLabelTextField = new JTextField(getTitle());
_jLabelTextField.setFont(BLOC_TITLE_FONT);
_jLabelTextField.setBorder(BorderFactory.createEmptyBorder());
// _jLabelTextField.setForeground(getFlexoNode().getTextColor());
_jLabelTextField.setBounds(topTitleLabel().getBounds());
_jLabelTextField.setHorizontalAlignment(SwingConstants.CENTER);
_jLabelTextField.getDocument().addDocumentListener(new TriggerRepaintDocumentListener(this));
_topTitle.removeLabel(topTitleLabel());
_topTitle.addTextField(_jLabelTextField);
_jLabelTextField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
finalizeEditBloc();
}
});
_jLabelTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent arg0) {
finalizeEditBloc();
}
});
_jLabelTextField.requestFocusInWindow();
_jLabelTextField.selectAll();
_topTitle.revalidate();
_topTitle.repaint();
}
public void finalizeEditBloc() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Finalize edit bloc");
}
if (labelEditing) {
getModel().setTitle(_jLabelTextField.getText());
}
labelEditing = false;
_topTitle.removeTextField(_jLabelTextField);
_topTitle.addLabel(topTitleLabel());
_topTitle.revalidate();
_topTitle.repaint();
}
private class TopTitle extends JPanel {
public TopTitle(IEBlocWidget model) {
super(new BorderLayout());
labelPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
labelPane.setOpaque(false);
if (getTitle() != null) {
_label = new JLabel(getTitle().toUpperCase());
} else {
_label = new JLabel(FlexoLocalization.localizedForKey("unnamed"));
}
_label.setOpaque(false);
_label.setForeground(getTextColor());
_label.setFont(BLOC_TITLE_FONT);
labelPane.add(_label);
add(labelPane, BorderLayout.CENTER);
initButtonPane();
updateColor();
}
public void updateColor() {
_label.setForeground(getTextColor());
setBackground(getMainColor());
repaint();
}
public void initButtonPane() {
HTMLListDescriptor desc = HTMLListDescriptor.createInstanceForBloc(getModel());
RepetitionOperator rep = null;
if (desc != null) {
rep = desc.getRepetitionOperator();
}
if (buttonPane == null) {
buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 5));
}
buttonPane.setOpaque(false);
_refreshButton.setOpaque(false);
_excelButton.setOpaque(false);
_refreshButton.setVisible(rep != null && rep.refreshButton());
_excelButton.setVisible(rep != null && rep.excelButton());
buttonPane.add(_refreshButton);
buttonPane.add(_excelButton);
buttonPane.validate();
if (buttonPane.getParent() == null) {
add(buttonPane, BorderLayout.EAST);
}
}
public void setText(String s) {
_label.setText(s.toUpperCase());
}
public void addLabel(JLabel l) {
labelPane.add(l);
}
public void removeLabel(JLabel l) {
labelPane.remove(l);
}
public void removeTextField(JTextField t) {
labelPane.remove(t);
}
public void addTextField(JTextField t) {
labelPane.add(t);
}
private JPanel labelPane;
protected JPanel buttonPane;
protected JLabel _label;
protected JLabel _excelButton = new JLabel(IconLibrary.SMALL_EXCEL_ICON);
protected JLabel _refreshButton = new JLabel(IconLibrary.REFRESH_ICON);
}
}