/*******************************************************************************
* Copyright (c) 2013, 2015 Cloud Bees, Inc.
* All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cloud Bees, Inc. - initial API and implementation
*******************************************************************************/
package com.cloudbees.eclipse.ui.views;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.part.ViewPart;
import com.cloudbees.eclipse.core.CBRemoteChangeAdapter;
import com.cloudbees.eclipse.core.CBRemoteChangeListener;
import com.cloudbees.eclipse.core.CloudBeesCorePlugin;
import com.cloudbees.eclipse.core.CloudBeesException;
import com.cloudbees.eclipse.core.GrandCentralService;
import com.cloudbees.eclipse.ui.AuthStatus;
import com.cloudbees.eclipse.ui.CloudBeesUIPlugin;
import com.cloudbees.eclipse.ui.internal.ActiveAccountContributionItem;
import com.cloudbees.eclipse.ui.views.CBTreeSeparator.SeparatorLocation;
public class CBTreeView extends ViewPart {
public static final String ID = "com.cloudbees.eclipse.ui.views.CBTreeView";
private TreeViewer viewer;
private ICBTreeProvider[] providers;
private CBRemoteChangeListener changeListener = new CBRemoteChangeAdapter() {
public void activeAccountChanged(final String email, final String newAccountName) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
updateCD(email, newAccountName);
}
});
}
};
private IMenuListener statusUpdateListener = new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
IActionBars bars = getViewSite().getActionBars();
IMenuManager pullDownMenu = bars.getMenuManager();
IContributionItem[] items = pullDownMenu.getItems();
for (int i = 0; i < items.length; i++) {
IContributionItem it = items[i];
if (it instanceof ActionContributionItem) {
ActionContributionItem ita = (ActionContributionItem) it;
//System.out.println("Action: "+ita.getAction());
ita.update();
}
//System.out.println("IT: "+it);
}
/*pullDownMenu.markDirty();
pullDownMenu.updateAll(true);*/
//System.out.println("About to show a menu!");
}
};
class NameSorter extends ViewerSorter {
@Override
public int compare(final Viewer viewer, final Object e1, final Object e2) {
if (e1 instanceof ICBGroup && e2 instanceof ICBGroup) {
return ((ICBGroup) e1).getOrder() - ((ICBGroup) e2).getOrder();
}
return super.compare(viewer, e1, e2);
}
}
public CBTreeView() {
super();
GrandCentralService gcs;
try {
gcs = CloudBeesCorePlugin.getDefault().getGrandCentralService();
String accountName = gcs.getActiveAccountName();
String email = gcs.getEmail();
updateCD(email, accountName);
} catch (CloudBeesException e1) {
//Ignore for now
}
IExtension[] extensions = Platform.getExtensionRegistry()
.getExtensionPoint(CloudBeesUIPlugin.PLUGIN_ID, "cbTreeProvider").getExtensions();
List<ICBTreeProvider> prs = new ArrayList<ICBTreeProvider>();
for (IExtension extension : extensions) {
for (IConfigurationElement element : extension.getConfigurationElements()) {
try {
Object provider = element.createExecutableExtension("class");
if (provider instanceof ICBTreeProvider) {
prs.add((ICBTreeProvider) provider);
}
} catch (Exception e) {
e.printStackTrace(); // FIXME
}
}
}
this.providers = prs.toArray(new ICBTreeProvider[prs.size()]);
Arrays.sort(this.providers, new Comparator<ICBTreeProvider>() {
public int compare(ICBTreeProvider o1, ICBTreeProvider o2) {
return o1.getId().compareTo(o2.getId());
}});
CloudBeesUIPlugin.getDefault().addCBRemoteChangeListener(changeListener);
}
public ICBTreeProvider[] getProviders() {
return this.providers;
}
@Override
public void createPartControl(final Composite parent) {
this.viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
this.viewer.setContentProvider(new CBContentProvider(this));
this.viewer.setLabelProvider(new CBLabelProvider(this));
this.viewer.setSorter(new NameSorter());
this.viewer.setInput(getViewSite());
for (ICBTreeProvider provider : this.providers) {
provider.setViewer(this.viewer);
getSite().setSelectionProvider(this.viewer);
}
this.viewer.addOpenListener(new IOpenListener() {
public void open(final OpenEvent event) {
ISelection sel = event.getSelection();
if (sel instanceof TreeSelection) {
Object el = ((TreeSelection) sel).getFirstElement();
//boolean opened = false;
for (ICBTreeProvider provider : CBTreeView.this.providers) {
//opened |= ;
if (provider.open(el)) {
break;
}
}
/* if (!opened) {
boolean exp = CBTreeView.this.viewer.getExpandedState(el);
if (exp) {
CBTreeView.this.viewer.collapseToLevel(el, 1);
} else {
CBTreeView.this.viewer.expandToLevel(el, 1);
}
}
*/ }
}
});
MenuManager popupMenu = new MenuManager();
popupMenu.setRemoveAllWhenShown(true);
popupMenu.addMenuListener(new IMenuListener() {
public void menuAboutToShow(final IMenuManager mgr) {
}
});
IActionBars bars = getViewSite().getActionBars();
IMenuManager pullDownMenu = bars.getMenuManager();
IToolBarManager toolbarMenu = bars.getToolBarManager();
for (ICBTreeProvider provider : this.providers) {
for (CBTreeContributor contributor : provider.getContributors()) {
if (contributor.isPopup()) {
contributor.contributeTo(popupMenu);
}
if (contributor.isPullDown()) {
contributor.contributeTo(pullDownMenu);
}
if (contributor.isToolbar()) {
contributor.contributeTo(toolbarMenu);
}
}
}
pullDownMenu.add(new CBTreeSeparator(SeparatorLocation.PULL_DOWN));
pullDownMenu.add(new ActiveAccountContributionItem(true));
pullDownMenu.addMenuListener(statusUpdateListener);
//pullDownMenu.add(this.configureAccountAction);
Menu menu = popupMenu.createContextMenu(this.viewer.getTree());
this.viewer.getTree().setMenu(menu);
getSite().registerContextMenu(popupMenu, this.viewer);
//Not loading here anymore as there is now improved loading workflow
//CloudBeesUIPlugin.getDefault().reloadAllJenkins(false);
}
@Override
public void setFocus() {
this.viewer.getControl().setFocus();
}
@Override
public void dispose() {
for (ICBTreeProvider provider : this.providers) {
provider.dispose();
}
this.providers = null;
CloudBeesUIPlugin.getDefault().removeCBRemoteChangeListener(changeListener);
super.dispose();
}
private void updateCD(String email, String newAccountName) {
if (email==null) {
CBTreeView.this.setContentDescription("Account not configured!");
return;
}
if (newAccountName!=null && newAccountName.length()>0) {
CBTreeView.this.setContentDescription(" "+email+"; "+newAccountName);
return;
}
String post="";
if (CloudBeesUIPlugin.getDefault().getAuthStatus()!=AuthStatus.OK) {
post=" (user not authenticated!)";
}
CBTreeView.this.setContentDescription(" "+email+post);
}
}