/**
* Warlock, the open-source cross-platform game client
*
* Copyright 2008, Warlock LLC, and individual contributors as indicated
* by the @authors tag.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package cc.warlock.rcp.prefs;
import java.util.ArrayList;
import java.util.regex.PatternSyntaxException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.preference.ColorSelector;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableColorProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPropertyPage;
import cc.warlock.core.client.IWarlockClient;
import cc.warlock.core.client.IWarlockSkin;
import cc.warlock.core.client.WarlockColor;
import cc.warlock.core.client.internal.WarlockStyle;
import cc.warlock.core.client.settings.IHighlightString;
import cc.warlock.core.client.settings.internal.ClientSettings;
import cc.warlock.core.client.settings.internal.HighlightConfigurationProvider;
import cc.warlock.core.client.settings.internal.HighlightString;
import cc.warlock.rcp.ui.WarlockSharedImages;
import cc.warlock.rcp.util.ColorUtil;
public class HighlightStringsPreferencePage extends PreferencePageUtils implements
IWorkbenchPropertyPage {
public static final String PAGE_ID = "cc.warlock.rcp.prefs.highlightStrings";
protected TableViewer stringTable;
protected Button fillLineButton, regexButton, fullWordMatchButton, caseSensitiveButton;
protected ColorSelector customBGSelector, customFGSelector;
protected Button defaultBG, customBG, defaultFG, customFG;
protected Button addString, removeString, soundButton;
protected Text filterText;
protected Text soundText;
protected IWarlockClient client;
protected IWarlockSkin skin;
protected ClientSettings settings;
protected HighlightString selectedString;
protected ArrayList<HighlightString> addedStrings = new ArrayList<HighlightString>();
protected ArrayList<HighlightString> removedStrings = new ArrayList<HighlightString>();
protected ArrayList<HighlightString> highlightStrings = new ArrayList<HighlightString>();
private void copyHighlightStrings ()
{
highlightStrings.clear();
for (IHighlightString string : client.getClientSettings().getAllHighlightStrings())
{
if (string instanceof HighlightString)
{
highlightStrings.add(new HighlightString((HighlightString)string));
}
}
}
@Override
protected Control createContents(Composite parent) {
Composite main = new Composite(parent, SWT.NONE);
main.setLayout(new GridLayout(1, false));
createStringsTable(main);
createOptions(main);
return main;
}
private void createStringsTable (Composite main)
{
Group stringsGroup = new Group(main, SWT.NONE);
stringsGroup.setLayout(new GridLayout(2, false));
stringsGroup.setText(getDisplayName());
stringsGroup.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
Composite filterComposite = new Composite(stringsGroup, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginWidth = layout.marginHeight = 0;
filterComposite.setLayout(layout);
filterComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
new Label(filterComposite, SWT.NONE).setText("Filter: ");
filterText = new Text(filterComposite, SWT.BORDER);
filterText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
stringTable.refresh();
}
});
filterText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
new Label(stringsGroup, SWT.NONE);
stringTable = new TableViewer(stringsGroup, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL );
TableColumn column = new TableColumn(stringTable.getTable(), SWT.NONE, 0);
column.setWidth(400);
stringTable.setUseHashlookup(true);
stringTable.setColumnProperties(new String[] { "highlightString" });
CellEditor editors[] = new CellEditor[] {
new TextCellEditor(stringTable.getTable())
};
stringTable.setCellEditors(editors);
stringTable.setCellModifier(new ICellModifier () {
public boolean canModify(Object element, String property) {
return true;
}
public Object getValue(Object element, String property) {
return ((HighlightString)element).getText();
}
public void modify(Object element, String property, Object value) {
TableItem item = (TableItem)element;
HighlightString string = (HighlightString)item.getData();
String pattern = ((String)value).trim();
try {
string.setText(pattern);
} catch(PatternSyntaxException e) {
e.printStackTrace();
}
stringTable.refresh(string);
}
});
stringTable.addFilter(new ViewerFilter () {
public boolean select(Viewer viewer, Object parentElement, Object element) {
HighlightString string = (HighlightString) element;
String str = string.getText();
if (str.equals("")) return true;
return (str.toLowerCase().contains(filterText.getText().toLowerCase()));
}
});
stringTable.setLabelProvider(new StringsLabelProvider());
stringTable.setContentProvider(new ArrayContentProvider());
stringTable.setInput(highlightStrings);
int listHeight = stringTable.getTable().getItemHeight() * 8;
Rectangle trim = stringTable.getTable().computeTrim(0, 0, 0, listHeight);
GridData data = new GridData(GridData.FILL, GridData.FILL, true, true);
data.heightHint = trim.height;
stringTable.getTable().setLayoutData(data);
stringTable.addSelectionChangedListener(new ISelectionChangedListener () {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
HighlightString string = (HighlightString) selection.getFirstElement();
if (string != selectedString)
{
stringTable.cancelEditing();
}
highlightStringSelected(string);
}
});
Composite buttonsComposite = new Composite(stringsGroup, SWT.NONE);
buttonsComposite.setLayout(new GridLayout(1, true));
buttonsComposite.setLayoutData(new GridData(GridData.CENTER, GridData.BEGINNING, true, true));
addString = createButton(buttonsComposite, "Add", SWT.LEFT | SWT.PUSH);
addString.setImage(WarlockSharedImages.getImage(WarlockSharedImages.IMG_ADD));
addString.setLayoutData(new GridData(GridData.FILL_BOTH));
removeString = createButton(buttonsComposite, "Remove", SWT.LEFT | SWT.PUSH);
removeString.setImage(WarlockSharedImages.getImage(WarlockSharedImages.IMG_REMOVE));
removeString.setEnabled(false);
}
private void createOptions (Composite main)
{
Group optionsGroup = new Group(main, SWT.NONE);
optionsGroup.setLayout(new GridLayout(1, false));
optionsGroup.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
optionsGroup.setText("Options");
Composite mainGroup = new Composite(optionsGroup, SWT.NONE);
mainGroup.setLayout(new GridLayout(2, false));
mainGroup.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
new Label(mainGroup, SWT.NONE).setText("Foreground Color: ");
Composite fgColorComposite = new Composite(mainGroup, SWT.NONE);
fgColorComposite.setLayout(new GridLayout(3, false));
fgColorComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
defaultFG = createRadio(fgColorComposite, "Default");
defaultFG.setEnabled(false);
customFG = createRadio(fgColorComposite);
customFG.setEnabled(false);
customFGSelector = createColorSelector(fgColorComposite);
customFGSelector.setEnabled(false);
customFGSelector.setColorValue(new RGB(0, 0, 0));
new Label(mainGroup, SWT.NONE).setText("Background Color: ");
Composite bgColorComposite = new Composite(mainGroup, SWT.NONE);
bgColorComposite.setLayout(new GridLayout(3, false));
bgColorComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
defaultBG = createRadio(bgColorComposite, "Default");
defaultBG.setEnabled(false);
customBG = createRadio(bgColorComposite);
customBG.setEnabled(false);
customBGSelector = createColorSelector(bgColorComposite);
customBGSelector.setEnabled(false);
customBGSelector.setColorValue(new RGB(0, 0, 0));
regexButton = createCheckbox(mainGroup, "Regular expression");
regexButton.setEnabled(false);
fillLineButton = createCheckbox(mainGroup, "Highlight Entire Line");
fillLineButton.setEnabled(false);
caseSensitiveButton = createCheckbox(mainGroup, "Case Sensitive");
caseSensitiveButton.setEnabled(false);
fullWordMatchButton = createCheckbox(mainGroup, "Match full word (word boundary)");
fullWordMatchButton.setEnabled(false);
Group soundGroup = new Group(optionsGroup, SWT.NONE);
soundGroup.setLayout(new GridLayout(3, false));
soundGroup.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
new Label(soundGroup, SWT.NONE).setText("Sound:");
soundText = new Text(soundGroup, SWT.BORDER | SWT.SINGLE);
soundText.setEnabled(false);
GridData soundTextData = new GridData(GridData.FILL_HORIZONTAL);
soundText.setLayoutData(soundTextData);
soundText.addListener(SWT.Modify, new Listener() {
public void handleEvent(Event event) {
selectedString.getStyle().setSound(soundText.getText());
}
});
soundButton = createButton(soundGroup, "Browse", SWT.PUSH);
soundButton.setEnabled(false);
addBtnSoundListener(main);
}
private void addBtnSoundListener(final Composite parent){
soundButton.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e){
browseForSound();
}
public void widgetDefaultSelected(SelectionEvent e){}
});
}
protected String getDisplayName ()
{
return "Highlight Strings";
}
protected HighlightString createHighlightString ()
{
return new HighlightString(
settings.getHighlightConfigurationProvider(), "<Highlight Text>", true, true, false, new WarlockStyle());
}
private void highlightStringSelected (HighlightString string)
{
if (string == null) {
// No string selected, disable all fields
removeString.setEnabled(false);
defaultFG.setEnabled(false);
defaultFG.setSelection(true);
customFG.setEnabled(false);
customFG.setSelection(true);
customFGSelector.setEnabled(false);
customFGSelector.setColorValue(new RGB(0, 0, 0));
defaultBG.setEnabled(false);
customBG.setEnabled(false);
customBG.setSelection(true);
customBGSelector.setEnabled(false);
customBGSelector.setColorValue(new RGB(0, 0, 0));
regexButton.setEnabled(false);
regexButton.setSelection(false);
fillLineButton.setEnabled(false);
fillLineButton.setSelection(false);
caseSensitiveButton.setEnabled(false);
caseSensitiveButton.setSelection(false);
fullWordMatchButton.setEnabled(false);
fullWordMatchButton.setSelection(false);
soundText.setEnabled(false);
soundText.setText("");
soundButton.setEnabled(false);
return;
}
selectedString = string;
removeString.setEnabled(true);
WarlockColor fgColor = string.getStyle().getForegroundColor();
WarlockColor bgColor = string.getStyle().getBackgroundColor();
boolean fgIsDefault = fgColor.isDefault();
boolean bgIsDefault = bgColor.isDefault();
defaultFG.setSelection(fgIsDefault);
defaultFG.setEnabled(true);
customFG.setSelection(!fgIsDefault);
customFG.setEnabled(true);
customFGSelector.setEnabled(!fgIsDefault);
defaultBG.setSelection(bgIsDefault);
defaultBG.setEnabled(true);
customBG.setSelection(!bgIsDefault);
customBG.setEnabled(true);
customBGSelector.setEnabled(!bgIsDefault);
if (fgIsDefault) {
customFGSelector.setColorValue(ColorUtil.warlockColorToRGB(skin.getMainForeground()));
} else {
customFGSelector.setColorValue(ColorUtil.warlockColorToRGB(fgColor));
}
if (bgIsDefault) {
customBGSelector.setColorValue(ColorUtil.warlockColorToRGB(skin.getMainBackground()));
} else {
customBGSelector.setColorValue(ColorUtil.warlockColorToRGB(bgColor));
}
regexButton.setSelection(!string.isLiteral());
regexButton.setEnabled(true);
fillLineButton.setSelection(string.getStyle().isFullLine());
fillLineButton.setEnabled(true);
caseSensitiveButton.setSelection(string.isCaseSensitive());
caseSensitiveButton.setEnabled(true);
fullWordMatchButton.setSelection(string.isFullWordMatch());
fullWordMatchButton.setEnabled(true);
try{
if (string.getStyle().getSound() != null){
soundText.setText(string.getStyle().getSound());
}else{
soundText.setText("");
}
}catch(Exception e){
e.printStackTrace();
}
soundText.setEnabled(true);
soundButton.setEnabled(true);
}
@Override
protected void buttonPressed(Button button) {
if (button == removeString) {
removeStringSelected();
} else if (button == addString) {
addStringSelected();
} else if (button == defaultBG) {
defaultBackgroundSelected();
} else if (button == defaultFG) {
defaultForegroundSelected();
} else if (button == customBG) {
customBGSelector.setEnabled(true);
} else if (button == customFG) {
customFGSelector.setEnabled(true);
} else if (button == fillLineButton) {
fillLineSelected();
} else if (button == fullWordMatchButton) {
fullWordMatchSelected();
} else if (button == caseSensitiveButton) {
caseSensitiveSelected();
} else if (button == regexButton) {
regexSelected();
}
}
protected void browseForSound(){
FileDialog fd = new FileDialog(HighlightStringsPreferencePage.this.getShell(), SWT.OPEN);
fd.setFilterNames(new String[]{"Wave File (*.wav)"});
fd.setFilterExtensions(new String[]{"*.wav"});
String filename = fd.open();
if (filename != null){
soundText.setText(filename);
try{
if (selectedString != null && selectedString.getStyle() != null){
selectedString.getStyle().setSound(filename);
selectedString.setNeedsUpdate(true);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
@Override
protected void colorSelectorChanged(ColorSelector selector) {
if (selector == customBGSelector) {
customBackgroundChanged();
} else if (selector == customFGSelector) {
customForegroundChanged();
}
}
private void defaultForegroundSelected ()
{
selectedString.getStyle().setForegroundColor(skin.getMainForeground());
customFGSelector.setEnabled(false);
customFGSelector.setColorValue(ColorUtil.warlockColorToRGB(selectedString.getStyle().getForegroundColor()));
stringTable.update(selectedString, null);
setValid(true);
}
private void customForegroundChanged ()
{
RGB selectedColor = customFGSelector.getColorValue();
WarlockColor newColor = ColorUtil.rgbToWarlockColor(selectedColor);
selectedString.getStyle().setForegroundColor(newColor);
stringTable.update(selectedString, null);
setValid(true);
}
private void defaultBackgroundSelected ()
{
selectedString.getStyle().setBackgroundColor(skin.getMainBackground());
customBGSelector.setEnabled(false);
customBGSelector.setColorValue(ColorUtil.warlockColorToRGB(selectedString.getStyle().getBackgroundColor()));
stringTable.update(selectedString, null);
setValid(true);
}
private void customBackgroundChanged ()
{
selectedString.getStyle().setBackgroundColor(ColorUtil.rgbToWarlockColor(customBGSelector.getColorValue()));
stringTable.update(selectedString, null);
setValid(true);
}
private void removeStringSelected() {
// Grab selected string.
HighlightString string = selectedString;
// Select Next (or Previous if last) Highlight in line
int index = stringTable.getTable().getSelectionIndex();
if (stringTable.getElementAt(index + 1) != null) {
stringTable.getTable().setSelection(index + 1);
highlightStringSelected((HighlightString) stringTable.getElementAt(index + 1));
} else if (stringTable.getElementAt(index - 1) != null) {
stringTable.getTable().setSelection(index - 1);
highlightStringSelected((HighlightString) stringTable.getElementAt(index - 1));
}
// Mark string removed in our changelog to commit to prefs
// If it was added since the last commit, just remove it from the changelog
if (!addedStrings.remove(string))
removedStrings.add(string);
// Remove string from our display list and notify the table
highlightStrings.remove(string);
stringTable.remove(string);
}
private void addStringSelected() {
HighlightString newString = createHighlightString();
highlightStrings.add(newString);
addedStrings.add(newString);
selectedString = newString;
stringTable.add(newString);
stringTable.editElement(newString, 0);
}
private void fillLineSelected () {
selectedString.getStyle().setFullLine(fillLineButton.getSelection());
}
private void fullWordMatchSelected () {
selectedString.setFullWordMatch(fullWordMatchButton.getSelection());
}
private void caseSensitiveSelected () {
selectedString.setCaseSensitive(caseSensitiveButton.getSelection());
}
private void regexSelected () {
selectedString.setLiteral(!regexButton.getSelection());
}
protected class StringsLabelProvider implements ITableLabelProvider, ITableColorProvider
{
public Image getColumnImage(Object element, int columnIndex) {
// TODO Auto-generated method stub
return null;
}
public String getColumnText(Object element, int columnIndex) {
return ((HighlightString)element).getText();
}
public void addListener(ILabelProviderListener listener) { }
public void dispose() { }
public boolean isLabelProperty(Object element, String property) {
return true;
}
public void removeListener(ILabelProviderListener listener) {}
public Color getBackground(Object element, int columnIndex) {
HighlightString string = (HighlightString)element;
Color c = new Color(HighlightStringsPreferencePage.this.getShell().getDisplay(),
ColorUtil.warlockColorToRGB(skin.getBackgroundColor(string)));
return c;
}
public Color getForeground(Object element, int columnIndex) {
HighlightString string = (HighlightString)element;
Color c = new Color(HighlightStringsPreferencePage.this.getShell().getDisplay(),
ColorUtil.warlockColorToRGB(skin.getForegroundColor(string)));
return c;
}
}
@Override
public void setElement(IAdaptable element) {
client = (IWarlockClient)element.getAdapter(IWarlockClient.class);
settings = (ClientSettings) client.getClientSettings();
skin = settings.getClient().getSkin();
if (highlightStrings.isEmpty())
copyHighlightStrings();
}
@Override
protected void performDefaults() {
copyHighlightStrings();
stringTable.refresh();
}
@Override
public boolean performOk() {
HighlightConfigurationProvider highlightConfig = settings.getHighlightConfigurationProvider();
if(highlightConfig == null)
return false;
for (HighlightString string : highlightStrings) {
WarlockStyle style = (WarlockStyle) string.getStyle();
if (addedStrings.remove(string)) {
highlightConfig.addHighlightString(string);
} else if (string.needsUpdate() || (style != null && style.needsUpdate())) {
highlightConfig.replaceHighlightString(string.getOriginalHighlightString(), string);
}
}
for (HighlightString string : removedStrings)
{
if (string.getOriginalHighlightString() != null) {
highlightConfig.removeHighlightString(string.getOriginalHighlightString());
} else {
highlightConfig.removeHighlightString(string);
}
}
return true;
}
}