/**
* FyLLGen - A Java based tool for collecting and distributing family data
*
* Copyright (C) 2007-2011 Christian Packenius
*
* This program 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
* any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.chris_soft.fyllgen.widget.dialog;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import de.chris_soft.fyllgen.GUI;
import de.chris_soft.fyllgen.data.Family;
import de.chris_soft.fyllgen.data.OptionData;
import de.chris_soft.fyllgen.utilities.SwtConsts;
import de.chris_soft.fyllgen.utilities.SwtUtilities;
/**
* Optionen-Dialog. Hier werden ausnahmslos alle Optionen des Programms
* verwaltet.
* @author Christian Packenius, Juli 2008.
*/
public class OptionsDialog extends Dialog implements SelectionListener, MouseListener {
/**
* Das eigentliche Fenster-Objekt.
*/
private final Shell shell;
/**
* Push-Buttons.
*/
private final Button buttonOK;
private final Button buttonCancel;
/**
* S�mtliche verwendeten Controls f�r Optionen.
*/
private Map<String, Control> controls = new HashMap<String, Control>();
private int shellWidth = 550;
/**
* Konstruktor. Erzeugt das Fenster, ohne es anzuzeigen.
* @param parent Parent-Shell, �ber der dieser Dialog angezeigt wird.
*/
public OptionsDialog(Shell parent) {
super(parent, 0);
shell = new Shell(parent, SWT.CLOSE | SWT.TITLE | SWT.APPLICATION_MODAL);
shell.setImage(GUI.instance.shellIcon);
shell.setText("Optionen");
shell.setSize(shellWidth, 420);
// Noch mittig ins vorhandene Fenster setzen.
SwtUtilities.centerInParent(shell, parent);
// Shell hat innen einen Rahmen.
FormLayout shellLayout = new FormLayout();
shellLayout.marginBottom = shellLayout.marginLeft = shellLayout.marginRight = shellLayout.marginTop = 5;
shell.setLayout(shellLayout);
// Composite, in dem die unteren Buttons stecken.
Composite compButtons = new Composite(shell, 0);
GridLayout gridLayout = new GridLayout(2, true);
compButtons.setLayout(gridLayout);
FormData fd = new FormData();
fd.bottom = new FormAttachment(100, 0);
fd.right = new FormAttachment(100, 0);
compButtons.setLayoutData(fd);
buttonOK = new Button(compButtons, SWT.PUSH);
buttonOK.setText("OK");
buttonOK.setSize(40, SWT.DEFAULT);
GridData gd = new GridData();
gd.horizontalAlignment = SWT.FILL;
buttonOK.setLayoutData(gd);
buttonOK.addSelectionListener(this);
shell.setDefaultButton(buttonOK);
buttonCancel = new Button(compButtons, SWT.PUSH);
buttonCancel.setText("Abbrechen");
buttonCancel.setSize(40, SWT.DEFAULT);
gd = new GridData();
gd.horizontalAlignment = SWT.FILL;
buttonCancel.setLayoutData(gd);
buttonCancel.addSelectionListener(this);
// Erzeugen aller Tabs f�r das innere Composite.
// Zuerst das TabFolder.
TabFolder tabFolder = new TabFolder(shell, 0);
fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.left = new FormAttachment(0, 0);
fd.right = new FormAttachment(100, 0);
fd.bottom = new FormAttachment(compButtons, -5, SWT.TOP);
tabFolder.setLayoutData(fd);
createDynamicTabs(tabFolder);
}
/**
* Erzeugt dynamisch alle Tabs und deren Inhalte.
*/
private void createDynamicTabs(TabFolder tabFolder) {
for (String tabName : OptionData.instance.getOptionTabNames()) {
// Den Tab selbst erzeugen.
TabItem item = new TabItem(tabFolder, SWT.BORDER);
item.setText(tabName);
Composite tabItemComp = new Composite(tabFolder, 0);
item.setControl(tabItemComp);
GridLayout gl = new GridLayout(1, false);
tabItemComp.setLayout(gl);
// F�r jeden Tab die Schl�ssel der Optionen ermitteln.
for (String key : OptionData.instance.getKeysFromTabName(tabName)) {
Class<?> type = OptionData.instance.getTypeFromKey(key);
String title = OptionData.instance.getTitleFromKey(key);
if (type == Boolean.class) {
Button checkbox = new Button(tabItemComp, SWT.CHECK);
checkbox.setText(" " + title);
checkbox.setSelection(OptionData.instance.getBoolean(key));
checkbox.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
controls.put(key, checkbox);
}
else if (type == String.class) {
Label label = new Label(tabItemComp, 0);
label.setText(title + ":");
label.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
Text text = new Text(tabItemComp, SWT.BORDER);
text.setText(OptionData.instance.getString(key));
text.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
controls.put(key, text);
}
else if (type == Color.class) {
Composite comp = new Composite(tabItemComp, SWT.BORDER_DOT);
comp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
comp.setLayout(new FormLayout());
Label button = new Label(comp, SWT.BORDER);
Color color = OptionData.instance.getColor(key);
button.setBackground(color);
color.dispose();
FormData fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.bottom = new FormAttachment(100, 0);
fd.right = new FormAttachment(15, 0);
fd.left = new FormAttachment(0, 0);
button.setLayoutData(fd);
controls.put(key, button);
button.addMouseListener(this);
Label label = new Label(comp, 0);
label.setText(title + ": ");
fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.bottom = new FormAttachment(100, 0);
fd.right = new FormAttachment(100, 0);
fd.left = new FormAttachment(button, 5);
label.setLayoutData(fd);
}
else if (type == StringBuffer.class || type == StringBuilder.class) {
Label label = new Label(tabItemComp, 0);
label.setText(title + ":");
label.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
Text text = new Text(tabItemComp, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
text.setText(OptionData.instance.getString(key));
GridData gd = new GridData(SWT.FILL, SWT.END, true, false);
gd.heightHint = 80;
text.setLayoutData(gd);
controls.put(key, text);
}
else if (type == Integer.class) {
Composite comp = new Composite(tabItemComp, SWT.BORDER_DOT);
comp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
comp.setLayout(new FormLayout());
Combo combo = new Combo(comp, SWT.DROP_DOWN | SWT.READ_ONLY);
int min = OptionData.instance.getMinValueFromKey(key);
int max = OptionData.instance.getMaxValueFromKey(key);
int step = OptionData.instance.getStepValueFromKey(key);
for (int i = min; i <= max; i += step) {
combo.add(Integer.toString(i));
}
combo.select((OptionData.instance.getInt(key) - min) / step);
FormData fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.bottom = new FormAttachment(100, 0);
fd.right = new FormAttachment(100, 0);
fd.left = new FormAttachment(80, 0);
combo.setLayoutData(fd);
controls.put(key, combo);
Label label = new Label(comp, 0);
label.setText(title + ": ");
fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.bottom = new FormAttachment(100, 0);
fd.right = new FormAttachment(combo, -5);
fd.left = new FormAttachment(0, 0);
label.setLayoutData(fd);
}
else if (type == Combo.class) {
Composite comp = new Composite(tabItemComp, SWT.BORDER_DASH);
comp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
comp.setLayout(new FormLayout());
Combo combo = new Combo(comp, SWT.DROP_DOWN | SWT.READ_ONLY);
String currText = OptionData.instance.getComboText(key);
List<String> texts = OptionData.instance.getComboTexts(key);
for (String text : texts) {
combo.add(text);
if (text.equals(currText)) {
combo.select(combo.getItemCount() - 1);
}
}
FormData fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.bottom = new FormAttachment(100, 0);
fd.right = new FormAttachment(100, 0);
fd.left = new FormAttachment(80, 0);
combo.setLayoutData(fd);
controls.put(key, combo);
Label label = new Label(comp, 0);
label.setText(title + ": ");
fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.bottom = new FormAttachment(100, 0);
fd.right = new FormAttachment(combo, -5);
fd.left = new FormAttachment(0, 0);
label.setLayoutData(fd);
}
else {
throw new RuntimeException("Typ " + type.getName() + " nicht beachtet!");
}
}
}
}
/**
* �ffnet den Optionen-Dialog.
*/
public void open() {
shell.open();
// Ereignis-Liste abarbeiten.
while (!shell.isDisposed()) {
if (!SwtConsts.display.readAndDispatch()) {
SwtConsts.display.sleep();
}
}
}
/**
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
/**
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
if (e.widget == buttonOK) {
changeOptions();
// Consts.getOptionData().saveOptions();
shell.close();
shell.dispose();
Family.instance.setChanged(true);
Family.instance.review();
}
else if (e.widget == buttonCancel) {
shell.close();
shell.dispose();
}
}
/**
* �ndert die Optionen den Controls entsprechend ab.
*/
private void changeOptions() {
for (String tabName : OptionData.instance.getOptionTabNames()) {
for (String key : OptionData.instance.getKeysFromTabName(tabName)) {
Class<?> type = OptionData.instance.getTypeFromKey(key);
if (type == Boolean.class) {
Button checkbox = (Button) controls.get(key);
OptionData.instance.setBoolean(key, checkbox.getSelection());
}
else if (type == String.class || type == StringBuffer.class || type == StringBuilder.class) {
Text text = (Text) controls.get(key);
OptionData.instance.setString(key, text.getText());
}
else if (type == Integer.class) {
Combo combo = (Combo) controls.get(key);
OptionData.instance.setString(key, combo.getText());
}
else if (type == Combo.class) {
Combo combo = (Combo) controls.get(key);
OptionData.instance.setComboKeyFromText(key, combo.getText());
}
else if (type == Color.class) {
Label label = (Label) controls.get(key);
Color color = label.getBackground();
OptionData.instance.setColor(key, color);
color.dispose();
}
else {
throw new RuntimeException("Typ " + type.getName() + " nicht beachtet!");
}
}
}
}
/**
* @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
*/
public void mouseDoubleClick(MouseEvent e) {
// Ignorieren.
}
/**
* @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
*/
public void mouseDown(MouseEvent e) {
// Ignorieren.
}
/**
* Mausklick auf einem Label, das f�r eine Farbwahl da ist.
* @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
*/
public void mouseUp(MouseEvent e) {
if (e.widget instanceof Label) {
Control control = (Control) e.widget;
ColorDialog cd = new ColorDialog(shell);
Color color = control.getBackground();
RGB rgb = color.getRGB();
cd.setRGB(rgb);
color.dispose();
rgb = cd.open();
if (rgb != null) {
color = new Color(SwtConsts.display, rgb);
control.setBackground(color);
color.dispose();
}
}
}
}