package net.sf.latexdraw.instruments;
import java.awt.Font;
import javax.swing.AbstractButton;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import net.sf.latexdraw.actions.ModifyLatexProperties;
import net.sf.latexdraw.actions.ModifyLatexProperties.LatexProperties;
import net.sf.latexdraw.actions.ModifyPencilParameter;
import net.sf.latexdraw.actions.shape.ModifyShapeProperty;
import net.sf.latexdraw.actions.shape.ShapeProperties;
import net.sf.latexdraw.badaboom.BadaboomCollector;
import net.sf.latexdraw.glib.models.interfaces.prop.ITextProp;
import net.sf.latexdraw.glib.models.interfaces.prop.ITextProp.TextPosition;
import net.sf.latexdraw.glib.models.interfaces.shape.IGroup;
import net.sf.latexdraw.glib.models.interfaces.shape.IText;
import net.sf.latexdraw.glib.views.Java2D.impl.FlyweightThumbnail;
import net.sf.latexdraw.glib.views.Java2D.interfaces.IViewText;
import net.sf.latexdraw.glib.views.latex.LaTeXGenerator;
import net.sf.latexdraw.lang.LangTool;
import net.sf.latexdraw.util.LResources;
import org.malai.instrument.Interactor;
import org.malai.interaction.library.KeysTyped;
import org.malai.mapping.MappingRegistry;
import org.malai.swing.ui.SwingUIComposer;
import org.malai.swing.widget.MTextArea;
import org.malai.swing.widget.MToggleButton;
/**
* This instrument modifies texts.<br>
* <br>
* This file is part of LaTeXDraw.<br>
* Copyright (c) 2005-2014 Arnaud BLOUIN<br>
* <br>
* LaTeXDraw 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.
* <br>
* LaTeXDraw is distributed 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.<br>
* <br>
* 12/27/2010<br>
* @author Arnaud BLOUIN
* @since 3.0
*/
public class TextCustomiser extends ShapePropertyCustomiser {
/** The button that selects the bottom-left text position. */
protected MToggleButton blButton;
/** The button that selects the bottom text position. */
protected MToggleButton bButton;
/** The button that selects the bottom-right text position. */
protected MToggleButton brButton;
/** The button that selects the top-left text position. */
protected MToggleButton tlButton;
/** The button that selects the top text position. */
protected MToggleButton tButton;
/** The button that selects the top-right text position. */
protected MToggleButton trButton;
/** The button that selects the left text position. */
protected MToggleButton lButton;
/** The button that selects the right text position. */
protected MToggleButton rButton;
/** The button that selects the centre text position. */
protected MToggleButton centreButton;
/** The label used to explain the goal of the package text field. */
protected JLabel packagesLabel;
/** This text field permits to add latex packages that will be used during compilation. */
protected MTextArea packagesField;
/** The error log field. */
protected MTextArea logField;
/**
* Creates the instrument.
* @param composer The composer that manages the widgets of the instrument.
* @param hand The Hand instrument.
* @param pencil The Pencil instrument.
* @throws IllegalArgumentException If one of the given parameters is null.
* @since 3.0
*/
public TextCustomiser(final SwingUIComposer<?> composer, final Hand hand, final Pencil pencil) {
super(composer, hand, pencil);
initialiseWidgets();
}
@Override
protected void initialiseWidgets() {
packagesLabel = new JLabel(LangTool.INSTANCE.getStringActions("TextCust.1")); //$NON-NLS-1$
packagesField = new MTextArea(true, true);
packagesLabel.setLabelFor(packagesField);
final Font font = packagesField.getFont();
packagesField.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.2")); //$NON-NLS-1$
packagesField.setFont(new Font(font.getName(), font.getStyle(), Math.max(10, font.getSize()-4)));
packagesField.setColumns(35);
packagesField.setRows(10);
logField = new MTextArea(true, false);
logField.setEditable(false);
logField.setFont(new Font(font.getName(), font.getStyle(), Math.max(10, font.getSize()-4)));
logField.setColumns(50);
logField.setRows(10);
blButton = new MToggleButton(LResources.TEXTPOS_BL);
blButton.setMargin(LResources.INSET_BUTTON);
blButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.3")); //$NON-NLS-1$
bButton = new MToggleButton(LResources.TEXTPOS_B);
bButton.setMargin(LResources.INSET_BUTTON);
bButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.4")); //$NON-NLS-1$
brButton = new MToggleButton(LResources.TEXTPOS_BR);
brButton.setMargin(LResources.INSET_BUTTON);
brButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.5")); //$NON-NLS-1$
tlButton = new MToggleButton(LResources.TEXTPOS_TL);
tlButton.setMargin(LResources.INSET_BUTTON);
tlButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.6")); //$NON-NLS-1$
tButton = new MToggleButton(LResources.TEXTPOS_T);
tButton.setMargin(LResources.INSET_BUTTON);
tButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.7")); //$NON-NLS-1$
trButton = new MToggleButton(LResources.TEXTPOS_TR);
trButton.setMargin(LResources.INSET_BUTTON);
trButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.8")); //$NON-NLS-1$
centreButton = new MToggleButton(LResources.TEXTPOS_CENTRE);
centreButton.setMargin(LResources.INSET_BUTTON);
centreButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.9")); //$NON-NLS-1$
lButton = new MToggleButton(LResources.TEXTPOS_L);
lButton.setMargin(LResources.INSET_BUTTON);
lButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.10")); //$NON-NLS-1$
rButton = new MToggleButton(LResources.TEXTPOS_R);
rButton.setMargin(LResources.INSET_BUTTON);
rButton.setToolTipText(LangTool.INSTANCE.getStringActions("TextCust.11")); //$NON-NLS-1$
}
@Override
protected void setWidgetsVisible(final boolean visible) {
composer.setWidgetVisible(blButton, visible);
composer.setWidgetVisible(bButton, visible);
composer.setWidgetVisible(brButton, visible);
composer.setWidgetVisible(tlButton, visible);
composer.setWidgetVisible(tButton, visible);
composer.setWidgetVisible(trButton, visible);
composer.setWidgetVisible(lButton, visible);
composer.setWidgetVisible(rButton, visible);
composer.setWidgetVisible(centreButton, visible);
composer.setWidgetVisible(packagesLabel, visible);
composer.setWidgetVisible(packagesField.getScrollpane(), visible);
composer.setWidgetVisible(logField.getScrollpane(), visible);
}
@Override
protected void update(final IGroup shape) {
if(shape.isTypeOf(ITextProp.class)) {
final TextPosition tp = shape.getTextPosition();
bButton.setSelected(tp==TextPosition.BOT);
brButton.setSelected(tp==TextPosition.BOT_RIGHT);
blButton.setSelected(tp==TextPosition.BOT_LEFT);
tButton.setSelected(tp==TextPosition.TOP);
trButton.setSelected(tp==TextPosition.TOP_RIGHT);
tlButton.setSelected(tp==TextPosition.TOP_LEFT);
centreButton.setSelected(tp==TextPosition.CENTER);
lButton.setSelected(tp==TextPosition.LEFT);
rButton.setSelected(tp==TextPosition.RIGHT);
if(!packagesField.hasFocus()) // Otherwise it means that this field is currently being edited and must not be updated.
packagesField.setText(LaTeXGenerator.getPackages());
// Updating the log field.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IText txt = null;
for(int i=0, size=shape.size(); i<size && txt==null; i++) //TODO closure
if(shape.getShapeAt(i) instanceof IText)
txt = (IText)shape.getShapeAt(i);
if(txt!=null) {
final int max = 10;
final String msg = FlyweightThumbnail.inProgressMsg();
String log = FlyweightThumbnail.getLog(MappingRegistry.REGISTRY.getTargetFromSource(txt, IViewText.class));
int i = 0;
while(i<max && msg.equals(log)) {
try{ Thread.sleep(100);}
catch(final InterruptedException e){ BadaboomCollector.INSTANCE.add(e); }
log = FlyweightThumbnail.getLog(MappingRegistry.REGISTRY.getTargetFromSource(txt, IViewText.class));
i++;
}
if(log==null) log = ""; //$NON-NLS-1$
logField.setText(log);
}
}
});
}
else setActivated(false);
}
@Override
protected void initialiseInteractors() {
try{
addInteractor(new KeysTyped2ChangePackages(this));
addInteractor(new ButtonPressed2ChangeTextPosition(this));
addInteractor(new ButtonPressed2ChangePencil(this));
}catch(InstantiationException | IllegalAccessException e){
BadaboomCollector.INSTANCE.add(e);
}
}
/**
* @return The button that selects the bottom-left text position.
* @since 3.0
*/
public MToggleButton getBlButton() {
return blButton;
}
/**
* @return The button that selects the bottom text position.
* @since 3.0
*/
public MToggleButton getBButton() {
return bButton;
}
/**
* @return The button that selects the bottom-right text position.
* @since 3.0
*/
public MToggleButton getBrButton() {
return brButton;
}
/**
* @return The button that selects the top-left text position.
* @since 3.0
*/
public MToggleButton getTlButton() {
return tlButton;
}
/**
* @return The button that selects the top text position.
* @since 3.0
*/
public MToggleButton getTButton() {
return tButton;
}
/**
* @return The button that selects the top-right text position.
* @since 3.0
*/
public MToggleButton getTrButton() {
return trButton;
}
/**
* @return The button that selects the left text position.
* @since 3.0
*/
public MToggleButton getLButton() {
return lButton;
}
/**
* @return The button that selects the right text position.
* @since 3.0
*/
public MToggleButton getRButton() {
return rButton;
}
/**
* @return The button that selects the centre text position.
* @since 3.0
*/
public MToggleButton getCentreButton() {
return centreButton;
}
/**
* @return the packagesLabel.
* @since 3.0
*/
public JLabel getPackagesLabel() {
return packagesLabel;
}
/**
* @return the packagesField.
* @since 3.0
*/
public MTextArea getPackagesField() {
return packagesField;
}
/** @return The text field that contains the compilation log. */
public MTextArea getLogField() {
return logField;
}
}
class KeysTyped2ChangePackages extends Interactor<ModifyLatexProperties, KeysTyped, TextCustomiser> {
protected KeysTyped2ChangePackages(final TextCustomiser ins) throws InstantiationException, IllegalAccessException {
super(ins, false, ModifyLatexProperties.class, KeysTyped.class);
}
@Override
public void initAction() {
action.setProperty(LatexProperties.PACKAGES);
}
@Override
public void updateAction() {
action.setValue(instrument.getPackagesField().getText());
}
@Override
public boolean isConditionRespected() {
return interaction.getObject()==instrument.packagesField;
}
}
/**
* Links a button interaction to an action that modifies the pencil.
*/
class ButtonPressed2ChangePencil extends ButtonPressedForCustomiser<ModifyPencilParameter, TextCustomiser> {
/**
* Creates the link.
* @param ins The instrument that contains the link.
* @throws InstantiationException If an error of instantiation (interaction, action) occurs.
* @throws IllegalAccessException If no free-parameter constructor are provided.
*/
ButtonPressed2ChangePencil(final TextCustomiser ins) throws InstantiationException, IllegalAccessException {
super(ins, ModifyPencilParameter.class);
}
@Override
public void initAction() {
final AbstractButton ab = interaction.getButton();
action.setProperty(ShapeProperties.TEXT_POSITION);
action.setPencil(instrument.pencil);
if(instrument.blButton==ab) action.setValue(ITextProp.TextPosition.BOT_LEFT);
else if(instrument.brButton==ab) action.setValue(ITextProp.TextPosition.BOT_RIGHT);
else if(instrument.tButton==ab) action.setValue(ITextProp.TextPosition.TOP);
else if(instrument.bButton==ab) action.setValue(ITextProp.TextPosition.BOT);
else if(instrument.tlButton==ab) action.setValue(ITextProp.TextPosition.TOP_LEFT);
else if(instrument.centreButton==ab) action.setValue(ITextProp.TextPosition.CENTER);
else if(instrument.lButton==ab) action.setValue(ITextProp.TextPosition.LEFT);
else if(instrument.rButton==ab) action.setValue(ITextProp.TextPosition.RIGHT);
else action.setValue(ITextProp.TextPosition.TOP_RIGHT);
}
@Override
public boolean isConditionRespected() {
final AbstractButton ab = interaction.getButton();
return instrument.pencil.isActivated() && (instrument.tButton==ab || instrument.tlButton==ab || instrument.centreButton==ab ||
instrument.trButton==ab || instrument.bButton==ab || instrument.blButton==ab || instrument.brButton==ab ||
instrument.lButton==ab || instrument.rButton==ab);
}
}
/**
* Links a button interaction to an action that modifies the selected shapes.
*/
class ButtonPressed2ChangeTextPosition extends ButtonPressedForCustomiser<ModifyShapeProperty, TextCustomiser> {
/**
* Creates the link.
* @param ins The instrument that contains the link.
* @throws InstantiationException If an error of instantiation (interaction, action) occurs.
* @throws IllegalAccessException If no free-parameter constructor are provided.
*/
ButtonPressed2ChangeTextPosition(final TextCustomiser ins) throws InstantiationException, IllegalAccessException {
super(ins, ModifyShapeProperty.class);
}
@Override
public void initAction() {
final AbstractButton ab = interaction.getButton();
action.setGroup(instrument.hand.canvas().getDrawing().getSelection().duplicateDeep(false));
action.setProperty(ShapeProperties.TEXT_POSITION);
if(instrument.bButton==ab) action.setValue(ITextProp.TextPosition.BOT);
else if(instrument.blButton==ab) action.setValue(ITextProp.TextPosition.BOT_LEFT);
else if(instrument.brButton==ab) action.setValue(ITextProp.TextPosition.BOT_RIGHT);
else if(instrument.tButton==ab) action.setValue(ITextProp.TextPosition.TOP);
else if(instrument.tlButton==ab) action.setValue(ITextProp.TextPosition.TOP_LEFT);
else if(instrument.centreButton==ab) action.setValue(ITextProp.TextPosition.CENTER);
else if(instrument.lButton==ab) action.setValue(ITextProp.TextPosition.LEFT);
else if(instrument.rButton==ab) action.setValue(ITextProp.TextPosition.RIGHT);
else action.setValue(ITextProp.TextPosition.TOP_RIGHT);
}
@Override
public boolean isConditionRespected() {
final AbstractButton ab = interaction.getButton();
return instrument.hand.isActivated() && ( instrument.bButton==ab || instrument.blButton==ab || instrument.centreButton==ab ||
instrument.brButton==ab || instrument.tButton==ab || instrument.tlButton==ab || instrument.trButton==ab ||
instrument.lButton==ab || instrument.rButton==ab);
}
}