quickdoc reformat, rearrange, drop final

This commit is contained in:
Gregory.Shrago
2018-06-29 02:54:19 +03:00
parent aba4573d3d
commit 85c58af2c6
2 changed files with 292 additions and 264 deletions
@@ -96,15 +96,14 @@ import java.util.List;
public class DocumentationComponent extends JPanel implements Disposable, DataProvider {
private static final Logger LOG = Logger.getInstance(DocumentationComponent.class);
private static final String DOCUMENTATION_TOPIC_ID = "reference.toolWindows.Documentation";
private static final Color DOCUMENTATION_COLOR = new JBColor(new Color(0xf7f7f7), new Color(0x46484a));
static final JBColor BORDER_COLOR = new JBColor(new Color(0xadadad), new Color(0x616366));
private static final JBColor BORDER_COLOR = new JBColor(new Color(0xadadad), new Color(0x616366));
public static final ColorKey COLOR_KEY = ColorKey.createColorKey("DOCUMENTATION_COLOR", DOCUMENTATION_COLOR);
public static final Color SECTION_COLOR = Gray.get(0x90);
private static final Highlighter.HighlightPainter LINK_HIGHLIGHTER = new LinkHighlighter();
@NonNls private static final String DOCUMENTATION_TOPIC_ID = "reference.toolWindows.Documentation";
private static final int PREFERRED_HEIGHT_MAX_EM = 10;
private static final JBDimension MAX_DEFAULT = new JBDimension(650, 500);
@@ -132,81 +131,13 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private final MyDictionary<String, Image> myImageProvider = new MyDictionary<String, Image>() {
@Override
public Image get(Object key) {
if (myManager == null || key == null) return null;
PsiElement element = getElement();
if (element == null) return null;
URL url = (URL)key;
Image inMemory = myManager.getElementImage(element, url.toExternalForm());
if (inMemory != null) {
return inMemory;
}
Url parsedUrl = Urls.parseEncoded(url.toExternalForm());
BuiltInServerManager builtInServerManager = BuiltInServerManager.getInstance();
if (parsedUrl != null && builtInServerManager.isOnBuiltInWebServer(parsedUrl)) {
try {
url = new URL(builtInServerManager.addAuthToken(parsedUrl).toExternalForm());
}
catch (MalformedURLException e) {
LOG.warn(e);
}
}
Image image = ImageLoader.loadFromUrl(url);
return image != null ? ImageUtil.toBufferedImage(image) : Toolkit.getDefaultToolkit().createImage(url);
return getImageByKeyImpl(key);
}
};
private Runnable myToolwindowCallback;
private final ActionButton myCorner;
public AnAction[] getActions() {
return myToolBar.getActions().stream().filter((action -> !(action instanceof Separator))).toArray(AnAction[]::new);
}
public AnAction getFontSizeAction() {
return new MyShowSettingsAction();
}
public void removeCornerMenu() {
myCorner.setVisible(false);
}
public void setToolwindowCallback(Runnable callback) {
myToolwindowCallback = callback;
}
public void showExternalDoc() {
final DataContext dataContext = DataManager.getInstance().getDataContext(this);
myExternalDocAction.actionPerformed(AnActionEvent.createFromDataContext(ActionPlaces.UNKNOWN, null, dataContext));
}
private static class Context {
final SmartPsiElementPointer element;
final String text;
final String externalUrl;
final DocumentationProvider provider;
final Rectangle viewRect;
final int highlightedLink;
Context(SmartPsiElementPointer element,
String text,
String externalUrl,
DocumentationProvider provider,
Rectangle viewRect,
int highlightedLink) {
this.element = element;
this.text = text;
this.externalUrl = externalUrl;
this.provider = provider;
this.viewRect = viewRect;
this.highlightedLink = highlightedLink;
}
@NotNull
Context withText(@NotNull String text) {
return new Context(element, text, externalUrl, provider, viewRect, highlightedLink);
}
}
private final MyScrollPane myScrollPane;
private final JEditorPane myEditorPane;
private String myText; // myEditorPane.getText() surprisingly crashes.., let's cache the text
@@ -219,34 +150,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private final Map<KeyStroke, ActionListener> myKeyboardActions = new HashMap<>();
@Override
public boolean requestFocusInWindow() {
// With a screen reader active, set the focus directly to the editor because
// it makes it easier for users to read/navigate the documentation contents.
if (ScreenReader.isActive()) {
return myEditorPane.requestFocusInWindow();
}
else {
return myScrollPane.requestFocusInWindow();
}
}
@Override
public void requestFocus() {
// With a screen reader active, set the focus directly to the editor because
// it makes it easier for users to read/navigate the documentation contents.
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> {
if (ScreenReader.isActive()) {
IdeFocusManager.getGlobalInstance().requestFocus(myEditorPane, true);
}
else {
IdeFocusManager.getGlobalInstance().requestFocus(myScrollPane, true);
}
});
}
public static DocumentationComponent createAndFetch(Project project, PsiElement element, Disposable disposable) {
@NotNull
public static DocumentationComponent createAndFetch(@NotNull Project project,
@NotNull PsiElement element,
@NotNull Disposable disposable) {
DocumentationManager manager = DocumentationManager.getInstance(project);
DocumentationComponent component = new DocumentationComponent(manager);
Disposer.register(disposable, component);
@@ -254,13 +161,12 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
return component;
}
public DocumentationComponent(final DocumentationManager manager) {
public DocumentationComponent(DocumentationManager manager) {
myManager = manager;
myIsEmpty = true;
myIsShown = false;
myEditorPane = new JEditorPane(UIUtil.HTML_MIME, "") {
private Point initialClick;
{
enableEvents(AWTEvent.KEY_EVENT_MASK);
}
@@ -277,6 +183,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
super.processKeyEvent(e);
}
Point initialClick;
@Override
protected void processMouseEvent(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_PRESSED && myHint != null) {
@@ -357,10 +265,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
@Override
public View create(Element elem) {
if ("icon".equals(elem.getName())) {
final Object src = elem.getAttributes().getAttribute(HTML.Attribute.SRC);
Object src = elem.getAttributes().getAttribute(HTML.Attribute.SRC);
Icon icon = src != null ? IconLoader.findIcon((String)src, false) : null;
if (icon == null) {
final ModuleType id = ModuleTypeManager.getInstance().findByID((String)src);
ModuleType id = ModuleTypeManager.getInstance().findByID((String)src);
if (id != null) icon = id.getIcon();
}
if (icon != null) {
@@ -400,7 +308,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
@Override
public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
Rectangle alloc = (Rectangle) a;
Rectangle alloc = (Rectangle)a;
if (x < alloc.x + (alloc.width / 2)) {
bias[0] = Position.Bias.Forward;
return getStartOffset();
@@ -422,7 +330,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myScrollPane = new MyScrollPane();
myScrollPane.putClientProperty(DataManager.CLIENT_PROPERTY_DATA_PROVIDER, helpDataProvider);
final FocusListener focusAdapter = new FocusAdapter() {
FocusListener focusAdapter = new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
Component previouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(manager.getProject(getElement()));
@@ -448,9 +356,9 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
setOpaque(true);
myScrollPane.setBorder(JBUI.Borders.empty());
final DefaultActionGroup actions = new DefaultActionGroup();
final BackAction back = new BackAction();
final ForwardAction forward = new ForwardAction();
DefaultActionGroup actions = new DefaultActionGroup();
BackAction back = new BackAction();
ForwardAction forward = new ForwardAction();
EditDocumentationSourceAction edit = new EditDocumentationSourceAction();
myExternalDocAction = new ExternalDocAction();
actions.add(back);
@@ -469,18 +377,18 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
forward.registerCustomShortcutSet(forwardShortcutSet, this);
// mouse actions are checked only for exact component over which click was performed,
// so we need to register shortcuts for myEditorPane as well
back.registerCustomShortcutSet(backShortcutSet, myEditorPane);
back.registerCustomShortcutSet(backShortcutSet, myEditorPane);
forward.registerCustomShortcutSet(forwardShortcutSet, myEditorPane);
}
catch (InvalidDataException e) {
LOG.error(e);
}
myExternalDocAction.registerCustomShortcutSet(CustomShortcutSet.fromString("UP"), this);
myExternalDocAction.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_EXTERNAL_JAVADOC).getShortcutSet(), myEditorPane);
edit.registerCustomShortcutSet(CommonShortcuts.getEditSource(), this);
ActionPopupMenu contextMenu = ((ActionManagerImpl)ActionManager.getInstance()).createActionPopupMenu(ActionPlaces.JAVADOC_TOOLBAR, actions,
new MenuItemPresentationFactory(true));
ActionPopupMenu contextMenu = ((ActionManagerImpl)ActionManager.getInstance()).createActionPopupMenu(
ActionPlaces.JAVADOC_TOOLBAR, actions, new MenuItemPresentationFactory(true));
PopupHandler popupHandler = new PopupHandler() {
@Override
public void invokePopup(Component comp, int x, int y) {
@@ -499,7 +407,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
JLayeredPane layeredPane = new JBLayeredPane() {
@Override
public void doLayout() {
final Rectangle r = getBounds();
Rectangle r = getBounds();
for (Component component : getComponents()) {
if (component instanceof JScrollPane) {
component.setBounds(0, 0, r.width, r.height);
@@ -526,7 +434,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
layeredPane.add(myScrollPane);
layeredPane.setLayer(myScrollPane, 0);
final DefaultActionGroup gearActions = new MyGearActionGroup();
DefaultActionGroup gearActions = new MyGearActionGroup();
gearActions.add(new ShowAsToolwindowAction());
gearActions.add(new MyShowSettingsAction());
gearActions.add(new ShowToolbarAction());
@@ -553,7 +461,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myControlPanel.add(new MyShowSettingsButton(), BorderLayout.EAST);
myControlPanelVisible = false;
final HyperlinkListener hyperlinkListener = new HyperlinkListener() {
HyperlinkListener hyperlinkListener = new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent e) {
HyperlinkEvent.EventType type = e.getEventType();
@@ -572,7 +480,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
if (myHint != null) {
Disposer.register(myHint, this);
} else if (myManager.myToolWindow != null) {
}
else if (myManager.myToolWindow != null) {
Disposer.register(myManager.myToolWindow.getContentManager(), this);
}
@@ -581,14 +490,62 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
updateControlState();
}
public AnAction[] getActions() {
return myToolBar.getActions().stream().filter((action -> !(action instanceof Separator))).toArray(AnAction[]::new);
}
public AnAction getFontSizeAction() {
return new MyShowSettingsAction();
}
public void removeCornerMenu() {
myCorner.setVisible(false);
}
public void setToolwindowCallback(Runnable callback) {
myToolwindowCallback = callback;
}
public void showExternalDoc() {
DataContext dataContext = DataManager.getInstance().getDataContext(this);
myExternalDocAction.actionPerformed(AnActionEvent.createFromDataContext(ActionPlaces.UNKNOWN, null, dataContext));
}
@Override
public boolean requestFocusInWindow() {
// With a screen reader active, set the focus directly to the editor because
// it makes it easier for users to read/navigate the documentation contents.
if (ScreenReader.isActive()) {
return myEditorPane.requestFocusInWindow();
}
else {
return myScrollPane.requestFocusInWindow();
}
}
@Override
public void requestFocus() {
// With a screen reader active, set the focus directly to the editor because
// it makes it easier for users to read/navigate the documentation contents.
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> {
if (ScreenReader.isActive()) {
IdeFocusManager.getGlobalInstance().requestFocus(myEditorPane, true);
}
else {
IdeFocusManager.getGlobalInstance().requestFocus(myScrollPane, true);
}
});
}
private static void prepareCSS(HTMLEditorKit editorKit) {
Color borderColor = ColorUtil.mix(DOCUMENTATION_COLOR, BORDER_COLOR, 0.5);
String editorFontName = StringUtil.escapeQuotes(EditorColorsManager.getInstance().getGlobalScheme().getEditorFontName());
editorKit.getStyleSheet().addRule("code {font-family:\"" + editorFontName + "\"}");
editorKit.getStyleSheet().addRule("pre {font-family:\"" + editorFontName + "\"}");
editorKit.getStyleSheet().addRule(".pre {font-family:\"" + editorFontName + "\"}");
editorKit.getStyleSheet().addRule("html { padding-bottom: 5px; }");
editorKit.getStyleSheet().addRule("a { color: #" + ColorUtil.toHex(getLinkColor()) + "; text-decoration: none;}");
editorKit.getStyleSheet().addRule(".definition { padding: 3px 17px 1px 7px; border-bottom: thin solid #" + ColorUtil.toHex(ColorUtil.mix(DOCUMENTATION_COLOR, BORDER_COLOR, 0.5)) + "; }");
editorKit.getStyleSheet().addRule(".definition { padding: 3px 17px 1px 7px; border-bottom: thin solid #" + ColorUtil.toHex(borderColor) + "; }");
editorKit.getStyleSheet().addRule(".content { padding: 5px 16px 0 7px; max-width: 100% }");
editorKit.getStyleSheet().addRule(".bottom { padding: 3px 16px 0 7px; }");
editorKit.getStyleSheet().addRule(".bottom-no-content { padding: 5px 16px 0 7px; }");
@@ -616,7 +573,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
// Javadocs often contain &nbsp; symbols (non-breakable white space). We don't want to copy them as is and replace
// with raw white spaces. See IDEA-86633 for more details.
String selectedText = myEditorPane.getSelectedText();
return selectedText == null? null : selectedText.replace((char)160, ' ');
return selectedText == null ? null : selectedText.replace((char)160, ' ');
}
return null;
@@ -768,7 +725,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
pointer = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element);
}
setDataInternal(pointer, text, new Rectangle(0, 0), ref);
}
}
private void setDataInternal(@Nullable SmartPsiElementPointer element,
@NotNull String text,
@@ -779,7 +736,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
updateControlState();
setElement(element);
highlightLink(-1);
myEditorPane.setText(decorate(text));
@@ -794,10 +751,13 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myEditorPane.scrollRectToVisible(viewRect); // if ref is defined but is not found in document, this provides a default location
if (ref != null) {
myEditorPane.scrollToReference(ref);
} else if (ScreenReader.isActive()) {
}
else if (ScreenReader.isActive()) {
myEditorPane.setCaretPosition(0);
}});
}
});
}
private void showHint() {
Editor editor = myManager.getEditor();
Component popupAnchor = getPopupAnchor(editor);
@@ -820,7 +780,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
int height = preferredSize.height + (needsToolbar() ? myControlPanel.getPreferredSize().height : 0);
height = Math.min(MAX_DEFAULT.height, Math.max(MIN_DEFAULT.height, height));
hintSize = new Dimension(width, height);
} else {
}
else {
hintSize = DimensionService.getInstance().getSize(DocumentationManager.NEW_JAVADOC_LOCATION_AND_SIZE, myManager.myProject);
if (hintSize == null) {
hintSize = new Dimension(MIN_DEFAULT);
@@ -836,7 +797,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
// pin upper right corner (instead of default upper left)
location = new RelativePoint(popupAnchor, new Point(-hintSize.width - 5, 0)).getScreenPoint();
myHint.setLocation(location);
} else if (editor != null && editor.getComponent().isShowing()) {
}
else if (editor != null && editor.getComponent().isShowing()) {
// pin lower bound (instead of default upper)
Point preferredLocation = JBPopupFactory.getInstance().guessBestPopupLocation(editor).getScreenPoint();
preferredLocation.y -= editor.getLineHeight();
@@ -883,7 +845,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
// if documentation doesn't fit into screen, put it on the left hand side
if (x + Math.max(hintSize.width, maxWidth) > screenRectangle.width) {
point = new RelativePoint(popupAnchor, new Point(-hintSize.width - 5, 0));
} else {
}
else {
point = new RelativePoint(popupAnchor, new Point(lookupWidthAndGap, 0));
}
myHint.show(point);
@@ -892,14 +855,15 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
lookup.addLookupListener(new LookupAdapter() {
@Override
public void lookupCanceled(LookupEvent event) {
final AbstractPopup hint = myHint;
AbstractPopup hint = myHint;
if (hint != null && hint.canClose() && hint.isVisible()) {
hint.cancel();
}
}
});
}
} else if (editor != null && editor.getComponent().isShowing()) {
}
else if (editor != null && editor.getComponent().isShowing()) {
// let's try to fit at least of half of maximum size on the bottom
Point preferredLocation = JBPopupFactory.getInstance().guessBestPopupLocation(editor).getScreenPoint();
Rectangle preferred = new Rectangle(preferredLocation.x, preferredLocation.y, MAX_DEFAULT.width, MAX_DEFAULT.height / 2);
@@ -935,7 +899,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
if (lookup != null && lookup.getCurrentItem() != null && lookup.getComponent().isShowing()) {
return lookup.getComponent();
}
final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
JBPopup popup = PopupUtil.getPopupContainerFor(focusOwner);
if (popup != null) {
return popup.getContent();
@@ -944,10 +908,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private void registerSizeTracker() {
final AbstractPopup hint = myHint;
AbstractPopup hint = myHint;
if (hint == null) return;
final Window window = hint.getPopupWindow();
final ComponentAdapter listener = new ComponentAdapter() {
Window window = hint.getPopupWindow();
ComponentAdapter listener = new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
if (myResizing) {
@@ -962,9 +926,9 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private int definitionPreferredWidth() {
final TextUI ui = myEditorPane.getUI();
final View view = ui.getRootView(myEditorPane);
final View definition = findDefinition(view);
TextUI ui = myEditorPane.getUI();
View view = ui.getRootView(myEditorPane);
View definition = findDefinition(view);
return definition != null ? (int)definition.getPreferredSpan(View.X_AXIS) : -1;
}
@@ -973,7 +937,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
return view;
}
for (int i = 0; i < view.getViewCount(); i++) {
final View definition = findDefinition(view.getView(i));
View definition = findDefinition(view.getView(i));
if (definition != null) return definition;
}
return null;
@@ -990,12 +954,13 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
DocumentationMarkup.CONTENT_START +
text.substring(bodyStart) +
DocumentationMarkup.CONTENT_END;
} else {
}
else {
text = DocumentationMarkup.CONTENT_START + text + DocumentationMarkup.CONTENT_END;
}
hasContent = true;
}
final String location = getLocationText();
String location = getLocationText();
if (location != null) {
text = text + getBottom(hasContent) + location + "</div>";
}
@@ -1020,7 +985,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
return null;
}
final String title = manager.getTitle(element);
String title = manager.getTitle(element);
if (externalUrl == null) {
List<String> urls = provider.getUrlFor(element, originalElement);
if (urls != null) {
@@ -1086,7 +1051,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
try {
return new URL(url).toURI().getHost();
}
catch (URISyntaxException|MalformedURLException ignored) {}
catch (URISyntaxException | MalformedURLException ignored) { }
return null;
}
@@ -1113,22 +1078,22 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private String getLocationText() {
final PsiElement element = getElement();
PsiElement element = getElement();
if (element != null) {
PsiFile file = element.getContainingFile();
VirtualFile vfile = file == null ? null : file.getVirtualFile();
if (vfile == null) return null;
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(element.getProject()).getFileIndex();
final Module module = fileIndex.getModuleForFile(vfile);
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(element.getProject()).getFileIndex();
Module module = fileIndex.getModuleForFile(vfile);
if (module != null) {
if (ModuleManager.getInstance(element.getProject()).getModules().length == 1) return null;
return "<icon src='" + ModuleType.get(module).getId() + "'>&nbsp;" + module.getName().replace("<", "&lt;");
}
else {
final List<OrderEntry> entries = fileIndex.getOrderEntriesForFile(vfile);
List<OrderEntry> entries = fileIndex.getOrderEntriesForFile(vfile);
for (OrderEntry order : entries) {
if (order instanceof LibraryOrderEntry || order instanceof JdkOrderEntry) {
return "<icon src='AllIcons.Nodes.PpLibFolder" + "'>&nbsp;" + order.getPresentableName().replace("<", "&lt;");
@@ -1153,6 +1118,31 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myEditorPane.setFont(UIUtil.getFontWithFallback(fontName, Font.PLAIN, JBUI.scale(getQuickDocFontSize().getSize())));
}
@Nullable
private Image getImageByKeyImpl(Object key) {
if (myManager == null || key == null) return null;
PsiElement element = getElement();
if (element == null) return null;
URL url = (URL)key;
Image inMemory = myManager.getElementImage(element, url.toExternalForm());
if (inMemory != null) {
return inMemory;
}
Url parsedUrl = Urls.parseEncoded(url.toExternalForm());
BuiltInServerManager builtInServerManager = BuiltInServerManager.getInstance();
if (parsedUrl != null && builtInServerManager.isOnBuiltInWebServer(parsedUrl)) {
try {
url = new URL(builtInServerManager.addAuthToken(parsedUrl).toExternalForm());
}
catch (MalformedURLException e) {
LOG.warn(e);
}
}
Image image = ImageLoader.loadFromUrl(url);
return image != null ? ImageUtil.toBufferedImage(image) : Toolkit.getDefaultToolkit().createImage(url);
}
private void goBack() {
if (myBackStack.isEmpty()) return;
Context context = myBackStack.pop();
@@ -1198,14 +1188,14 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private static class MyGearActionGroup extends DefaultActionGroup implements HintManagerImpl.ActionToIgnore {
public MyGearActionGroup(@NotNull AnAction... actions) {
MyGearActionGroup(@NotNull AnAction... actions) {
super(actions);
setPopup(true);
}
}
private class BackAction extends AnAction implements HintManagerImpl.ActionToIgnore {
public BackAction() {
BackAction() {
super(CodeInsightBundle.message("javadoc.action.back"), null, AllIcons.Actions.Back);
}
@@ -1225,7 +1215,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private class ForwardAction extends AnAction implements HintManagerImpl.ActionToIgnore {
public ForwardAction() {
ForwardAction() {
super(CodeInsightBundle.message("javadoc.action.forward"), null, AllIcons.Actions.Forward);
}
@@ -1255,7 +1245,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
@Override
public void actionPerformed(AnActionEvent e) {
super.actionPerformed(e);
final JBPopup hint = myHint;
JBPopup hint = myHint;
if (hint != null && hint.isVisible()) {
hint.cancel();
}
@@ -1267,7 +1257,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
SmartPsiElementPointer element = myElement;
if (element != null) {
PsiElement psiElement = element.getElement();
return psiElement instanceof Navigatable ? new Navigatable[] {(Navigatable)psiElement} : null;
return psiElement instanceof Navigatable ? new Navigatable[]{(Navigatable)psiElement} : null;
}
return null;
}
@@ -1290,15 +1280,15 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
return;
}
final PsiElement element = myElement.getElement();
final PsiElement originalElement = DocumentationManager.getOriginalElement(element);
PsiElement element = myElement.getElement();
PsiElement originalElement = DocumentationManager.getOriginalElement(element);
ExternalJavaDocAction.showExternalJavadoc(element, originalElement, myExternalUrl, e.getDataContext());
}
@Override
public void update(AnActionEvent e) {
final Presentation presentation = e.getPresentation();
Presentation presentation = e.getPresentation();
presentation.setEnabled(hasExternalDoc());
}
}
@@ -1445,7 +1435,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
return null;
}
private void highlightLink(int n) {
myHighlightedLink = n;
Highlighter highlighter = myEditorPane.getHighlighter();
@@ -1480,10 +1470,41 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
}
private static class Context {
final SmartPsiElementPointer element;
final String text;
final String externalUrl;
final DocumentationProvider provider;
final Rectangle viewRect;
final int highlightedLink;
Context(SmartPsiElementPointer element,
String text,
String externalUrl,
DocumentationProvider provider,
Rectangle viewRect,
int highlightedLink) {
this.element = element;
this.text = text;
this.externalUrl = externalUrl;
this.provider = provider;
this.viewRect = viewRect;
this.highlightedLink = highlightedLink;
}
@NotNull
Context withText(@NotNull String text) {
return new Context(element, text, externalUrl, provider, viewRect, highlightedLink);
}
}
private class MyShowSettingsButton extends ActionButton {
public MyShowSettingsButton() {
this(new MyGearActionGroup(new ShowAsToolwindowAction(), new MyShowSettingsAction(), new ShowToolbarAction(), new RestoreDefaultSizeAction()),
MyShowSettingsButton() {
this(new MyGearActionGroup(new ShowAsToolwindowAction(),
new MyShowSettingsAction(),
new ShowToolbarAction(),
new RestoreDefaultSizeAction()),
new Presentation(), ActionPlaces.JAVADOC_INPLACE_SETTINGS, ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE);
}
@@ -1494,7 +1515,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private class MyShowSettingsAction extends AnAction implements HintManagerImpl.ActionToIgnore {
public MyShowSettingsAction() {
MyShowSettingsAction() {
super("Adjust font size...");
}
@@ -1565,10 +1586,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
activateLink(myHighlightedLink);
}
}
private static class LinkHighlighter implements Highlighter.HighlightPainter {
private static final Stroke STROKE = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{1}, 0);
@Override
public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {
try {
@@ -1590,7 +1611,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private class ShowToolbarAction extends ToggleAction implements HintManagerImpl.ActionToIgnore {
public ShowToolbarAction() {
ShowToolbarAction() {
super("Show Toolbar");
}
@@ -1608,7 +1629,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private class MyScrollPane extends JBScrollPane {
public MyScrollPane() {
MyScrollPane() {
super(myEditorPane, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
setLayout(new Layout() {
@Override
@@ -1665,7 +1686,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private class ShowAsToolwindowAction extends AnAction implements HintManagerImpl.ActionToIgnore {
public ShowAsToolwindowAction() {
ShowAsToolwindowAction() {
super("Open as Tool Window");
}
@@ -1681,7 +1702,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
private class RestoreDefaultSizeAction extends AnAction implements HintManagerImpl.ActionToIgnore {
public RestoreDefaultSizeAction() {
RestoreDefaultSizeAction() {
super("Restore Size");
}
@@ -89,7 +89,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
private static final Logger LOG = Logger.getInstance(DocumentationManager.class);
private static final String SHOW_DOCUMENTATION_IN_TOOL_WINDOW = "ShowDocumentationInToolWindow";
private static final String DOCUMENTATION_AUTO_UPDATE_ENABLED = "DocumentationAutoUpdateEnabled";
private static final long DOC_GENERATION_TIMEOUT_MILLISECONDS = 60000;
private static final long DOC_GENERATION_PAUSE_MILLISECONDS = 100;
@@ -105,10 +105,10 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
private boolean myCloseOnSneeze;
private String myPrecalculatedDocumentation;
private ActionCallback myLastAction;
private DocumentationComponent myTestDocumentationComponent;
private AnAction myRestorePopupAction;
@Override
@@ -173,9 +173,9 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
/**
* @return {@code true} if quick doc control is configured to not prevent user-IDE interaction (e.g. should be closed if
* the user presses a key);
* {@code false} otherwise
* @return {@code true} if quick doc control is configured to not prevent user-IDE interaction (e.g. should be closed if
* the user presses a key);
* {@code false} otherwise
*/
public boolean isCloseOnSneeze() {
return myCloseOnSneeze;
@@ -203,13 +203,13 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return ServiceManager.getService(project, DocumentationManager.class);
}
public DocumentationManager(final Project project, ActionManager manager, TargetElementUtil targetElementUtil) {
public DocumentationManager(Project project, ActionManager manager, TargetElementUtil targetElementUtil) {
super(project);
myActionManager = manager;
final AnActionListener actionListener = new AnActionListener() {
AnActionListener actionListener = new AnActionListener() {
@Override
public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {
final JBPopup hint = getDocInfoHint();
JBPopup hint = getDocInfoHint();
if (hint != null) {
if (action instanceof ShowQuickDocInfoAction) {
((AbstractPopup)hint).focusPreferredComponent();
@@ -230,14 +230,14 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
public void beforeEditorTyping(char c, DataContext dataContext) {
final JBPopup hint = getDocInfoHint();
JBPopup hint = getDocInfoHint();
if (hint != null && LookupManager.getActiveLookup(myEditor) == null) {
hint.cancel();
}
}
};
myActionManager.addAnActionListener(actionListener, project);
myUpdateDocAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD,myProject);
myUpdateDocAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, myProject);
myTargetElementUtil = targetElementUtil;
}
@@ -276,53 +276,52 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
.doWhenDone(() -> component.clearHistory());
}
public void showJavaDocInfo(@NotNull final PsiElement element, final PsiElement original) {
public void showJavaDocInfo(@NotNull PsiElement element, PsiElement original) {
showJavaDocInfo(element, original, null);
}
/**
* Asks to show quick doc for the target element.
*
* @param editor editor with an element for which quick do should be shown
* @param element target element which documentation should be shown
* @param original element that was used as a quick doc anchor. Example: consider a code like {@code Runnable task;}.
* A user wants to see javadoc for the {@code Runnable}, so, original element is a class name from the variable
* declaration but {@code 'element'} argument is a {@code Runnable} descriptor
* @param closeCallback callback to be notified on target hint close (if any)
* @param documentation precalculated documentation
* @param closeOnSneeze flag that defines whether quick doc control should be as non-obtrusive as possible. E.g. there are at least
* two possible situations - the quick doc is shown automatically on mouse over element; the quick doc is shown
* on explicit action call (Ctrl+Q). We want to close the doc on, say, editor viewport position change
* at the first situation but don't want to do that at the second
* @param editor editor with an element for which quick do should be shown
* @param element target element which documentation should be shown
* @param original element that was used as a quick doc anchor. Example: consider a code like {@code Runnable task;}.
* A user wants to see javadoc for the {@code Runnable}, so, original element is a class name from the variable
* declaration but {@code 'element'} argument is a {@code Runnable} descriptor
* @param closeCallback callback to be notified on target hint close (if any)
* @param documentation precalculated documentation
* @param closeOnSneeze flag that defines whether quick doc control should be as non-obtrusive as possible. E.g. there are at least
* two possible situations - the quick doc is shown automatically on mouse over element; the quick doc is shown
* on explicit action call (Ctrl+Q). We want to close the doc on, say, editor viewport position change
* at the first situation but don't want to do that at the second
*/
public void showJavaDocInfo(@NotNull Editor editor,
@NotNull final PsiElement element,
@NotNull final PsiElement original,
@NotNull PsiElement element,
@NotNull PsiElement original,
@Nullable Runnable closeCallback,
@Nullable String documentation,
boolean closeOnSneeze)
{
boolean closeOnSneeze) {
myEditor = editor;
myCloseOnSneeze = closeOnSneeze;
showJavaDocInfo(element, original, false, closeCallback, documentation);
}
public void showJavaDocInfo(@NotNull final PsiElement element,
final PsiElement original,
public void showJavaDocInfo(@NotNull PsiElement element,
PsiElement original,
@Nullable Runnable closeCallback) {
showJavaDocInfo(element, original, false, closeCallback);
}
public void showJavaDocInfo(@NotNull final PsiElement element,
final PsiElement original,
final boolean requestFocus,
public void showJavaDocInfo(@NotNull PsiElement element,
PsiElement original,
boolean requestFocus,
@Nullable Runnable closeCallback) {
showJavaDocInfo(element, original, requestFocus, closeCallback, null);
}
public void showJavaDocInfo(@NotNull final PsiElement element,
final PsiElement original,
final boolean requestFocus,
public void showJavaDocInfo(@NotNull PsiElement element,
PsiElement original,
boolean requestFocus,
@Nullable Runnable closeCallback,
@Nullable String documentation) {
if (!element.isValid()) {
@@ -341,31 +340,31 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
doShowJavaDocInfo(element, requestFocus, updateProcessor, original, closeCallback, documentation);
}
public void showJavaDocInfo(final Editor editor, @Nullable final PsiFile file, boolean requestFocus) {
public void showJavaDocInfo(Editor editor, @Nullable PsiFile file, boolean requestFocus) {
showJavaDocInfo(editor, file, requestFocus, null);
}
public void showJavaDocInfo(final Editor editor,
@Nullable final PsiFile file,
public void showJavaDocInfo(Editor editor,
@Nullable PsiFile file,
boolean requestFocus,
@Nullable final Runnable closeCallback) {
@Nullable Runnable closeCallback) {
myEditor = editor;
final Project project = getProject(file);
Project project = getProject(file);
PsiDocumentManager.getInstance(project).commitAllDocuments();
final PsiElement list =
ParameterInfoController.findArgumentList(file, editor.getCaretModel().getOffset(), -1);
PsiElement list = ParameterInfoController.findArgumentList(file, editor.getCaretModel().getOffset(), -1);
PsiElement expressionList = null;
if (list != null) {
LookupEx lookup = LookupManager.getInstance(myProject).getActiveLookup();
if (lookup != null) {
expressionList = null; // take completion variants for documentation then
} else {
}
else {
expressionList = list;
}
}
final PsiElement originalElement = getContextElement(editor, file);
PsiElement originalElement = getContextElement(editor, file);
PsiElement element = assertSameProject(findTargetElement(editor, file));
if (element == null && expressionList != null) {
@@ -387,7 +386,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
PsiElement finalElement = element;
final PopupUpdateProcessor updateProcessor = new PopupUpdateProcessor(project) {
PopupUpdateProcessor updateProcessor = new PopupUpdateProcessor(project) {
@Override
public void updatePopup(Object lookupIteObject) {
if (lookupIteObject == null) {
@@ -413,7 +412,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
if (myEditor != null) {
final PsiFile file = element.getContainingFile();
PsiFile file = element.getContainingFile();
if (file != null) {
Editor editor = myEditor;
showJavaDocInfo(myEditor, file, false);
@@ -437,11 +436,11 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return file != null ? file.findElementAt(editor.getCaretModel().getOffset()) : null;
}
private void doShowJavaDocInfo(@NotNull final PsiElement element,
private void doShowJavaDocInfo(@NotNull PsiElement element,
boolean requestFocus,
PopupUpdateProcessor updateProcessor,
final PsiElement originalElement,
@Nullable final Runnable closeCallback,
PsiElement originalElement,
@Nullable Runnable closeCallback,
@Nullable String documentation) {
Project project = getProject(element);
if (!project.isOpen()) return;
@@ -493,18 +492,18 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
}
private void showInPopup(@NotNull final PsiElement element,
private void showInPopup(@NotNull PsiElement element,
boolean requestFocus,
PopupUpdateProcessor updateProcessor,
final PsiElement originalElement,
@Nullable final Runnable closeCallback) {
final DocumentationComponent component = myTestDocumentationComponent == null ? new DocumentationComponent(this) :
myTestDocumentationComponent;
PsiElement originalElement,
@Nullable Runnable closeCallback) {
DocumentationComponent component = myTestDocumentationComponent == null ? new DocumentationComponent(this) :
myTestDocumentationComponent;
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
createToolWindow(element, originalElement);
final JBPopup hint = getDocInfoHint();
JBPopup hint = getDocInfoHint();
if (hint != null && hint.isVisible()) hint.cancel();
}
};
@@ -516,7 +515,8 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
boolean hasLookup = LookupManager.getActiveLookup(myEditor) != null;
AbstractPopup hint = (AbstractPopup)JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
AbstractPopup hint = (AbstractPopup)JBPopupFactory
.getInstance().createComponentPopupBuilder(component, component)
.setProject(element.getProject())
.addListener(updateProcessor)
.addUserData(updateProcessor)
@@ -579,30 +579,32 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
findQuickSearchComponent(myPreviouslyFocused).ifPresent(quickSearch -> quickSearch.registerHint(hint));
}
static String getTitle(@NotNull final PsiElement element, final boolean _short) {
final String title = SymbolPresentationUtil.getSymbolPresentableText(element);
return _short ? title != null ? title : element.getText() : CodeInsightBundle.message("javadoc.info.title", title != null ? title : element.getText());
static String getTitle(@NotNull PsiElement element, boolean isShort) {
String title = SymbolPresentationUtil.getSymbolPresentableText(element);
return isShort ? title != null ? title : element.getText()
: CodeInsightBundle.message("javadoc.info.title", title != null ? title : element.getText());
}
public static void storeOriginalElement(final Project project, final PsiElement originalElement, final PsiElement element) {
public static void storeOriginalElement(Project project, PsiElement originalElement, PsiElement element) {
if (element == null) return;
try {
element.putUserData(
ORIGINAL_ELEMENT_KEY,
SmartPointerManager.getInstance(project).createSmartPsiElementPointer(originalElement)
);
} catch (RuntimeException ex) {
}
catch (RuntimeException ex) {
// PsiPackage does not allow putUserData
}
}
@Nullable
public PsiElement findTargetElement(@NotNull final Editor editor, @Nullable final PsiFile file, PsiElement contextElement) {
public PsiElement findTargetElement(@NotNull Editor editor, @Nullable PsiFile file, PsiElement contextElement) {
return findTargetElement(editor, editor.getCaretModel().getOffset(), file, contextElement);
}
@Nullable
public PsiElement findTargetElement(final Editor editor, int offset, @Nullable final PsiFile file, PsiElement contextElement) {
public PsiElement findTargetElement(Editor editor, int offset, @Nullable PsiFile file, PsiElement contextElement) {
try {
return findTargetElementUnsafe(editor, offset, file, contextElement);
}
@@ -617,7 +619,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
* in case index is not ready will throw IndexNotReadyException
*/
@Nullable
private PsiElement findTargetElementUnsafe(final Editor editor, int offset, @Nullable final PsiFile file, PsiElement contextElement) {
private PsiElement findTargetElementUnsafe(Editor editor, int offset, @Nullable PsiFile file, PsiElement contextElement) {
if (LookupManager.getInstance(myProject).getActiveLookup() != null) {
return assertSameProject(getElementFromLookup(editor, file));
}
@@ -625,7 +627,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
TargetElementUtil util = TargetElementUtil.getInstance();
PsiElement element = null;
if (file != null) {
final DocumentationProvider documentationProvider = getProviderFromElement(file);
DocumentationProvider documentationProvider = getProviderFromElement(file);
if (documentationProvider instanceof DocumentationProviderEx) {
element = assertSameProject(((DocumentationProviderEx)documentationProvider).getCustomDocumentationElement(editor, file, contextElement));
}
@@ -636,7 +638,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
// Allow context doc over xml tag content
if (element != null || contextElement != null) {
final PsiElement adjusted = assertSameProject(util.adjustElement(editor, myTargetElementUtil.getAllAccepted(), element, contextElement));
PsiElement adjusted = assertSameProject(util.adjustElement(editor, myTargetElementUtil.getAllAccepted(), element, contextElement));
if (adjusted != null) {
element = adjusted;
}
@@ -644,7 +646,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
if (element == null) {
final PsiReference ref = TargetElementUtil.findReference(editor, offset);
PsiReference ref = TargetElementUtil.findReference(editor, offset);
if (ref != null) {
element = assertSameProject(util.adjustReference(ref));
if (ref instanceof PsiPolyVariantReference) {
@@ -668,7 +670,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
int offset = editor.getCaretModel().getOffset();
if (offset > 0 && offset == editor.getDocument().getTextLength()) offset--;
PsiReference ref = TargetElementUtil.findReference(editor, offset);
PsiElement contextElement = file == null? null : file.findElementAt(offset);
PsiElement contextElement = file == null ? null : file.findElementAt(offset);
PsiElement targetElement = ref != null ? ref.getElement() : contextElement;
if (targetElement != null) {
PsiUtilCore.ensureValid(targetElement);
@@ -698,15 +700,15 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return hint;
}
public void fetchDocInfo(PsiElement element, DocumentationComponent component) {
public void fetchDocInfo(@NotNull PsiElement element, @NotNull DocumentationComponent component) {
cancelAndFetchDocInfo(component, new MyCollector(myProject, element, null, null));
}
public ActionCallback queueFetchDocInfo(PsiElement element, DocumentationComponent component) {
public ActionCallback queueFetchDocInfo(@NotNull PsiElement element, @NotNull DocumentationComponent component) {
return doFetchDocInfo(component, new MyCollector(myProject, element, null, null));
}
private void cancelAndFetchDocInfo(DocumentationComponent component, DocumentationCollector provider) {
private void cancelAndFetchDocInfo(@NotNull DocumentationComponent component, @NotNull DocumentationCollector provider) {
myUpdateDocAlarm.cancelAllRequests();
doFetchDocInfo(component, provider);
}
@@ -728,7 +730,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
component.startWait();
if (wasEmpty) {
component.setText(CodeInsightBundle.message("javadoc.fetching.progress"), collector.element, collector.provider);
final AbstractPopup jbPopup = (AbstractPopup)getDocInfoHint();
AbstractPopup jbPopup = (AbstractPopup)getDocInfoHint();
if (jbPopup != null) {
jbPopup.setDimensionServiceKey(null);
}
@@ -760,8 +762,8 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
Throwable finalFail = fail;
GuiUtils.invokeLaterIfNeeded(() -> {
String message = finalFail instanceof IndexNotReadyException
? "Documentation is not available until indices are built."
: CodeInsightBundle.message("javadoc.external.fetch.error.message");
? "Documentation is not available until indices are built."
: CodeInsightBundle.message("javadoc.external.fetch.error.message");
component.setText(message, null, collector.provider);
component.clearHistory();
callback.setDone();
@@ -771,7 +773,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
LOG.debug("Documentation fetched successfully:\n", text);
final String finalText = text;
String finalText = text;
PsiDocumentManager.getInstance(myProject).performLaterWhenAllCommitted(() -> {
if (!element.isValid()) {
LOG.debug("Element for which documentation was requested is not valid");
@@ -809,8 +811,8 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return callback;
}
@NotNull
public static DocumentationProvider getProviderFromElement(final PsiElement element) {
@NotNull
public static DocumentationProvider getProviderFromElement(PsiElement element) {
return getProviderFromElement(element, null);
}
@@ -863,33 +865,33 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
@Nullable
public static PsiElement getOriginalElement(final PsiElement element) {
SmartPsiElementPointer originalElementPointer = element!=null ? element.getUserData(ORIGINAL_ELEMENT_KEY):null;
public static PsiElement getOriginalElement(PsiElement element) {
SmartPsiElementPointer originalElementPointer = element != null ? element.getUserData(ORIGINAL_ELEMENT_KEY) : null;
return originalElementPointer != null ? originalElementPointer.getElement() : null;
}
void navigateByLink(final DocumentationComponent component, final String url) {
void navigateByLink(DocumentationComponent component, String url) {
component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
final PsiElement psiElement = component.getElement();
PsiElement psiElement = component.getElement();
if (psiElement == null) {
return;
}
final PsiManager manager = PsiManager.getInstance(getProject(psiElement));
PsiManager manager = PsiManager.getInstance(getProject(psiElement));
if (url.equals("external_doc")) {
component.showExternalDoc();
return;
}
if (url.startsWith("open")) {
final PsiFile containingFile = psiElement.getContainingFile();
PsiFile containingFile = psiElement.getContainingFile();
OrderEntry libraryEntry = null;
if (containingFile != null) {
final VirtualFile virtualFile = containingFile.getVirtualFile();
VirtualFile virtualFile = containingFile.getVirtualFile();
libraryEntry = LibraryUtil.findLibraryEntry(virtualFile, myProject);
}
else if (psiElement instanceof PsiDirectoryContainer) {
PsiDirectory[] directories = ((PsiDirectoryContainer)psiElement).getDirectories();
for (PsiDirectory directory : directories) {
final VirtualFile virtualFile = directory.getVirtualFile();
VirtualFile virtualFile = directory.getVirtualFile();
libraryEntry = LibraryUtil.findLibraryEntry(virtualFile, myProject);
if (libraryEntry != null) {
break;
@@ -977,12 +979,14 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
public void requestFocus() {
findQuickSearchComponent(myPreviouslyFocused).ifPresent(quickSearch ->
getGlobalInstance().doWhenFocusSettlesDown(() -> getGlobalInstance().requestFocus(quickSearch.asComponent(), true))
findQuickSearchComponent(myPreviouslyFocused).ifPresent(
quickSearch ->
getGlobalInstance().doWhenFocusSettlesDown(
() -> getGlobalInstance().requestFocus(quickSearch.asComponent(), true))
);
}
public Project getProject(@Nullable final PsiElement element) {
public Project getProject(@Nullable PsiElement element) {
assertSameProject(element);
return myProject;
}
@@ -994,7 +998,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return element;
}
public static void createHyperlink(StringBuilder buffer, String refText,String label,boolean plainLink) {
public static void createHyperlink(StringBuilder buffer, String refText, String label, boolean plainLink) {
DocumentationManagerUtil.createHyperlink(buffer, refText, label, plainLink);
}
@@ -1012,7 +1016,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
protected void doUpdateComponent(PsiElement element, PsiElement originalElement, DocumentationComponent component) {
cancelAndFetchDocInfo(component, new MyCollector(myProject, element, originalElement, null));
}
@Override
protected void doUpdateComponent(Editor editor, PsiFile psiFile, boolean requestFocus) {
showJavaDocInfo(editor, psiFile, requestFocus, null);
@@ -1055,7 +1059,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
public ActionCallback getLastAction() {
return myLastAction;
}
@TestOnly
public void setDocumentationComponent(DocumentationComponent documentationComponent) {
myTestDocumentationComponent = documentationComponent;
@@ -1107,7 +1111,8 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
LOG.debug("External documentation URLs: ", urls);
if (urls != null) {
for (String url : urls) {
String doc = ((ExternalDocumentationProvider)provider).fetchExternalDocumentation(project, element, Collections.singletonList(url));
String doc = ((ExternalDocumentationProvider)provider).fetchExternalDocumentation(
project, element, Collections.singletonList(url));
if (doc != null) {
LOG.debug("Fetched documentation from ", url);
effectiveUrl = url;
@@ -1151,18 +1156,20 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
type == ArchiveFileType.INSTANCE ? "Archive" :
type.getName();
String languageName = type.isBinary() ? "" : psiFile.getLanguage().getDisplayName();
return (withUrl ? DocumentationMarkup.DEFINITION_START + file.getPresentableUrl() + DocumentationMarkup.DEFINITION_END + DocumentationMarkup.CONTENT_START : "") +
"<p><span class='grayed'>Size:</span> " + StringUtil.formatFileSize(attr.size()) +
"<p><span class='grayed'>Type:</span> " + typeName + (type.isBinary() || typeName.equals(languageName) ? "" : " (" + languageName + ")") +
"<p><span class='grayed'>Modified:</span> " + DateFormatUtil.formatDateTime(attr.lastModifiedTime().toMillis()) +
"<p><span class='grayed'>Created:</span> " + DateFormatUtil.formatDateTime(attr.creationTime().toMillis()) +
(withUrl ? DocumentationMarkup.CONTENT_END : "");
return (withUrl ? DocumentationMarkup.DEFINITION_START +
file.getPresentableUrl() +
DocumentationMarkup.DEFINITION_END +
DocumentationMarkup.CONTENT_START : "") +
"<p><span class='grayed'>Size:</span> " + StringUtil.formatFileSize(attr.size()) +
"<p><span class='grayed'>Type:</span> " + typeName + (type.isBinary() || typeName.equals(languageName) ? "" : " (" + languageName + ")") +
"<p><span class='grayed'>Modified:</span> " + DateFormatUtil.formatDateTime(attr.lastModifiedTime().toMillis()) +
"<p><span class='grayed'>Created:</span> " + DateFormatUtil.formatDateTime(attr.creationTime().toMillis()) + (withUrl ? DocumentationMarkup.CONTENT_END : "");
}
private static Optional<QuickSearchComponent> findQuickSearchComponent(Component c) {
while (c != null) {
if (c instanceof QuickSearchComponent) {
return Optional.of((QuickSearchComponent) c);
return Optional.of((QuickSearchComponent)c);
}
c = c.getParent();
}