/*
* Copyright (c) 2014 tabletoptool.com team.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* rptools.com team - initial implementation
* tabletoptool.com team - further development
*/
package com.t3.client.ui;
import java.awt.event.ActionEvent;
import java.lang.reflect.Method;
import java.util.LinkedList;
import javax.swing.DefaultComboBoxModel;
import javax.swing.border.TitledBorder;
import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.autocomplete.DefaultCompletionProvider;
import org.fife.ui.autocomplete.FunctionCompletion;
import org.fife.ui.autocomplete.ParameterizedCompletion.Parameter;
import com.t3.client.AppConstants;
import com.t3.client.AppUtil;
import com.t3.client.T3Util;
import com.t3.client.TabletopTool;
import com.t3.client.ui.forms.MacroButtonBaseDialog;
import com.t3.client.ui.macrobuttons.buttons.MacroButton;
import com.t3.language.I18N;
import com.t3.macro.api.functions.DialogFunctions;
import com.t3.macro.api.functions.InfoFunctions;
import com.t3.macro.api.functions.MapFunctions;
import com.t3.macro.api.functions.PathFunctions;
import com.t3.macro.api.functions.PlayerFunctions;
import com.t3.macro.api.functions.input.InputFunctions;
import com.t3.model.MacroButtonProperties;
import com.t3.model.Token;
import com.t3.swing.SwingUtil;
import com.t3.swing.preference.WindowPreferences;
public class MacroButtonDialog extends MacroButtonBaseDialog {
MacroButton button;
MacroButtonProperties properties;
boolean isTokenMacro = false;
int oldHashCode = 0;
Boolean startingCompareGroup;
Boolean startingCompareSortPrefix;
Boolean startingCompareCommand;
Boolean startingAllowPlayerEdits;
public MacroButtonDialog() {
SwingUtil.centerOver(this, TabletopTool.getFrame());
getRootPane().setDefaultButton(okButton);
installHotKeyCombo();
installColorCombo();
installFontColorCombo();
installFontSizeCombo();
initCommandTextArea();
hotKeyCombo.setEnabled(!isTokenMacro);
maxWidthTextField.setEnabled(false); // can't get max-width to work, so temporarily disabling it.
allowPlayerEditsCheckBox.setEnabled(TabletopTool.getPlayer().isGM());
new WindowPreferences(AppConstants.APP_NAME, "editMacroDialog", this);
}
private void installHotKeyCombo() {
String[] hotkeys = MacroButtonHotKeyManager.HOTKEYS;
for (int i = 0; i < hotkeys.length; i++)
hotKeyCombo.insertItemAt(hotkeys[i], i);
}
private void installColorCombo() {
colorComboBox.setModel(new DefaultComboBoxModel<String>(T3Util.getColorNames().toArray(new String[0])));
colorComboBox.insertItemAt("default", 0);
colorComboBox.setSelectedItem("default");
colorComboBox.setRenderer(new ColorComboBoxRenderer());
}
private void installFontColorCombo() {
fontColorComboBox.setModel(new DefaultComboBoxModel<String>(MacroButtonProperties.getFontColors()));
fontColorComboBox.setSelectedItem("black");
fontColorComboBox.setRenderer(new ColorComboBoxRenderer());
}
private void installFontSizeCombo() {
String[] fontSizes = { "0.75em", "0.80em", "0.85em", "0.90em", "0.95em", "1.00em", "1.05em", "1.10em", "1.15em", "1.20em", "1.25em" };
fontSizeComboBox.setModel(new DefaultComboBoxModel<String>(fontSizes));
}
public void show(MacroButton button) {
initI18NSupport();
this.button = button;
this.isTokenMacro = button.getToken() == null ? false : true;
this.properties = button.getProperties();
oldHashCode = properties.hashCodeForComparison();
Boolean playerCanEdit = !TabletopTool.getPlayer().isGM() && properties.getAllowPlayerEdits();
Boolean onGlobalPanel = properties.getSaveLocation().equals("Global");
Boolean allowEdits = onGlobalPanel || TabletopTool.getPlayer().isGM() || playerCanEdit;
Boolean isCommonMacro = button.getPanelClass().equals("SelectionPanel") && TabletopTool.getFrame().getSelectionPanel().getCommonMacros().contains(properties);
if (allowEdits) {
this.setTitle(I18N.getText("component.dialogTitle.macro.macroID") + ": " + Integer.toString(this.properties.hashCodeForComparison()));
colorComboBox.setSelectedItem(properties.getColorKey());
hotKeyCombo.setSelectedItem(properties.getHotKey());
labelTextField.setText(properties.getLabel());
groupTextField.setText(properties.getGroup());
sortByTextField.setText(properties.getSortby());
commandTextArea.setText(properties.getCommand());
commandTextArea.setCaretPosition(0);
commandTextArea.discardAllEdits(); //this removes all edits, otherwise adding all the text is an edit itself
fontColorComboBox.setSelectedItem(properties.getFontColorKey());
fontSizeComboBox.setSelectedItem(properties.getFontSize());
minWidthTextField.setText(properties.getMinWidth());
maxWidthTextField.setText(properties.getMaxWidth());
compareGroupCheckBox.setSelected(properties.getCompareGroup());
compareSortPrefixCheckBox.setSelected(properties.getCompareSortPrefix());
compareCommandCheckBox.setSelected(properties.getCompareCommand());
allowPlayerEditsCheckBox.setSelected(properties.getAllowPlayerEdits());
tooltipTextField.setText(properties.getToolTip());
if (isCommonMacro) {
colorComboBox.setEnabled(false);
hotKeyCombo.setEnabled(false);
groupTextField.setEnabled(properties.getCompareGroup());
sortByTextField.setEnabled(properties.getCompareSortPrefix());
commandTextArea.setEnabled(properties.getCompareCommand());
fontColorComboBox.setEnabled(false);
fontSizeComboBox.setEnabled(false);
minWidthTextField.setEnabled(false);
maxWidthTextField.setEnabled(false);
}
startingCompareGroup = properties.getCompareGroup();
startingCompareSortPrefix = properties.getCompareSortPrefix();
startingCompareCommand = properties.getCompareCommand();
startingAllowPlayerEdits = properties.getAllowPlayerEdits();
setVisible(true);
} else {
TabletopTool.showWarning(I18N.getText("msg.warning.macro.playerChangesNotAllowed"));
}
}
private void initCommandTextArea() {
//TODO create a real code completion -> the one below is crap
/*CompletionProvider provider = createCompletionProvider();
AutoCompletion ac = new AutoCompletion(provider);
ac.setAutoActivationEnabled(true);
ac.setParameterAssistanceEnabled(true);
ac.setShowDescWindow(true);
ac.install(commandTextArea);*/
}
private CompletionProvider createCompletionProvider() {
// A DefaultCompletionProvider is the simplest concrete implementation
// of CompletionProvider. This provider has no understanding of
// language semantics. It simply checks the text entered up to the
// caret position for a match against known completions. This is all
// that is needed in the majority of cases.
DefaultCompletionProvider provider = new DefaultCompletionProvider();
provider.setParameterizedCompletionParams('(', ", " , ')');
provider.setAutoActivationRules(false, ".");
// Add completions for all Java keywords. A BasicCompletion is just
// a straightforward word completion.
//TODO create a real xml file to parse from with comments
provider.addCompletion(new BasicCompletion(provider,"print","Printing a String","<b>Printing</b> a string."));
createDynamicCompletions(provider, "info", InfoFunctions.class);
createDynamicCompletions(provider, "player", PlayerFunctions.class);
createDynamicCompletions(provider, "map", MapFunctions.class);
createDynamicCompletions(provider, "dialog", DialogFunctions.class);
createDynamicCompletions(provider, "path", PathFunctions.class);
createDynamicCompletions(provider, "input", InputFunctions.class);
return provider;
}
private void createDynamicCompletions(DefaultCompletionProvider prov, String lib, Class<?> c) {
for(Method m:c.getMethods()) {
if(m.getDeclaringClass().equals(c)) {
FunctionCompletion fc = new FunctionCompletion(prov, lib+'.'+m.getName(),m.getReturnType().getSimpleName());
LinkedList<Parameter> params=new LinkedList<Parameter>();
Class<?>[] pts=m.getParameterTypes();
for(int i=0;i<pts.length;i++)
params.add(new Parameter(pts[i].getSimpleName(), "arg"+i));
if(!params.isEmpty())
fc.setParams(params);
prov.addCompletion(fc);
}
}
}
private void save() {
String hotKey = hotKeyCombo.getSelectedItem().toString();
button.getHotKeyManager().assignKeyStroke(hotKey);
button.setColor(colorComboBox.getSelectedItem().toString());
button.setText(this.button.getButtonText());
properties.setHotKey(hotKey);
properties.setColorKey(colorComboBox.getSelectedItem().toString());
properties.setLabel(labelTextField.getText());
properties.setGroup(groupTextField.getText());
properties.setSortby(sortByTextField.getText());
properties.setCommand(commandTextArea.getText());
properties.setFontColorKey(fontColorComboBox.getSelectedItem().toString());
properties.setFontSize(fontSizeComboBox.getSelectedItem().toString());
properties.setMinWidth(minWidthTextField.getText());
properties.setMaxWidth(maxWidthTextField.getText());
properties.setCompareGroup(compareGroupCheckBox.isSelected());
properties.setCompareSortPrefix(compareSortPrefixCheckBox.isSelected());
properties.setCompareCommand(compareCommandCheckBox.isSelected());
properties.setAllowPlayerEdits(allowPlayerEditsCheckBox.isSelected());
properties.setToolTip(tooltipTextField.getText());
properties.save();
if (button.getPanelClass().equals("SelectionPanel")) {
if (TabletopTool.getFrame().getSelectionPanel().getCommonMacros().contains(button.getProperties())) {
Boolean changeAllowPlayerEdits = false;
Boolean endingAllowPlayerEdits = false;
if (startingAllowPlayerEdits) {
if (!properties.getAllowPlayerEdits()) {
Boolean confirmDisallowPlayerEdits = TabletopTool.confirm(I18N.getText("confirm.macro.disallowPlayerEdits"));
if (confirmDisallowPlayerEdits) {
changeAllowPlayerEdits = true;
endingAllowPlayerEdits = false;
} else {
properties.setAllowPlayerEdits(true);
}
}
} else {
if (properties.getAllowPlayerEdits()) {
Boolean confirmAllowPlayerEdits = TabletopTool.confirm(I18N.getText("confirm.macro.allowPlayerEdits"));
if (confirmAllowPlayerEdits) {
changeAllowPlayerEdits = true;
endingAllowPlayerEdits = true;
} else {
properties.setAllowPlayerEdits(false);
}
}
}
Boolean trusted = true;
for (Token nextToken : TabletopTool.getFrame().getCurrentZoneRenderer().getSelectedTokensList()) {
if (AppUtil.playerOwns(nextToken)) {
trusted = true;
} else {
trusted = false;
}
boolean isGM = TabletopTool.getPlayer().isGM();
for (MacroButtonProperties nextMacro : nextToken.getMacroList(trusted)) {
if (isGM) { //FIXME or should this be if true?
if (nextMacro.hashCodeForComparison() == oldHashCode) {
nextMacro.setLabel(properties.getLabel());
if (properties.getCompareGroup() && startingCompareGroup) {
nextMacro.setGroup(properties.getGroup());
}
if (properties.getCompareSortPrefix() && startingCompareSortPrefix) {
nextMacro.setSortby(properties.getSortby());
}
if (properties.getCompareCommand() && startingCompareCommand) {
nextMacro.setCommand(properties.getCommand());
}
if (changeAllowPlayerEdits) {
nextMacro.setAllowPlayerEdits(endingAllowPlayerEdits);
}
nextMacro.setCompareGroup(properties.getCompareGroup());
nextMacro.setCompareSortPrefix(properties.getCompareSortPrefix());
nextMacro.setCompareCommand(properties.getCompareCommand());
nextMacro.save();
}
}
}
}
}
TabletopTool.getFrame().getSelectionPanel().reset();
}
if (button.getPanelClass().equals("CampaignPanel")) {
TabletopTool.serverCommand().updateCampaignMacros(TabletopTool.getCampaign().getMacroButtonPropertiesArray());
TabletopTool.getFrame().getCampaignPanel().reset();
}
setVisible(false);
}
private void cancel() {
setVisible(false);
}
private void initI18NSupport() {
macroTabs.setTitleAt(0, I18N.getText("component.tab.macro.details"));
macroTabs.setTitleAt(1, I18N.getText("component.tab.macro.options"));
macroLabelLabel.setText(I18N.getText("component.label.macro.label") + ":");
labelTextField.setToolTipText(I18N.getText("component.tooltip.macro.label"));
macroGroupLabel.setText(I18N.getText("component.label.macro.group") + ":");
groupTextField.setToolTipText(I18N.getText("component.tooltip.macro.group"));
macroSortPrefixLabel.setText(I18N.getText("component.label.macro.sortPrefix") + ":");
sortByTextField.setToolTipText(I18N.getText("component.tooltip.macro.sortPrefix"));
macroHotKeyLabel.setText(I18N.getText("component.label.macro.hotKey") + ":");
hotKeyCombo.setToolTipText(I18N.getText("component.tooltip.macro.hotKey"));
macroCommandLabel.setText(I18N.getText("component.label.macro.command"));
macroButtonColorLabel.setText(I18N.getText("component.label.macro.buttonColor") + ":");
colorComboBox.setToolTipText(I18N.getText("component.tooltip.macro.buttonColor"));
macroFontColorLabel.setText(I18N.getText("component.label.macro.fontColor") + ":");
fontColorComboBox.setToolTipText(I18N.getText("component.tooltip.macro.fontColor"));
macroFontSizeLabel.setText(I18N.getText("component.label.macro.fontSize") + ":");
fontSizeComboBox.setToolTipText(I18N.getText("component.tooltip.macro.fontSize"));
macroMinWidthLabel.setText(I18N.getText("component.label.macro.minWidth") + ":");
minWidthTextField.setToolTipText(I18N.getText("component.tooltip.macro.minWidth"));
macroMaxWidthLabel.setText(I18N.getText("component.label.macro.maxWidth") + ":");
maxWidthTextField.setToolTipText(I18N.getText("component.tooltip.macro.maxWidth"));
macroToolTipLabel.setText(I18N.getText("component.label.macro.toolTip") + ":");
tooltipTextField.setToolTipText(I18N.getText("component.tooltip.macro.tooltip"));
allowPlayerEditsCheckBox.setText(I18N.getText("component.label.macro.allowPlayerEdits"));
allowPlayerEditsCheckBox.setToolTipText(I18N.getText("component.tooltip.macro.allowPlayerEdits"));
((TitledBorder) macroComparisonGridView.getBorder()).setTitle(I18N.getText("component.label.macro.macroCommonality"));
compareGroupCheckBox.setText(I18N.getText("component.label.macro.compareUseGroup"));
compareGroupCheckBox.setToolTipText(I18N.getText("component.tooltip.macro.compareUseGroup"));
compareSortPrefixCheckBox.setText(I18N.getText("component.label.macro.compareUseSortPrefix"));
compareSortPrefixCheckBox.setToolTipText(I18N.getText("component.tooltip.macro.compareUseSortPrefix"));
compareCommandCheckBox.setText(I18N.getText("component.label.macro.compareUseCommand"));
compareCommandCheckBox.setToolTipText(I18N.getText("component.tooltip.macro.compareUseCommand"));
}
@Override
protected void okButtonClicked(ActionEvent e) {
save();
}
@Override
protected void cancelButtonClicked(ActionEvent e) {
cancel();
}
}