package com.redhat.ceylon.eclipse.code.modulesearch;
import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getProjectDeclaredSourceModules;
import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getProjects;
import static com.redhat.ceylon.eclipse.java2ceylon.Java2CeylonProxies.modelJ2C;
import static com.redhat.ceylon.eclipse.java2ceylon.Java2CeylonProxies.importsJ2C;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.CEYLON_ADD;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.internal.ui.actions.CollapseAllAction;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.LocationAdapter;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Rectangle;
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.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import com.github.rjeschke.txtmark.Configuration;
import com.github.rjeschke.txtmark.Processor;
import com.redhat.ceylon.common.config.Repositories;
import com.redhat.ceylon.common.config.Repositories.Repository;
import com.redhat.ceylon.eclipse.code.editor.CeylonEditor;
import com.redhat.ceylon.eclipse.code.hover.CeylonBlockEmitter;
import com.redhat.ceylon.eclipse.code.hover.DocumentationHover;
import com.redhat.ceylon.eclipse.code.html.HTML;
import com.redhat.ceylon.eclipse.code.html.HTMLPrinter;
import com.redhat.ceylon.eclipse.code.navigator.SourceModuleNode;
import com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider;
import com.redhat.ceylon.eclipse.core.builder.CeylonNature;
import com.redhat.ceylon.eclipse.ui.CeylonPlugin;
import com.redhat.ceylon.eclipse.ui.CeylonResources;
import com.redhat.ceylon.eclipse.util.DocBrowser;
import com.redhat.ceylon.eclipse.util.EditorUtil;
import com.redhat.ceylon.eclipse.util.UnlinkedSpanEmitter;
import com.redhat.ceylon.ide.common.modulesearch.ModuleNode;
import com.redhat.ceylon.ide.common.modulesearch.ModuleVersionNode;
import com.redhat.ceylon.model.typechecker.model.Module;
import com.redhat.ceylon.model.typechecker.model.ModuleImport;
public class ModuleSearchViewPart extends ViewPart implements IShowInTarget {
private class RemoveSelectedAction extends Action implements ISelectionChangedListener {
public RemoveSelectedAction() {
super("Remove Selected");
setToolTipText("Remove Selected");
setEnabled(false);
ISharedImages workbenchImages = PlatformUI.getWorkbench().getSharedImages();
setImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_ELCL_REMOVE));
setHoverImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_ELCL_REMOVE));
moduleTreeViewer.addSelectionChangedListener(this);
}
@Override
public void run() {
List<?> selectedElements = ((IStructuredSelection) moduleTreeViewer.getSelection()).toList();
if (selectedElements != null) {
int lastSelectedModuleIndex = -1;
for (Object selectedElement : selectedElements) {
int selectedModuleIndex = moduleSearchManager.getModules().indexOf(selectedElement);
if (selectedModuleIndex != -1) {
lastSelectedModuleIndex = selectedModuleIndex;
}
}
if( lastSelectedModuleIndex != -1 ) {
moduleSearchManager.remove(selectedElements);
int nextSelectedModuleIndex = -1;
if (moduleSearchManager.getModules() != null) {
if (lastSelectedModuleIndex > moduleSearchManager.getModules().size() - 1) {
nextSelectedModuleIndex = moduleSearchManager.getModules().size() - 1;
} else {
nextSelectedModuleIndex = lastSelectedModuleIndex;
}
}
update(false);
if (nextSelectedModuleIndex != -1) {
moduleTreeViewer.setSelection(new StructuredSelection(moduleSearchManager.getModules().get(nextSelectedModuleIndex)));
}
}
}
}
@Override
public void selectionChanged(SelectionChangedEvent e) {
boolean isEnabled = false;
List<?> selectedElements = ((IStructuredSelection) e.getSelection()).toList();
if( selectedElements != null ) {
for( Object selectedElement : selectedElements ) {
if( selectedElement instanceof ModuleNode ) {
isEnabled = true;
break;
}
}
}
setEnabled(isEnabled);
}
}
private class RemoveAllAction extends Action {
public RemoveAllAction() {
super("Remove All");
setToolTipText("Remove All");
ISharedImages workbenchImages = PlatformUI.getWorkbench().getSharedImages();
setImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_ELCL_REMOVEALL));
setHoverImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_ELCL_REMOVEALL));
}
@Override
public void run() {
moduleSearchManager.clear();
update(true);
searchCombo.setText("");
}
}
private class ExpandAllAction extends Action {
public ExpandAllAction() {
super("Expand All");
setToolTipText("Expand All");
ImageDescriptor expandAllImage =
CeylonPlugin.imageRegistry()
.getDescriptor(CeylonResources.EXPAND_ALL);
setImageDescriptor(expandAllImage);
setHoverImageDescriptor(expandAllImage);
}
@Override
public void run() {
moduleTreeViewer.expandAll();
}
}
private class FetchNextAction extends Action {
public FetchNextAction() {
super("Fetch Next");
setToolTipText("Fetch Next");
setEnabled(false);
ImageDescriptor fetchNextImage =
CeylonPlugin.imageRegistry()
.getDescriptor(CeylonResources.PAGING);
setHoverImageDescriptor(fetchNextImage);
setImageDescriptor(fetchNextImage);
}
@Override
public void run() {
updateBeforeSearch(false);
moduleSearchManager.fetchNextModules();
}
}
private class AddModuleImportAction extends Action implements ISelectionChangedListener {
public AddModuleImportAction() {
super("Add Module Import...");
setToolTipText("Add Module Import...");
setEnabled(false);
ImageDescriptor image =
CeylonPlugin.imageRegistry()
.getDescriptor(CEYLON_ADD);
setImageDescriptor(image);
moduleTreeViewer.addSelectionChangedListener(this);
}
@Override
public void run() {
Object selectedElement = ((IStructuredSelection) moduleTreeViewer.getSelection()).getFirstElement();
ModuleVersionNode versionNode = null;
if (selectedElement instanceof ModuleNode) {
versionNode = ((ModuleNode) selectedElement).getLastVersion();
} else if (selectedElement instanceof ModuleVersionNode) {
versionNode = (ModuleVersionNode) selectedElement;
}
if (versionNode != null) {
addModuleImport(versionNode.getModule().getName(), versionNode.getVersion());
}
}
private void addModuleImport(String moduleName, String moduleVersion) {
Map<Module, IProject> moduleMap = new HashMap<Module, IProject>();
for (IProject project : getProjects()) {
for (Module module : getProjectDeclaredSourceModules(project)) {
moduleMap.put(module, project);
}
}
List<Module> targets = new ArrayList<Module>();
if (moduleMap.isEmpty()) {
MessageDialog.openInformation(parent.getShell(), "Information", "Can not add module import, because there are no ceylon modules in workspace.");
} else if (moduleMap.size() == 1) {
targets.addAll(moduleMap.keySet());
} else {
ElementListSelectionDialog dlg =
new ElementListSelectionDialog(parent.getShell(),
new CeylonLabelProvider());
dlg.setTitle("Select Module");
dlg.setMessage("Select module, where to add module import.");
dlg.setMultipleSelection(true);
dlg.setHelpAvailable(false);
dlg.setElements(moduleMap.keySet().toArray(new Module[] {}));
if (dlg.open() == Dialog.OK) {
Object[] results = dlg.getResult();
for (Object result : results) {
targets.add((Module) result);
}
}
}
if (!targets.isEmpty()) {
for (Module target : targets) {
boolean containsImport = false;
for (ModuleImport moduleImport : target.getImports()) {
if (moduleName.equals(moduleImport.getModule().getNameAsString())) {
containsImport = true;
break;
}
}
if( containsImport ) {
MessageDialog.openInformation(parent.getShell(), "Information", "Can not add module import, because module '" +
target.getNameAsString() + "' contains it already.");
} else {
importsJ2C().importUtil()
.addModuleImport(target, moduleName, moduleVersion);
}
}
}
}
@Override
public void selectionChanged(SelectionChangedEvent e) {
int selectionSize = ((IStructuredSelection) e.getSelection()).size();
setEnabled(selectionSize == 1);
}
}
private class ShowDocAction extends Action {
private static final String IS_CHECKED = "ModuleSearch.ShowDocAction.isChecked";
public ShowDocAction() {
super("Show/Hide Documentation", AS_CHECK_BOX);
setToolTipText("Show/Hide Documentation");
ImageDescriptor showDocImage =
CeylonPlugin.imageRegistry()
.getDescriptor(CeylonResources.SHOW_DOC);
setImageDescriptor(showDocImage);
setHoverImageDescriptor(showDocImage);
setChecked(CeylonPlugin.getPreferences().getBoolean(IS_CHECKED));
run();
}
@Override
public void run() {
if (isChecked()) {
sashForm.setMaximizedControl(null);
} else {
sashForm.setMaximizedControl(moduleTreeViewer.getTree());
}
CeylonPlugin.getPreferences().setValue(IS_CHECKED, isChecked());
}
}
private class ShowRepositoriesAction extends Action {
public ShowRepositoriesAction() {
super("Show Repositories");
setToolTipText("Show Repositories");
ImageDescriptor showRepositoriesImage =
CeylonPlugin.imageRegistry()
.getDescriptor(CeylonResources.REPOSITORIES);
setImageDescriptor(showRepositoriesImage);
setHoverImageDescriptor(showRepositoriesImage);
}
@Override
public void run() {
ShowRepositoriesDialog showRepositoriesDialog = new ShowRepositoriesDialog();
showRepositoriesDialog.open();
}
}
private class ShowRepositoriesDialog extends TitleAreaDialog {
public ShowRepositoriesDialog() {
super(parent.getShell());
}
@Override
public void create() {
setHelpAvailable(false);
super.create();
setTitle("Ceylon repositories");
setMessage("The following repositories will be searched.");
}
@Override
protected Control createDialogArea(Composite parent) {
Repositories repositories;
IProject selectedProject = getSelectedProject();
if( selectedProject != null ) {
repositories = modelJ2C().ceylonModel().getProject(selectedProject).getConfiguration().getRepositories();
} else {
repositories = Repositories.get();
}
List<Repository> repositoryList = new ArrayList<Repository>();
Collections.addAll(repositoryList, repositories.getLocalLookupRepositories());
Collections.addAll(repositoryList, repositories.getGlobalLookupRepositories());
Collections.addAll(repositoryList, repositories.getRemoteLookupRepositories());
Collections.addAll(repositoryList, repositories.getOtherLookupRepositories());
parent.setLayout(new GridLayout(1, false));
TableViewer tableViewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
TableViewerColumn colName = new TableViewerColumn(tableViewer, SWT.NONE);
colName.getColumn().setWidth(200);
colName.getColumn().setText("Name");
colName.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
return ((Repository)element).getName();
}
});
TableViewerColumn colUrl = new TableViewerColumn(tableViewer, SWT.NONE);
colUrl.getColumn().setWidth(200);
colUrl.getColumn().setText("URL");
colUrl.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
return ((Repository)element).getUrl();
}
});
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
tableViewer.setInput(repositoryList);
tableViewer.getTable().setHeaderVisible(true);
tableViewer.getTable().setLinesVisible(true);
tableViewer.getTable().setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).create());
return parent;
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
}
}
private ModuleSearchManager moduleSearchManager = new ModuleSearchManager(this);
private RemoveSelectedAction removeSelectedAction;
private RemoveAllAction removeAllAction;
private ExpandAllAction expandAllAction;
private CollapseAllAction collapseAllAction;
private FetchNextAction fetchNextAction;
private AddModuleImportAction addModuleImportAction;
private ShowDocAction showDocAction;
private ShowRepositoriesAction showRepositoriesAction;
private Composite parent;
private Combo searchCombo;
private Button searchButton;
private Combo projectCombo;
private Link searchInfo;
private SashForm sashForm;
private TreeViewer moduleTreeViewer;
private DocBrowser docBrowser;
private List<String> queryHistory = new ArrayList<String>();
private Map<String, IProject> projectMap = new ConcurrentHashMap<String, IProject>();
private IResourceChangeListener updateProjectComboListener;
@Override
public void setFocus() {
searchCombo.setFocus();
}
@Override
public void createPartControl(Composite parent) {
this.parent = parent;
this.parent.setLayout(new GridLayout(2, false));
initSearchCombo();
initSearchButton();
initProjectCombo();
initSearchInfo();
initSashForm();
initModuleTreeViewer();
initDocBrowser();
initActions();
}
private void initSearchCombo() {
searchCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER);
searchCombo.setVisibleItemCount(10);
GridData gd = GridDataFactory.swtDefaults().span(1, 1).hint(250, SWT.DEFAULT).create();
searchCombo.setLayoutData(gd);
searchCombo.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
updateBeforeSearch(true);
moduleSearchManager.searchModules(searchCombo.getText());
}
}
});
}
private void initSearchButton() {
searchButton = new Button(parent, SWT.PUSH);
searchButton.setText("&Search");
searchButton.setLayoutData(GridDataFactory.swtDefaults().hint(120, SWT.DEFAULT).create());
searchButton.setAlignment(SWT.CENTER);
searchButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
updateBeforeSearch(true);
moduleSearchManager.searchModules(searchCombo.getText());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
}
private void initProjectCombo() {
Label projectLabel = new Label(parent, SWT.RIGHT | SWT.WRAP);
projectLabel.setText("Search in repositories of project");
GridData gd = GridDataFactory.swtDefaults().align(SWT.END, SWT.CENTER).create();
projectLabel.setLayoutData(gd);
projectCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);
projectCombo.setLayoutData(GridDataFactory.swtDefaults().hint(120, SWT.DEFAULT).create());
updateProjectCombo();
updateProjectComboListener = new IResourceChangeListener() {
@Override
public void resourceChanged(IResourceChangeEvent event) {
if (event.getResource() == null || event.getResource() instanceof IProject) {
updateProjectComboAsync();
}
}
};
ResourcesPlugin.getWorkspace().addResourceChangeListener(updateProjectComboListener);
}
private void initSearchInfo() {
searchInfo = new Link(parent, 0);
searchInfo.setLayoutData(GridDataFactory.swtDefaults().span(3, 1).create());
searchInfo.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
updateBeforeSearch(false);
moduleSearchManager.fetchNextModules();
}
});
updateInfoLabel();
}
private void initSashForm() {
sashForm = new SashForm(parent, SWT.HORIZONTAL | SWT.SMOOTH);
sashForm.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).span(4, 1).create());
sashForm.addControlListener(new ControlListener() {
boolean reentrant;
@Override
public void controlResized(ControlEvent e) {
if (reentrant) return;
reentrant = true;
try {
Rectangle bounds = sashForm.getBounds();
// IToolBarManager toolBarManager =
// getViewSite().getActionBars().getToolBarManager();
if (bounds.height>bounds.width) {
if (sashForm.getOrientation()!=SWT.VERTICAL) {
sashForm.setOrientation(SWT.VERTICAL);
// createMainToolBar(toolBarManager);
// toolBarManager.update(false);
// viewForm.setTopLeft(null);
}
}
else {
if (sashForm.getOrientation()!=SWT.HORIZONTAL) {
sashForm.setOrientation(SWT.HORIZONTAL);
// toolBarManager.removeAll();
// toolBarManager.update(false);
// ToolBarManager tbm = new ToolBarManager(SWT.NONE);
// createMainToolBar(tbm);
// tbm.createControl(viewForm);
// viewForm.setTopLeft(tbm.getControl());
}
}
getViewSite().getActionBars().updateActionBars();
}
finally {
reentrant = false;
}
}
@Override
public void controlMoved(ControlEvent e) {}
});
}
private void initModuleTreeViewer() {
moduleTreeViewer = new TreeViewer(sashForm, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
moduleTreeViewer.setContentProvider(new ModuleSearchViewContentProvider());
moduleTreeViewer.setLabelProvider(new ModuleSearchViewLabelProvider());
moduleTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent e) {
if( e.getSelection() instanceof IStructuredSelection ) {
Object selectedElement = ((IStructuredSelection)e.getSelection()).getFirstElement();
if( selectedElement != null ) {
boolean isExpanded = moduleTreeViewer.getExpandedState(selectedElement);
moduleTreeViewer.setExpandedState(selectedElement, !isExpanded);
}
}
}
});
}
private void initDocBrowser() {
docBrowser = new DocBrowser(sashForm, SWT.NONE);
docBrowser.setMenu(new Menu(parent.getShell(), SWT.NONE));
docBrowser.addLocationListener(new LocationAdapter() {
@Override
public void changing(LocationEvent e) {
if (e.location.startsWith("module:")) {
e.doit = false;
String[] split = e.location.split(":");
String moduleName = split[1];
String moduleVersion = split[2];
moduleSearchManager.fetchDocumentation(moduleName, moduleVersion);
}
}
});
moduleTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent e) {
updateDoc();
}
});
updateDoc();
}
private void initActions() {
removeSelectedAction = new RemoveSelectedAction();
removeAllAction = new RemoveAllAction();
expandAllAction = new ExpandAllAction();
collapseAllAction = new CollapseAllAction(moduleTreeViewer);
fetchNextAction = new FetchNextAction();
addModuleImportAction = new AddModuleImportAction();
showDocAction = new ShowDocAction();
showRepositoriesAction = new ShowRepositoriesAction();
IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
toolBarManager.add(fetchNextAction);
toolBarManager.add(new Separator());
toolBarManager.add(removeSelectedAction);
toolBarManager.add(removeAllAction);
toolBarManager.add(new Separator());
toolBarManager.add(expandAllAction);
toolBarManager.add(collapseAllAction);
toolBarManager.add(new Separator());
toolBarManager.add(showDocAction);
toolBarManager.add(showRepositoriesAction);
MenuManager menuManager = new MenuManager();
menuManager.add(addModuleImportAction);
menuManager.add(new Separator());
menuManager.add(removeSelectedAction);
menuManager.add(removeAllAction);
menuManager.add(new Separator());
menuManager.add(expandAllAction);
menuManager.add(collapseAllAction);
Menu menu = menuManager.createContextMenu(moduleTreeViewer.getTree());
moduleTreeViewer.getTree().setMenu(menu);
}
public void update(boolean newModel) {
if (newModel) {
moduleTreeViewer.setInput(moduleSearchManager.getModules());
} else {
moduleTreeViewer.refresh();
}
updateInfoLabel();
updateEnabledState();
updateFocusAndSelection(newModel);
updateSearchComboHistory(newModel);
parent.setCursor(null);
}
private void updateInfoLabel() {
StringBuilder info = new StringBuilder();
if( moduleSearchManager.getModules() != null ) {
if (moduleSearchManager.getModules().isEmpty()) {
info.append("No module found");
} else {
info.append("Found ");
if (moduleSearchManager.canFetchNext()) {
info.append("first ");
}
info.append(moduleSearchManager.getModules().size());
if( moduleSearchManager.getModules().size() == 1 ) {
info.append(" module");
} else {
info.append(" modules");
}
}
/*if( !moduleSearchManager.getLastQuery().isEmpty() ) {
info.append(" for query '");
info.append(moduleSearchManager.getLastQuery());
info.append("'");
}*/
if (moduleSearchManager.canFetchNext()) {
info.append(", click here to <a>see more</a> results");
}
} else {
info.append("Click 'Search' to find modules by module name");
}
if (info.length() != 0 && info.charAt(info.length() - 1) != '.') {
info.append(".");
}
searchInfo.setText(info.toString());
searchInfo.pack();
}
private void updateEnabledState() {
searchCombo.setEnabled(true);
searchButton.setEnabled(true);
if (moduleSearchManager.canFetchNext()) {
fetchNextAction.setEnabled(true);
} else {
fetchNextAction.setEnabled(false);
}
}
private void updateFocusAndSelection(boolean newModel) {
if (moduleSearchManager.getModules() == null || moduleSearchManager.getModules().isEmpty()) {
searchCombo.setFocus();
} else {
moduleTreeViewer.setSelection(new StructuredSelection(moduleSearchManager.getModules().get(0)));
moduleTreeViewer.getTree().setFocus();
}
}
private void updateSearchComboHistory(boolean newModel) {
String lastQuery = moduleSearchManager.getLastQuery();
if (newModel && lastQuery != null && !lastQuery.isEmpty() ) {
if (queryHistory.contains(lastQuery)) {
queryHistory.remove(lastQuery);
}
queryHistory.add(0, lastQuery);
searchCombo.setItems(queryHistory.toArray(new String[queryHistory.size()]));
searchCombo.setText(lastQuery);
}
}
private void updateBeforeSearch(boolean newModel) {
searchInfo.setText("Searching module repositories...");
searchInfo.pack();
searchButton.setEnabled(false);
if( newModel ) {
moduleTreeViewer.setInput(null);
}
parent.setCursor(Display.getDefault().getSystemCursor(SWT.CURSOR_WAIT));
}
public void updateDoc() {
ModuleVersionNode versionNode = null;
Object selectedElement = ((IStructuredSelection) moduleTreeViewer.getSelection()).getFirstElement();
if (selectedElement instanceof ModuleNode) {
versionNode = ((ModuleNode) selectedElement).getLastVersion();
} else if (selectedElement instanceof ModuleVersionNode) {
versionNode = (ModuleVersionNode) selectedElement;
}
docBrowser.setText(getModuleDoc(versionNode));
}
public static String getModuleDoc(ModuleVersionNode versionNode) {
StringBuilder docBuilder = new StringBuilder();
HTMLPrinter.insertPageProlog(docBuilder, 0, HTML.getStyleSheet());
if (versionNode != null) {
HTML.addImageAndLabel(docBuilder, null,
HTML.fileUrl("jar_l_obj.gif").toExternalForm(),
16, 16,
"<tt><span style='font-size:"+ DocumentationHover.largerSize + "%'>" +
HTML.highlightLine(description(versionNode)) +
"</span></tt>",
20, 4);
// docBuilder.append("<br/>");
if (versionNode.isFilled()) {
if( versionNode.getDoc() == null || versionNode.getDoc().isEmpty() ) {
docBuilder.append("<p>");
docBuilder.append("<i>Module does not have documentation.</i>");
docBuilder.append("</p>");
} else {
docBuilder.append(markdown(versionNode.getDoc()));
}
if (versionNode.getAuthors() != null && !versionNode.getAuthors().isEmpty()) {
docBuilder.append("<p><i>By: ");
docBuilder.append(versionNode.getAuthorsCommaSeparated());
docBuilder.append("</i></p>");
}
if( versionNode.getLicense() != null && !versionNode.getLicense().isEmpty() ) {
docBuilder.append("<p><i>License: ");
docBuilder.append(versionNode.getLicense());
docBuilder.append("</i></p>");
}
} else {
docBuilder.append("<p><i>Click here to <a href='module:");
docBuilder.append(versionNode.getModule().getName() + ":" + versionNode.getVersion());
docBuilder.append("'>fetch documentation</a></i> for this module version.");
docBuilder.append("</p>");
}
}
HTMLPrinter.addPageEpilog(docBuilder);
return docBuilder.toString();
}
public static String description(ModuleVersionNode versionNode) {
return "module " + versionNode.getModule().getName() +
" \"" + versionNode.getVersion() + "\"";
}
private void updateProjectComboAsync() {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (!projectCombo.isDisposed()) {
updateProjectCombo();
}
}
});
}
private void updateProjectCombo() {
projectMap.clear();
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
if (projects != null) {
for (IProject project : projects) {
if (project.isOpen() && CeylonNature.isEnabled(project)) {
projectMap.put(project.getName(), project);
}
}
}
List<String> projectNames = new ArrayList<String>(projectMap.keySet());
projectNames.add("");
Collections.sort(projectNames);
int selectedIndex = projectCombo.getSelectionIndex();
String selectedProjectName = selectedIndex != -1 ? projectCombo.getItem(selectedIndex) : "";
projectCombo.setItems(projectNames.toArray(new String[]{}));
if (projectNames.contains(selectedProjectName)) {
projectCombo.select(projectNames.indexOf(selectedProjectName));
} else {
projectCombo.select(0);
}
}
public IProject getSelectedProject() {
IProject selectedProject = null;
int selectionIndex = projectCombo.getSelectionIndex();
if (selectionIndex != -1) {
String selectedProjectName = projectCombo.getItem(selectionIndex);
selectedProject = projectMap.get(selectedProjectName);
}
return selectedProject;
}
private static String markdown(String text) {
if( text == null || text.length() == 0 ) {
return text;
}
Configuration config = Configuration.builder().
forceExtentedProfile().
setCodeBlockEmitter(new CeylonBlockEmitter()).
setSpecialLinkEmitter(new UnlinkedSpanEmitter()).
build();
return Processor.process(text, config);
}
@Override
public void dispose() {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(updateProjectComboListener);
}
public void setProject(IProject project) {
if (project!=null) {
int index = Arrays.asList(projectCombo.getItems())
.indexOf(project.getName());
projectCombo.select(index);
updateBeforeSearch(true);
moduleSearchManager.searchModules(searchCombo.getText());
}
}
@Override
public boolean show(ShowInContext context) {
ISelection selection = context.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) selection;
Object first = ss.getFirstElement();
if (first instanceof IProject) {
setProject((IProject) first);
return true;
}
else if (first instanceof IJavaElement) {
setProject(((IJavaElement) first).getJavaProject().getProject());
return true;
}
else if (first instanceof IResource) {
setProject(((IResource) first).getProject());
return true;
}
else if (first instanceof SourceModuleNode) {
SourceModuleNode mod = (SourceModuleNode) first;
setProject(mod.getProject());
return true;
}
}
else {
IEditorPart editor = EditorUtil.getCurrentEditor();
if (editor instanceof CeylonEditor) {
setProject(((CeylonEditor) editor).getParseController().getProject());
return true;
}
}
return false;
}
}