/**
* 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.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Point;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;
import de.chris_soft.fyllgen.GUI;
import de.chris_soft.fyllgen.data.AtomData;
import de.chris_soft.fyllgen.data.Person;
import de.chris_soft.fyllgen.utilities.SwtUtilities;
/**
* Running some reports.
* @author Christian Packenius, 20110930.
*/
public class ReportCreationDialog_ExtendedButNotOkay extends Dialog implements ShellListener, SelectionListener {
/**
* Dialog window.
*/
private final Shell shell;
private ScrolledComposite scroller;
/**
* Liste aller Einstellungen.
*/
private List<Choice> choices = new ArrayList<Choice>();
/**
* Zu jedem Radio-Button wird hier die �bergeordnete Checkbox gespeichert.
*/
// private Map<Button, Button> radio2check = new HashMap<Button, Button>();
/**
* Zu jeder Checkbox wird hier die Liste der Radio-Buttons gespeichert.
*/
// private Map<Button, List<Button>> check2radiolist = new HashMap<Button,
// List<Button>>();
/**
* Constructor.
* @param parent The parent shell for this dialog.
*/
public ReportCreationDialog_ExtendedButNotOkay(Shell parent) {
super(parent, 0);
shell = new Shell(parent, SWT.CLOSE | SWT.TITLE | SWT.APPLICATION_MODAL);
shell.setImage(GUI.instance.shellIcon);
shell.addShellListener(this);
shell.setText("Reports erstellen");
shell.setSize(500, 300);
shell.setLayout(new FormLayout());
scroller = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL);
FormData fd = new FormData();
fd.left = fd.top = new FormAttachment(0, 0);
fd.right = fd.bottom = new FormAttachment(100, 0);
scroller.setLayoutData(fd);
Composite comp = new Composite(scroller, 0);
scroller.setContent(comp);
comp.setLayout(new GridLayout(1, false));
addNewChoice(0);
// Alle Markierungen ins Fenster einf�gen.
// for (String tag : TagManagement.instance.getTagList()) {
// Button checkbox = new Button(comp, SWT.CHECK);
// checkbox.setText("Markierung: " + tag);
// addLineGrid(comp, checkbox, new String[] { "gesetzt", "nicht gesetzt" });
// }
// Composite im Scroller auf die korrekte Gr��e bringen.
resizeContent(comp);
// Noch mittig ins vorhandene Fenster setzen.
SwtUtilities.centerInParent(shell, parent);
}
/**
* Setzt eine Komponente in einem Scroller auf Default-Werte.
*/
private void resizeContent(Composite comp) {
Point size = comp.computeSize(SWT.DEFAULT, SWT.DEFAULT);
size.x = Math.max(size.x, scroller.getClientArea().width);
comp.setSize(size);
}
/**
* F�gt eine weitere Entscheidung ein.
*/
private void addNewChoice(int index) {
// Weitere Wahlm�glichkeit einf�gen.
choices.add(index, new Choice());
// Alles neu aufbauen.
rebuild();
}
/**
* Baut alles neu auf.
*/
public void rebuild() {
// Alle bisherigen Controls l�schen.
Composite comp = (Composite) scroller.getContent();
// comp.setVisible(false);
for (Control child : comp.getChildren()) {
child.dispose();
}
// Alles neu aufbauen.
Choice lastChoice = null;
for (int i = 0; i < choices.size(); i++) {
Choice choice = choices.get(i);
addOperationLine(comp, lastChoice, choice, i);
addComboLine(comp, i, choice);
lastChoice = choice;
}
addOperationLine(comp, lastChoice, null, choices.size());
// comp.setVisible(true);
// comp.redraw();
// scroller.setContent(comp);
// Point size = shell.getSize();
// size.x ^= 1;
// shell.setSize(size);
resizeContent(comp);
}
/**
* F�gt eine Zeile mit ComboBox ein.
*/
private void addComboLine(Composite comp, int i, Choice choice) {
Composite c2 = new Composite(comp, 0);
c2.setLayout(new GridLayout(4, false));
addEmptyLabel(c2, choice.level * 2);
Combo combo = new Combo(c2, SWT.DROP_DOWN | SWT.READ_ONLY);
addPersonFields(combo);
combo.setData("choice", i);
combo.addSelectionListener(this);
combo.select(choice.index);
Button buttonRemove = new Button(c2, SWT.PUSH);
buttonRemove.setText("-");
buttonRemove.setData("remove", i);
buttonRemove.addSelectionListener(this);
addFillingLabel(c2);
}
/**
* Schreibt alle m�glichen Personenfelder in die ComboBox.
*/
private void addPersonFields(Combo combo) {
for (AtomData ad : Person.atomData) {
String title = ad.title;
if (title != null) {
title = title.trim();
if (title.endsWith(":")) {
title = title.substring(0, title.length() - 1);
}
title = title.replace("&", "");
combo.add("Feld: " + title);
}
}
}
/**
* F�gt zwischen den Zeilen mit den eigentlichen Einzelauswahlen jeweils eine
* Zeile mit "UND", "ODER", "NEU" ein.
*/
@SuppressWarnings("null")
private void addOperationLine(Composite comp, Choice lastChoice, Choice choice, int index) {
Composite c2 = new Composite(comp, 0);
boolean anyNull = lastChoice == null || choice == null;
c2.setLayout(new GridLayout(anyNull ? 3 : 5, false));
int level = 0;
if (!anyNull) {
level = Math.max(lastChoice.level, choice.level);
}
else if (choice == null) {
level = lastChoice.level;
}
else {
level = choice.level;
}
addEmptyLabel(c2, level * 2);
if (!anyNull) {
Button radio1 = addRadioButton(c2, "UND");
radio1.setData("radioAND", index);
radio1.addSelectionListener(this);
Button radio2 = addRadioButton(c2, "ODER");
radio2.setData("radioOR", index);
radio2.addSelectionListener(this);
new Button[] { radio1, radio2 }[choice.operationWithPreControl].setSelection(true);
}
Button starButton = addButton(c2, "*");
starButton.setData("newIndex", index);
starButton.addSelectionListener(this);
addFillingLabel(c2);
}
/**
* Erzeugt einen "normalen" Push-Button.
*/
private Button addButton(Composite c2, String text) {
Button button = new Button(c2, SWT.PUSH);
button.setText(text);
return button;
}
/**
* Erzeugt ein leeres Label, das sich den Rest vom Platz der Grid-Zeile
* schnappt.
*/
private void addFillingLabel(Composite c2) {
Label label = new Label(c2, 0);
label.setText("");
GridData gd = new GridData(SWT.FILL, 0, true, false);
label.setLayoutData(gd);
}
/**
* Erzeugt einen neuen Radiobutton.
*/
private Button addRadioButton(Composite c2, String text) {
Button radio = new Button(c2, SWT.RADIO);
radio.setText(text);
return radio;
}
/**
* Erzeugt ein leeres Label einer bestimmten Spaceanzahl.
*/
private void addEmptyLabel(Composite c2, int i) {
String s = "";
while (i-- > 0) {
s += " ";
}
Label label = new Label(c2, 0);
label.setText(s);
}
/**
* Open this dialog.
*/
public void open() {
shell.open();
// Ereignis-Liste abarbeiten.
eventQueue();
}
/**
* SWT event queue.
*/
private void eventQueue() {
Display display = Display.getDefault();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent)
*/
public void shellActivated(ShellEvent e) {
// Ignorieren.
}
/**
* @see org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events.ShellEvent)
*/
public void shellClosed(ShellEvent e) {
// Ignorieren.
}
/**
* @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
*/
public void shellDeactivated(ShellEvent e) {
// Ignorieren.
}
/**
* @see org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt.events.ShellEvent)
*/
public void shellDeiconified(ShellEvent e) {
// Ignorieren.
}
/**
* @see org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events.ShellEvent)
*/
public void shellIconified(ShellEvent e) {
// Ignorieren.
}
/**
* Innere Klasse, welche die einzelnen Auswahlen beschreibt, damit sie
* jederzeit modifiziert werden k�nnen.
*/
class Choice {
/**
* Mathematische Klammerebene, auf der sich diese Auswahl befindet.
*/
public int level = 0;
/**
* Index des Inhaltes (-1 bedeutet, dass es keinen Inhalt gibt).
*/
public int index = -1;
/**
* Operation, die mit dem vorangehenden Control ausgef�hrt werden soll:
* 0=AND, 1=OR.
*/
public int operationWithPreControl = 0;
}
/**
* @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) {
Widget widget = e.widget;
Integer newIndex = (Integer) widget.getData("newIndex");
Integer choice = (Integer) widget.getData("choice");
Integer radioAND = (Integer) widget.getData("radioAND");
Integer radioOR = (Integer) widget.getData("radioOR");
Integer remove = (Integer) widget.getData("remove");
if (newIndex != null) {
addNewChoice(newIndex);
}
else if (choice != null) {
choices.get(choice).index = ((Combo) widget).getSelectionIndex();
}
else if (radioAND != null) {
choices.get(radioAND).operationWithPreControl = 0;
}
else if (radioOR != null) {
choices.get(radioOR).operationWithPreControl = 1;
}
else if (remove != null) {
choices.remove(remove);
if (choices.isEmpty()) {
addNewChoice(0);
}
rebuild();
}
}
}