Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support to redefine icons for LSP client #3459

Merged
merged 6 commits into from Jan 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions java/java.lsp.server/arch.xml
Expand Up @@ -961,6 +961,7 @@
<table>
<tbody>
<tr><td>is:folder</td><td>the Node represents a folder, or a DataFolder</td><td></td></tr>
<tr><td>is:file</td><td>the Node represents a file</td><td></td></tr>
<tr><td>is:project</td><td>the Node represents a project (the project's node itself)</td><td></td></tr>
<tr><td>is:projectRoot</td><td>the Node represents a root project in a multi-project tree</td><td></td></tr>
<tr><td>is:subProject</td><td>the Node represents a subproject in a multi-project tree</td><td></td></tr>
Expand Down
6 changes: 4 additions & 2 deletions java/java.lsp.server/licenseinfo.xml
Expand Up @@ -24,8 +24,9 @@
<file>vscode/package-lock.json</file>
<file>vscode/package.json</file>
<file>vscode/tsconfig.json</file>
<file>vscode/src/extension.ts</file>
<license ref="MIT-vscode-ext" />
<file>vscode/schemas/package.schema.json</file>
<license ref="Apache-2.0" />
<comment type="COMMENT_UNSUPPORTED" />
</fileset>
<fileset>
<file>src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.ttf</file>
Expand All @@ -40,6 +41,7 @@
<file>vscode/.vscode/tasks.json</file>
<file>vscode/.vscode/settings.json</file>
<license ref="Apache-2.0" />
<comment type="COMMENT_UNSUPPORTED" />
</fileset>
<fileset>
<file>vscode/images/Apache_NetBeans_Logo.png</file>
Expand Down
26 changes: 26 additions & 0 deletions java/java.lsp.server/nbcode/README.md
@@ -0,0 +1,26 @@
# Apache NetBeans Language Server Distribution
<!--

Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

Projects in this subdirectory are **not part of standard Apache NetBeans IDE distribution**.
They are part of a special Language Server application, based on Apache NetBeans Platform,
that runs *headless*. Modules in this subtree may register services, that override or
disrupt normal IDE operation: be careful when sharing or using code from this project and
subprojects.
45 changes: 41 additions & 4 deletions java/java.lsp.server/nbcode/integration/build.xml
Expand Up @@ -17,9 +17,46 @@
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.

-->
-->
<project name="org.netbeans.modules.nbcode.integration" default="netbeans" basedir=".">
<description>Builds, tests, and runs the project org.netbeans.modules.nbcode.integration.</description>
<import file="nbproject/build-impl.xml"/>
<description>Builds, tests, and runs the project org.netbeans.modules.nbcode.integration.</description>
<import file="nbproject/build-impl.xml"/>

<property name="nbantext.jar" location="${harness.dir}/../../build/nbantext.jar"/>
<target name="copy-icon-files" depends="init">
<!-- load the properties as plain text into a property -->
<loadfile property="_imagelist" srcfile="${src.dir}/org/netbeans/modules/nbcode/integration/resources/uimanager-icons.properties">
<!-- only load affirmative values of properties -->
<filterchain>
<linecontainsregexp negate="true">
<regexp pattern="^#|^\s*$|=" />
</linecontainsregexp>
<tokenfilter>
<replaceregex pattern="(.+)$" replace="\1,"/>
</tokenfilter>
<!--
<prefixlines prefix="copyicons." />
-->
</filterchain>
</loadfile>

<echo message="${_imagelist}"/>

<mkdir dir="${build.dir}/org/netbeans/modules/nbcode/integration/resources/uidefaults"/>
<taskdef name="repeat" classname="org.netbeans.nbbuild.Repeat" classpath="${nbantext.jar}"/>
<repeat target="-copy-single-file" name="copy.icon.name" values="${_imagelist}" />
</target>

<target name="-copy-single-file">
<condition property="empty">
<equals arg1="${copy.icon.name}" arg2="" trim="true"/>
</condition>
<antcall target="-copy-single-file2"/>
</target>
<target name="-copy-single-file2" unless="${empty}">
<copy file="${src.dir}/org/netbeans/modules/nbcode/integration/resources/empty.png" tofile="${build.classes.dir}/org/netbeans/modules/nbcode/integration/resources/uidefaults/${copy.icon.name}.png"/>
</target>

<target name="-pre-release" depends="projectized-common.-pre-release, copy-icon-files"/>
</project>
26 changes: 17 additions & 9 deletions java/java.lsp.server/nbcode/integration/nbproject/project.xml
Expand Up @@ -35,6 +35,14 @@
<specification-version>1.64</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.api.htmlui</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>1.23</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.api.io</code-name-base>
<build-prerequisite/>
Expand All @@ -60,14 +68,6 @@
<specification-version>1.19</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.api.htmlui</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>1.23</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.html.presenters.spi</code-name-base>
<build-prerequisite/>
Expand Down Expand Up @@ -115,6 +115,14 @@
<specification-version>7.80</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.modules</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.63</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.util</code-name-base>
<build-prerequisite/>
Expand All @@ -136,7 +144,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>9.23</specification-version>
<specification-version>9.24</specification-version>
</run-dependency>
</dependency>
</module-dependencies>
Expand Down
@@ -0,0 +1,106 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.nbcode.integration;

import java.awt.EventQueue;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIDefaults;
import javax.swing.UIDefaults.LazyValue;
import javax.swing.UIManager;
import org.openide.modules.OnStart;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;

/**
* Goes through UIDefaults and replaces Icons and Images with variants that
* return image's URL from the 'url' property.
* <b>Imporant note:</b> the class is <b>not a part of NetBeans IDE runtime</b>, it is
* packaged only to a LSP "nbcode" headless server.
* <p>
* The class processes resource
* {@code org/netbeans/modules/nbcode/integration/resources/uimanager-icons.properties}:
* keys define {@link UIManager} keys that will be replaced. If the key has a value, it will
* be replaced by an Icon {@link ImageUtilities#loadImage(java.lang.String) loaded} from that resource.
* If the key has no value, the image will be copied from a stub resource ({@code org/netbeans/modules/nbcode/integration/resources/empty.png})
* at build time and will get URL {@code org/netbeans/modules/nbcode/integration/resources/uidefaults&lt;property-key>}.
*
* @author sdedic
*/
@OnStart
public class UIDefaultsIconMetadata implements Runnable {
private static final Logger LOG = Logger.getLogger(UIDefaultsIconMetadata.class.getName());
private static final String RESOURCE_PREFIX = "org/netbeans/modules/nbcode/integration/resources/uidefaults/"; // NOI18N
@Override
public void run() {
EventQueue.invokeLater(() -> {
// force LaF initialization before the UIDefaults are read/patched.
UIManager.get("force.laf.initialization");
// force initialization of ImageUtilities class, otherwise its clinit could recursively call
// the lazy value here, which results in call into an (still) uninitialized ImageUtilities -> ClassDefNotFoundError.
ImageUtilities.loadImage("org/netbeans/modules/nbcode/integration/resources/empty.png");
replaceIconsAndImages(UIManager.getDefaults());
});
}

static void replaceIconsAndImages(UIDefaults defs) {
ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
try (InputStream is = UIDefaultsIconMetadata.class.getResourceAsStream("resources/uimanager-icons.properties")) { // NOI18N
Properties p = new Properties();
p.load(is);
// UIDefaults.keySet() is so lazy implemented that it does not enumerate any items ... but entrySet
sdedic marked this conversation as resolved.
Show resolved Hide resolved
// works and even allows to see raw LazyValue and ActiveValue instances...
Set<Map.Entry<Object,Object>> entries = defs.entrySet();
Set<Object> uiDefaultsKeys = new HashSet<>();
for (Map.Entry<Object,Object> e : entries) {
uiDefaultsKeys.add(e.getKey());
}
// defs.keySet() is empty for some reason
for (String uiKey : p.stringPropertyNames()) {
if (!uiDefaultsKeys.contains(uiKey)) {
LOG.log(Level.INFO, "Icon not used: {0}", uiKey);
continue;
}
String resImage = RESOURCE_PREFIX + uiKey + ".png"; // NOI18N
URL u = l.getResource(resImage);
if (u == null) {
LOG.log(Level.WARNING, "Resource missing: {0}", resImage);
continue;
}
LOG.log(Level.INFO, "Lazy-replacing icon: {0}", uiKey);
// verify the resource exists
defs.put(uiKey, new LazyValue() {
@Override
public Object createValue(UIDefaults table) {
return ImageUtilities.image2Icon(ImageUtilities.loadImage(resImage));
}
});
}
} catch (IOException ex) {
LOG.log(Level.WARNING, "Could not load image replacements", ex);
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,63 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# This file lists icons to be replaced by URL-loaded images.
# The format is j.u.Properties; if value is missing, the key will be prefixed
# with org/netbeans/modules/nbcode/integration/resources/uidefaults/, suffix
# .png. If the value is present, it must be the full path to the resource incl.
# extension, that can be loaded by ImageUtilities.loadImage.
#
# Buildscript will automatically create stub resources for keys without value.

CheckBox.icon
ComboBox.icon
ETableHeader.ascendingIcon
ETableHeader.descendingIcon
FileChooser.homeFolderIcon
FileChooser.newFolderIcon
FileChooser.upFolderIcon
Menu.arrowIcon
MSG_WaitScan
nb.bigclose.tab.icon.enabled.icon
nb.bigclose.tab.icon.pressed.icon
nb.bigclose.tab.icon.rollover.icon
nb.close.tab.icon.enabled.icon
nb.close.tab.icon.pressed.icon
nb.close.tab.icon.rollover.icon
nb.multitabs.button.dropdown.icon
nb.multitabs.button.left.icon
nb.multitabs.button.maximize.icon
nb.multitabs.button.right.icon
nb.popupswitcher.closebutton.defaultIcon
nb.popupswitcher.closebutton.rolloverIcon
nb.tabcontrol.busy.icon.normal
nb.tabcontrol.busy.icon.selected
OptionPane.informationIcon
OptionPane.warningIcon
PropSheet.customButtonIcon
RadioButton.icon
Table.columnSelection
ToolBar.handleIcon
Nb.Explorer.Folder.icon
Nb.Explorer.Folder.openedIcon
Tree.gtk_collapsedIcon
Tree.gtk_expandedIcon
Tree.closedIcon=org/netbeans/modules/nbcode/integration/resources/uidefaults/Tree.closedIcon.png
eirikbakke marked this conversation as resolved.
Show resolved Hide resolved
Tree.collapsedIcon
Tree.expandedIcon
Tree.leafIcon=org/netbeans/modules/nbcode/integration/resources/uidefaults/Tree.leafIcon.png
Tree.openIcon=org/netbeans/modules/nbcode/integration/resources/uidefaults/Tree.openIcon.png
2 changes: 1 addition & 1 deletion java/java.lsp.server/nbproject/project.xml
Expand Up @@ -617,7 +617,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>9.14</specification-version>
<specification-version>9.24</specification-version>
</run-dependency>
</dependency>
<dependency>
Expand Down
Expand Up @@ -56,6 +56,7 @@ public class DefaultDecorationsImpl implements TreeDataProvider.Factory {
public static final String EXPLORER_ROOT = "Explorers"; // NOI18N
public static final String COOKIES_EXT = "contextValues"; // NOI18N

public static final String CTXVALUE_FILE = "is:file"; // NOI18N
public static final String CTXVALUE_FOLDER = "is:folder"; // NOI18N
public static final String CTXVALUE_PROJECT = "is:project"; // NOI18N
public static final String CTXVALUE_PROJECT_ROOT = "is:projectRoot"; // NOI18N
Expand Down Expand Up @@ -166,7 +167,8 @@ public TreeItemData createDecorations(Node n, boolean expanded) {
}
folder = true;
d.addContextValues(CTXVALUE_FOLDER);
} else {
} else if ((f.isData() || f.isValid()) && !f.isVirtual()) {
d.addContextValues(CTXVALUE_FILE);
// PENDING: this could be moved to the VSNetbeans module ?
d.setCommand("vscode.open"); // NOI18N
}
Expand Down
Expand Up @@ -43,7 +43,6 @@ enum CollapsibleState {
public String description;
// ?: string | Uri | {dark: string | Uri, light: string | Uri} | ThemeIcon
public URI iconUri;
public int iconIndex;
// id for the tree item that has to be unique across tree.
// The id is used to preserve the selection and expansion state of the tree item.
public int id;
Expand All @@ -56,6 +55,27 @@ enum CollapsibleState {
public String resourceUri;
// ?: string | MarkdownString | undefined
public Object tooltip;

// NBLS-specific items, to be processed by the client:
// Metadata for the icon.
public IconDescriptor iconDescriptor;
// The icon's index
public int iconIndex;

/**
* Metadata that describe an icon origin or contents.
*/
public static class IconDescriptor {
/**
* Base URI / imageId of the icon.
*/
public URI baseUri;

/**
* Supplemental IDs from composed merged-in images or applied filters.
*/
public String[] composition;
sdedic marked this conversation as resolved.
Show resolved Hide resolved
}

public TreeItem() {
}
Expand Down