package org.nightlabs.jfire.issuetracking.ui.project;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.jdo.FetchPlan;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.nightlabs.base.ui.composite.XComposite;
import org.nightlabs.base.ui.custom.XCombo;
import org.nightlabs.base.ui.job.Job;
import org.nightlabs.jdo.NLJDOHelper;
import org.nightlabs.jfire.base.login.ui.Login;
import org.nightlabs.jfire.issue.project.Project;
import org.nightlabs.jfire.issue.project.ProjectDAO;
import org.nightlabs.jfire.issue.project.id.ProjectID;
import org.nightlabs.jfire.issuetracking.ui.resource.Messages;
import org.nightlabs.progress.NullProgressMonitor;
import org.nightlabs.progress.ProgressMonitor;
import org.nightlabs.util.CollectionUtil;
import org.nightlabs.util.NLLocale;
public class ProjectComboComposite
extends XComposite
implements ISelectionProvider
{
public ProjectComboComposite(Composite parent, int style)
{
this(parent, style, getLocalOrganisationID(), false);
}
private static String getLocalOrganisationID()
{
try {
return Login.getLogin().getOrganisationID();
} catch (Exception x) {
throw new RuntimeException(x);
}
}
private XCombo projectCombo;
private Project selectedProject;
public ProjectComboComposite(Composite parent, int style,String filterOrganisationID, boolean filterOrganisationIDInverse)
{
super(parent, style, LayoutMode.TIGHT_WRAPPER);
createCombo();
loadProjects();
}
protected XCombo createCombo() {
projectCombo = new XCombo(this, SWT.BORDER | SWT.READ_ONLY);
projectCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
projectCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e)
{
int idx = projectCombo.getSelectionIndex();
if (idx < 0 || idx > projectList.size() - 1)
selectedProject = null;
else
selectedProject = projectList.get(idx);
fireSelectionChangedEvent();
}
});
return projectCombo;
}
private static String[] FETCH_GROUP_PROJECT = new String[] {
FetchPlan.DEFAULT,
Project.FETCH_GROUP_NAME,
Project.FETCH_GROUP_PARENT_PROJECT,
Project.FETCH_GROUP_SUBPROJECTS,
Project.FETCH_GROUP_DESCRIPTION};
private List<Project> projectList = new ArrayList<Project>();
public void loadProjects()
{
projectCombo.removeAll();
Job loadJob = new Job(Messages.getString("org.nightlabs.jfire.issuetracking.ui.project.ProjectComboComposite.job.loadingProjects.text")) { //$NON-NLS-1$
@Override
protected IStatus run(ProgressMonitor monitor)
{
try {
final Collection<Project> _projects = ProjectDAO.sharedInstance().getRootProjects(getLocalOrganisationID(), FETCH_GROUP_PROJECT, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor());
List<Project> tempProjectList = new ArrayList<Project>();
CollectionUtil.addAllToCollection(_projects.toArray(new Project[0]), tempProjectList);
Collections.sort(tempProjectList);
for (Project project : tempProjectList) {
generateSub(project);
}
getDisplay().asyncExec(new Runnable()
{
public void run()
{
if (isDisposed())
return;
projectCombo.removeAll();
for (Project pj : projectList) {
StringBuffer sb = new StringBuffer(""); //$NON-NLS-1$
for (int i = 0; i < pj.getLevel(); i++)
sb.append("ยป"); //$NON-NLS-1$
projectCombo.add(null, (sb.toString().equals("")?"": sb.append(" ")) + pj.getName().getText(NLLocale.getDefault().getLanguage())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
setSelectedProject(Project.PROJECT_ID_DEFAULT);
ProjectComboComposite.this.getParent().layout(true);
}
});
} catch (Exception x) {
throw new RuntimeException(x);
}
return Status.OK_STATUS;
}
};
loadJob.setPriority(Job.SHORT);
loadJob.schedule();
}
private int level = 0;
private void generateSub(Project project)
{
if (project != null) {
projectList.add(project);
Collection<Project> sp = ProjectDAO.sharedInstance().getProjectsByParentProjectID(project.getObjectId(), FETCH_GROUP_PROJECT, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor());
List<Project> tempProjectList = new ArrayList<Project>();
CollectionUtil.addAllToCollection(sp.toArray(new Project[0]), tempProjectList);
Collections.sort(tempProjectList);
if (sp.size() > 0) {
level++;
for (Project p : tempProjectList) {
p.setLevel(level);
generateSub(p);
}
level--;
}
}
}
private ListenerList selectionChangedListeners = new ListenerList();
private void fireSelectionChangedEvent()
{
if (selectionChangedListeners.isEmpty())
return;
SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());
for (Object l : selectionChangedListeners.getListeners()) {
ISelectionChangedListener listener = (ISelectionChangedListener) l;
listener.selectionChanged(event);
}
}
@Override
public void addSelectionChangedListener(ISelectionChangedListener listener) {
selectionChangedListeners.add(listener);
}
@Override
public ISelection getSelection() {
if (selectedProject == null)
return new StructuredSelection(new Object[0]);
return new StructuredSelection(selectedProject);
}
@Override
public void removeSelectionChangedListener(ISelectionChangedListener listener)
{
selectionChangedListeners.remove(listener);
}
@Override
public void setSelection(ISelection selection) {
if (!(selection instanceof IStructuredSelection))
throw new IllegalArgumentException("selection is not an instance of " + IStructuredSelection.class.getName() + " but " + (selection == null ? null : selection.getClass().getName())); //$NON-NLS-1$ //$NON-NLS-2$
IStructuredSelection sel = (IStructuredSelection) selection;
Object selObj = sel.getFirstElement();
if (selObj instanceof Project)
setSelectedProject(((Project) selObj).getObjectId());
else if (selObj instanceof ProjectID)
setSelectedProject((ProjectID) selObj);
else
throw new IllegalArgumentException("selection.getFirstElement() is neither null, nor an instanceof " + Project.class.getName()+ " or " + ProjectID.class.getName()+ "! It is an instance of " + (selObj == null ? null : selObj.getClass().getName())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void setSelectedProject(ProjectID projectID) {
int idx = -1;
if (projectID != null){
int i = 0;
for (Project project : projectList) {
if (project.getProjectID() == projectID.projectID
&& project.getOrganisationID().equals(projectID.organisationID)) {
idx = i;
break;
}
++i;
}
}
if (idx < 0) {
projectCombo.deselectAll();
selectedProject = null;
} else {
projectCombo.select(idx);
selectedProject = projectList.get(idx);
}
fireSelectionChangedEvent();
}
public Project getSelectedProject() {
return selectedProject;
}
public void addProject(Project project, int index) {
projectList.add(index, project);
projectCombo.add(null, project.getName().getText(), index);
}
public XCombo getProjectCombo() {
return projectCombo;
}
@Override
public boolean setFocus() {
return projectCombo.setFocus();
}
}