/**
* 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.person;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import de.chris_soft.fyllgen.data.Person;
import de.chris_soft.fyllgen.data.Relationship;
import de.chris_soft.fyllgen.widget.listener.CurrentPersonChangeEvent;
import de.chris_soft.fyllgen.widget.listener.CurrentPersonChangeListener;
import de.chris_soft.fyllgen.widget.listener.CurrentPersonChanger;
import de.chris_soft.fyllgen.widget.listener.RelationshipChangeEvent;
import de.chris_soft.fyllgen.widget.listener.RelationshipChangeListener;
import de.chris_soft.fyllgen.widget.listener.RelationshipChanger;
/**
* Combo-Box, die einen Wert einer Person enth�lt und diesen verwaltet. Diese
* Klasse implementiert RelationshipChanger, um Personenbeziehungen beobachten
* zu lassen als auch CurrentPersonChanger, um anzugeben, wenn sich die in sich
* angezeigte Person wechselt.
* @author Christian Packenius, Juli 2008.
*/
public class PersonRelationCombo implements CurrentPersonChangeListener, SelectionListener, RelationshipChanger,
CurrentPersonChanger {
/**
* Das Objekt, das diesen PersonChangeListener bedient.
*/
private CurrentPersonChanger currentPersonChanger = null;
/**
* Die aktuelle Person, zu der hier Beziehungen dargestellt werden.
*/
private Person currentPerson = null;
/**
* Die SWT-ComboBox.
*/
private final Combo combo;
/**
* Signalisiert, ob sich gerade die aktuelle Person �ndert.
*/
private boolean bCurrentPersonChanging = false;
/**
* Typ der Beziehung zwischen der aktuellen und der hier gew�hlten Person.
*/
private String relationshipType;
/**
* Liste aller angezeigten Personenverbindungen.
*/
private Relationship[] relships;
/**
* Liste aller Listener, die informiert werden wollen, sobald sich die
* Beziehung hier �ndert.
*/
private final List<RelationshipChangeListener> vRelationshipChangeListener = new ArrayList<RelationshipChangeListener>();
/**
* Liste aller Listener, die �ber einen Wechsel der aktuellen Person
* informiert werden wollen.
*/
private List<CurrentPersonChangeListener> vCurrentPersonChangeListener = new ArrayList<CurrentPersonChangeListener>();
/**
* Constructor.
* @param parentComposite Composite, in dem die Text-Box liegt.
* @param relationshipType Typ der Personen-Beziehung.
*/
public PersonRelationCombo(Composite parentComposite, String relationshipType) {
this.relationshipType = relationshipType;
combo = new Combo(parentComposite, SWT.BORDER | SWT.READ_ONLY);
combo.addSelectionListener(this);
set();
}
/**
* �ndert den CurrentPersonChanger (in der Regel ein Family-Objekt).
* @param currentPersonChanger Objekt, das eine (ver�nderbare) aktuelle Person
* enth�lt.
*/
public void setCurrentPersonChanger(CurrentPersonChanger currentPersonChanger) {
// Beim alten Changer abmelden.
if (this.currentPersonChanger != null) {
this.currentPersonChanger.removeCurrentPersonChangeListener(this);
}
// Neuen Changer merken und bei ihm anmelden.
this.currentPersonChanger = currentPersonChanger;
if (currentPersonChanger != null) {
currentPersonChanger.addCurrentPersonChangeListener(this);
currentPerson = currentPersonChanger.getCurrentPerson();
}
// Alles setzen.
set();
}
/**
* Setzt den Feldinhalt, en-/disabled das Feld und mehr.
*/
private void set() {
boolean bCurrentPersonExists = currentPerson != null;
combo.removeAll();
relships = null;
if (currentPerson != null && bCurrentPersonExists) {
relships = currentPerson.getRelationships(relationshipType);
for (Relationship relship : relships) {
combo.add(relship.getOtherPerson(currentPerson).getValue(Person.NAME));
}
if (relships.length > 0) {
combo.select(0);
}
}
boolean isEnabled = bCurrentPersonExists && relships != null && relships.length > 0;
combo.setEnabled(isEnabled);
}
/**
* Eine andere Person wurde in der ComboBox angew�hlt.
*/
private void changed() {
if (!bCurrentPersonChanging) {
if (currentPerson != null && combo.getSelectionIndex() >= 0) {
sendRelationshipChangeListenerEvent(new RelationshipChangeEvent(relships[combo.getSelectionIndex()]));
sendCurrentPersonChangeListenerEvent(new CurrentPersonChangeEvent(
relships[combo.getSelectionIndex()].getOtherPerson(currentPerson)));
}
else {
// 20110916 - Ein Versuch...
sendRelationshipChangeListenerEvent(new RelationshipChangeEvent(null));
}
}
}
/**
* @see de.chris_soft.fyllgen.widget.listener.CurrentPersonChangeListener#currentPersonChanged(de.chris_soft.fyllgen.widget.listener.CurrentPersonChangeEvent)
*/
public void currentPersonChanged(CurrentPersonChangeEvent event) {
bCurrentPersonChanging = true;
currentPerson = event.person;
set();
bCurrentPersonChanging = false;
changed();
}
/**
* @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) {
changed();
}
/**
* F�gt einen weiteren Listener hinzu, der informiert werden m�chte, sobald
* sich die aktuell beobachtete Beziehung �ndert.
* @param listener
*/
public void addRelationshipChangeListener(RelationshipChangeListener listener) {
// Den neuen Listener merken und ihm die aktuelle Beziehung anzeigen.
vRelationshipChangeListener.add(listener);
if (currentPerson == null || relships == null || relships.length == 0) {
listener.relationshipChanged(new RelationshipChangeEvent(null));
}
else {
listener.relationshipChanged(new RelationshipChangeEvent(relships[combo.getSelectionIndex()]));
}
}
/**
* Entfernt den angegebenen Listener wieder.
* @param listener
*/
public void removeRelationshipChangeListener(RelationshipChangeListener listener) {
vRelationshipChangeListener.remove(listener);
}
/**
* Den Event an alle Listener senden, dass sich die aktuelle Beziehung
* zwischen zwei Personen ge�ndert hat.
* @param event
*/
private void sendRelationshipChangeListenerEvent(RelationshipChangeEvent event) {
for (RelationshipChangeListener listener : vRelationshipChangeListener) {
listener.relationshipChanged(event);
}
}
/**
* @see de.chris_soft.fyllgen.widget.listener.CurrentPersonChangeListener#getControl()
*/
public Control getControl() {
return combo;
}
/**
* @see de.chris_soft.fyllgen.widget.listener.RelationshipChanger#getCurrentRelationship()
*/
public Relationship getCurrentRelationship() {
if (combo.getSelectionIndex() < 0) {
return null;
}
return relships[combo.getSelectionIndex()];
}
/**
* F�gt einen weiteren Listener hinzu, der informiert werden m�chte, sobald
* sich die aktuelle Person �ndern.
* @param listener
*/
public void addCurrentPersonChangeListener(CurrentPersonChangeListener listener) {
// Den neuen Listener merken und ihm die aktuelle Person anzeigen.
vCurrentPersonChangeListener.add(listener);
listener.currentPersonChanged(new CurrentPersonChangeEvent(currentPerson));
}
/**
* Entfernt den angegebenen Listener wieder.
* @param listener
*/
public void removeCurrentPersonChangeListener(CurrentPersonChangeListener listener) {
vCurrentPersonChangeListener.remove(listener);
}
/**
* Den Event an alle Listener senden, dass sich die aktuelle Person ge�ndert
* hat.
* @param event
*/
private void sendCurrentPersonChangeListenerEvent(CurrentPersonChangeEvent event) {
for (CurrentPersonChangeListener listener : vCurrentPersonChangeListener) {
listener.currentPersonChanged(event);
}
}
/**
* @see de.chris_soft.fyllgen.widget.listener.CurrentPersonChanger#getCurrentPerson()
*/
public Person getCurrentPerson() {
if (combo.getSelectionIndex() < 0) {
return null;
}
return relships[combo.getSelectionIndex()].getOtherPerson(currentPerson);
}
}