package org.lttpp.eemory.util; import java.io.File; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.SimpleContentProposalProvider; import org.eclipse.jface.fieldassist.TextContentAdapter; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.handlers.HandlerUtil; import org.lttpp.eemory.Constants; import org.lttpp.eemory.Messages; import org.lttpp.eemory.enml.FontStyle; import org.lttpp.eemory.enml.StyleText; import org.lttpp.eemory.exception.NoDataFoundException; import org.lttpp.eemory.ui.ConfigContentProposalProvider; import org.lttpp.eemory.ui.ConfigTextContentAdapter; public class EclipseUtil { public static List<File> getSelectedFiles(final ExecutionEvent event) throws NoDataFoundException { ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection(); final List<File> files = ListUtil.list(); if (selection instanceof ITextSelection) { IEditorPart editorPart = HandlerUtil.getActiveEditor(event); if (editorPart == null) { throw new NoDataFoundException(Messages.Plugin_Error_NoFile); } IFile iFile = (IFile) editorPart.getEditorInput().getAdapter(IFile.class); if (iFile != null) { File file = iFile.getLocation().makeAbsolute().toFile(); files.add(file); } else { throw new NoDataFoundException(Messages.Plugin_Error_NoFile); } } else if (selection instanceof IStructuredSelection) { Iterator<?> iterator = ((StructuredSelection) selection).iterator(); while (iterator.hasNext()) { IFile iFile = null; Object object = iterator.next(); if (object instanceof IFile) { iFile = (IFile) object; } else if (object instanceof IAdaptable) { IAdaptable adapt = (IAdaptable) object; Object resource = adapt.getAdapter(IResource.class); if (resource instanceof IFile) { iFile = (IFile) resource; } } if (iFile != null) { File file = iFile.getLocation().makeAbsolute().toFile(); files.add(file); } else { throw new NoDataFoundException(Messages.Plugin_Error_NoFile); } } } return files; } public static List<List<StyleText>> getSelectedStyleText(final StyledText styledText) { Point selection = styledText.getSelection(); String selectionText = styledText.getSelectionText(); if (StringUtils.isEmpty(selectionText)) { return ListUtil.list(); } int size = 10; // 10 as default value in eclipse, will be overwritten by custom String face = StringUtils.EMPTY; FontStyle foreStyle = FontStyle.NORMAL; FontData[] fontDatas = styledText.getFont().getFontData(); // On Windows, only one FontData will be returned per font. On X however, a Font object may be composed of multiple X fonts. if (ArrayUtils.isNotEmpty(fontDatas)) { size = fontDatas[0].getHeight(); try { foreStyle = FontStyle.forNumber(fontDatas[0].getStyle()); } catch (IllegalArgumentException e) { foreStyle = FontStyle.NORMAL; } LogUtil.debug(Messages.bind(Messages.Plugin_Debug_Default_Font_Style, foreStyle)); List<String> fontFamily = ListUtil.list(); for (FontData f : fontDatas) { if (StringUtils.isNotBlank(f.getName())) { fontFamily.add(f.getName()); } } face = StringUtils.join(fontFamily, ConstantsUtil.COMMA); } List<List<StyleText>> list = ListUtil.list(); int start = 0; while (start >= 0) { int end = StringUtil.indexOfAny(selectionText, ArrayUtils.toArray(StringUtil.CRLF, StringUtils.CR, StringUtils.LF), start); String line = selectionText.substring(start, end < 0 ? selectionText.length() : end); int offset = selection.x + start; StyleRange[] ranges = styledText.getStyleRanges(offset, line.length()); List<StyleText> textRanges = parseLine(line, ranges, offset, face, String.valueOf(size), ObjectUtils.defaultIfNull(styledText.getForeground(), ColorUtil.SWT_COLOR_DEFAULT), foreStyle); list.add(textRanges); start = end < 0 ? end : end + (selectionText.startsWith(StringUtil.CRLF, end) ? StringUtil.CRLF.length() : selectionText.startsWith(StringUtils.CR, end) ? StringUtils.CR.length() : StringUtils.LF.length()); } return list; } // [PlainText][StyledText][PlainText] private static List<StyleText> parseLine(final String text, final StyleRange[] styleRanges, final int offset, final String face, final String size, final Color defaultForeColor, final FontStyle defaultForeStyle) { List<StyleText> textRanges = ListUtil.list(); if (ArrayUtils.isEmpty(styleRanges)) { StyleText textRange = new StyleText(text, face, ColorUtil.toHexCode(defaultForeColor.getRed(), defaultForeColor.getGreen(), defaultForeColor.getBlue()), size, defaultForeStyle); textRanges.add(textRange); return textRanges; } int count = 0; for (StyleRange styleRange : styleRanges) { int start = styleRange.start - offset; // [PlainText] - Part1 String part = text.substring(count, start); if (!StringUtils.isEmpty(part)) { StyleText textRange = new StyleText(part, face, ColorUtil.toHexCode(defaultForeColor.getRed(), defaultForeColor.getGreen(), defaultForeColor.getBlue()), size, defaultForeStyle); textRanges.add(textRange); count += part.length(); } // // [StyledText] part = text.substring(start, start + styleRange.length); Color foreground = styleRange.foreground != null ? styleRange.foreground : defaultForeColor; FontStyle fontStyle; try { FontStyle rangeStyle = FontStyle.forNumber(styleRange.fontStyle); LogUtil.debug(Messages.bind(Messages.Plugin_Debug_StyleRange_Font_Style, rangeStyle)); if (rangeStyle == FontStyle.NORMAL && defaultForeStyle != FontStyle.NORMAL) { fontStyle = defaultForeStyle; } else { fontStyle = rangeStyle; } } catch (IllegalArgumentException e) { fontStyle = defaultForeStyle; } LogUtil.debug(Messages.bind(Messages.Plugin_Debug_FinalConcluded_Font_Style, fontStyle)); StyleText textRange = new StyleText(part, face, ColorUtil.toHexCode(foreground.getRed(), foreground.getGreen(), foreground.getBlue()), size, fontStyle); textRanges.add(textRange); count += part.length(); } // [PlainText] - Part2 String part = text.substring(count); if (!StringUtils.isEmpty(part)) { StyleText textRange = new StyleText(part, face, ColorUtil.toHexCode(defaultForeColor.getRed(), defaultForeColor.getGreen(), defaultForeColor.getBlue()), size, defaultForeStyle); textRanges.add(textRange); } return textRanges; } public static boolean isBundleInstalled(final String bundleId) { return Platform.getBundle(bundleId) != null; } public static SimpleContentProposalProvider enableFilteringContentAssist(final Control control, final String[] proposals, final String byOperator) { Arrays.sort(proposals); ConfigContentProposalProvider contentProposalProvider = new ConfigContentProposalProvider(proposals); contentProposalProvider.setFiltering(true); contentProposalProvider.setByOperator(byOperator); ConfigTextContentAdapter textContentAdapter = new ConfigTextContentAdapter(); textContentAdapter.setByOperator(byOperator); new ContentProposalAdapter(control, textContentAdapter, contentProposalProvider, null, null); return contentProposalProvider; } public static SimpleContentProposalProvider enableFilteringContentAssist(final Control control, final String[] proposals) { Arrays.sort(proposals); SimpleContentProposalProvider contentProposalProvider = new SimpleContentProposalProvider(proposals); contentProposalProvider.setFiltering(true); TextContentAdapter textContentAdapter = new TextContentAdapter(); ContentProposalAdapter contentProposalAdapter = new ContentProposalAdapter(control, textContentAdapter, contentProposalProvider, null, null); contentProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); return contentProposalProvider; } public static void openErrorSyncly(final Shell shell, final String title, final String message) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { MessageDialog.openError(shell, title, message); } }); } public static String openCustomImageTypeWithCustomButtons(final Shell shell, final String title, final String message, final Image dialogImage, final LinkedHashMap<String, String> buttons) { return String.valueOf(openCustomImageTypeWithCustomButtons(shell, title, message, dialogImage, buttons, null, false).get(Constants.returnCode)); } public static Map<String, Object> openCustomImageTypeWithCustomButtons(final Shell shell, final String title, final String message, final Image dialogImage, final LinkedHashMap<String, String> buttons, final String toggleMessage, final boolean defaultToggleState) { MessageDialog dialog; if (StringUtils.isBlank(toggleMessage)) { dialog = new MessageDialog(shell, title, null, message, MessageDialog.NONE, buttons.values().toArray(new String[buttons.size()]), 0) { @Override public Image getImage() { return dialogImage; } }; } else { dialog = new MessageDialogWithToggle(shell, title, null, message, MessageDialog.NONE, buttons.values().toArray(new String[buttons.size()]), 0, toggleMessage, defaultToggleState) { @Override public Image getImage() { return dialogImage; } @Override protected void createButtonsForButtonBar(final Composite parent) { String[] buttonLabels = getButtonLabels(); Button[] buttons = new Button[buttonLabels.length]; int defaultButtonIndex = getDefaultButtonIndex(); for (int i = 0; i < buttonLabels.length; i++) { String label = buttonLabels[i]; Button button = createButton(parent, i, label, defaultButtonIndex == i); buttons[i] = button; } setButtons(buttons); } }; } dialog.open(); Map<String, Object> map = MapUtil.map(); map.put(Constants.returnCode, buttons.keySet().toArray()[dialog.getReturnCode()]); if (dialog instanceof MessageDialogWithToggle) { map.put(Constants.toggleState, ((MessageDialogWithToggle) dialog).getToggleState()); } return map; } public static String openInformationWithCustomButtons(final Shell shell, final String title, final String message, final LinkedHashMap<String, String> buttons) { MessageDialog dialog = new MessageDialog(shell, title, null, message, MessageDialog.INFORMATION, buttons.values().toArray(new String[buttons.size()]), 0); dialog.open(); return (String) buttons.keySet().toArray()[dialog.getReturnCode()]; } public static String openQuestionWithCustomButtons(final Shell shell, final String title, final String message, final LinkedHashMap<String, String> buttons) { MessageDialog dialog = new MessageDialog(shell, title, null, message, MessageDialog.QUESTION_WITH_CANCEL, buttons.values().toArray(new String[buttons.size()]), 0); dialog.open(); return (String) buttons.keySet().toArray()[dialog.getReturnCode()]; } public static String openWarningWithCustomButtons(final Shell shell, final String title, final String message, final LinkedHashMap<String, String> buttons) { MessageDialog dialog = new MessageDialog(shell, title, null, message, MessageDialog.WARNING, buttons.values().toArray(new String[buttons.size()]), 0); dialog.open(); return (String) buttons.keySet().toArray()[dialog.getReturnCode()]; } public static String openErrorWithCustomButtons(final Shell shell, final String title, final String message, final LinkedHashMap<String, String> buttons) { MessageDialog dialog = new MessageDialog(shell, title, null, message, MessageDialog.ERROR, buttons.values().toArray(new String[buttons.size()]), 0); dialog.open(); return (String) buttons.keySet().toArray()[dialog.getReturnCode()]; } }