Skip to content
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions ISSUE_UI_SCREENSHOT_IMPROVEMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Improve UI screenshot generation for PR documentation

## Problem

The current approach to generating screenshots for UI components using Python/PIL produces white/blank images that don't accurately represent the Eclipse UI.

## Proposed Solutions

### 1. SWT Snippet Approach
Create small SWT snippets that can render the UI components. However, this requires complex setup for many components that depend on Eclipse platform infrastructure.

### 2. MCP Server with Eclipse Install (Recommended)
Create a Model Context Protocol (MCP) server that includes a full Eclipse installation. This would allow:
- Programmatic access to Eclipse UI components
- Automated screenshot capture of actual rendered UI
- Better representation of Eclipse styling and themes
- Reusable infrastructure for future UI documentation

## Context

This issue was identified while implementing the Source Lookups preference page (see related PR for #2073). The generated screenshot using Python/PIL doesn't accurately show how the preference page would look in a real Eclipse environment.

## Benefits of MCP Server Approach

- **Accuracy**: Screenshots show actual Eclipse UI rendering with proper fonts, colors, and styling
- **Reusability**: Can be used for all future UI-related PRs and documentation
- **Automation**: Can be integrated into CI/CD pipeline for automatic screenshot generation
- **Quality**: Better documentation quality improves contributor and user experience

## Implementation Ideas

1. Create a headless Eclipse installation in a container
2. Build an MCP server that can:
- Launch Eclipse workbench programmatically
- Navigate to specific UI components (dialogs, preference pages, views, etc.)
- Capture screenshots using SWT/platform APIs
- Return screenshots as base64 or file paths
3. Integrate with Copilot workflow for automatic screenshot generation

## Labels

- `enhancement`
- `documentation`
- `tooling`

## Related

- Source Lookups preference page PR
- Issue #2073
Binary file added source_lookups_preference_page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions ui/org.eclipse.pde.core/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@
<locator
class="org.eclipse.pde.internal.core.LocalMavenPluginSourcePathLocator"
complexity="low"/>
<locator
class="org.eclipse.pde.internal.core.ExternalPluginSourcePathLocator"
complexity="high"/>
</extension>
<extension
point="org.eclipse.pde.core.targetLocations">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*******************************************************************************
* Copyright (c) 2025 Christoph Läubrich and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Läubrich - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.internal.core;

import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.pde.core.IPluginSourcePathLocator;
import org.eclipse.pde.core.plugin.IPluginBase;
import org.eclipse.pde.internal.ui.IPreferenceConstants;
import org.eclipse.pde.internal.ui.PDEPlugin;

/**
* A plugin source path locator that queries external repositories and the
* Eclipse index for source bundles based on the configured preferences.
* <p>
* This locator checks the Source Lookups preference page settings and performs
* lookups according to the configured order.
* </p>
*
* @since 3.17
*/
public class ExternalPluginSourcePathLocator implements IPluginSourcePathLocator {

// Source lookup strategy identifiers
private static final String STRATEGY_REPOSITORIES = "REPOSITORIES"; //$NON-NLS-1$
private static final String STRATEGY_TARGETS = "TARGETS"; //$NON-NLS-1$
private static final String STRATEGY_INDEX = "INDEX"; //$NON-NLS-1$
private static final String STRATEGY_SITES = "SITES"; //$NON-NLS-1$

@Override
public IPath locateSource(IPluginBase plugin) {
IPreferenceStore store = PDEPlugin.getDefault().getPreferenceStore();

// Check if source lookup is enabled
if (!store.getBoolean(IPreferenceConstants.SOURCE_LOOKUP_ENABLED)) {
return null;
}

// Get the lookup order
List<String> lookupOrder = getLookupOrder(store);

// Execute lookups in the configured order
for (String strategy : lookupOrder) {
IPath result = null;
switch (strategy) {
case STRATEGY_REPOSITORIES:
result = searchInRepositories(plugin, getConfiguredRepositories(store));
break;
case STRATEGY_TARGETS:
result = searchInTargets(plugin, getSelectedTargets(store));
break;
case STRATEGY_INDEX:
result = queryEclipseIndex(plugin);
break;
case STRATEGY_SITES:
result = queryAvailableSoftwareSites(plugin);
break;
default:
// Unknown strategy, skip
break;
}

if (result != null) {
return result;
}
}

return null;
}

/**
* Gets the configured lookup order from preferences.
*
* @param store the preference store
* @return the list of strategy identifiers in order
*/
private List<String> getLookupOrder(IPreferenceStore store) {
String order = store.getString(IPreferenceConstants.SOURCE_LOOKUP_ORDER);
if (order == null || order.trim().isEmpty()) {
// Use default order
return Arrays.asList(STRATEGY_REPOSITORIES, STRATEGY_TARGETS, STRATEGY_INDEX, STRATEGY_SITES);
}
return Arrays.asList(order.split(",")); //$NON-NLS-1$
}

/**
* Searches for the source bundle in the configured repositories.
*
* @param plugin the plugin to locate sources for
* @param repositories the list of repository URLs
* @return the path to the source bundle or null if not found
*/
private IPath searchInRepositories(IPluginBase plugin, List<String> repositories) {
// TODO: Implement searching in configured repositories
// This will be implemented in a future step
return null;
}
Comment thread
laeubi marked this conversation as resolved.

/**
* Searches for the source bundle in the specified target platforms.
*
* @param plugin the plugin to locate sources for
* @param selectedTargets the list of selected target platform names
* @return the path to the source bundle or null if not found
*/
private IPath searchInTargets(IPluginBase plugin, List<String> selectedTargets) {
// TODO: Implement searching in selected target platforms
// This will be implemented in a future step
return null;
}
Comment thread
laeubi marked this conversation as resolved.

/**
* Queries the Eclipse index for the source bundle.
*
* @param plugin the plugin to locate sources for
* @return the path to the source bundle or null if not found
*/
private IPath queryEclipseIndex(IPluginBase plugin) {
// TODO: Implement querying the Eclipse index
// This will be implemented in a future step
return null;
}
Comment thread
laeubi marked this conversation as resolved.

/**
* Queries available software sites for the source bundle.
*
* @param plugin the plugin to locate sources for
* @return the path to the source bundle or null if not found
*/
private IPath queryAvailableSoftwareSites(IPluginBase plugin) {
// TODO: Implement querying available software sites
// This will be implemented in a future step
return null;
}
Comment on lines +378 to +417

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot This sis the last one to implement and we need to get all Known repositories from the P2 Manager then loop through them and look for the source bundle

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in commit 9f3b5fc.

Implementation:

  • Gets IMetadataRepositoryManager from P2TargetUtils
  • Retrieves all known repositories using getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)
  • Loops through all known P2 repository URIs
  • For each repository, calls downloadArtifact() to search for source bundle
  • Returns immediately on first successful download
  • Logs failures and continues to next repository

This completes all 4 source lookup strategies. The method searches all P2 repositories registered in Eclipse (update sites, installed software sites, etc.), providing the broadest search scope.


/**
* Gets the list of selected target platform names from preferences.
*
* @param store the preference store
* @return the list of selected target names
*/
private List<String> getSelectedTargets(IPreferenceStore store) {
String selectedTargets = store.getString(IPreferenceConstants.SOURCE_LOOKUP_SELECTED_TARGETS);
if (selectedTargets == null || selectedTargets.trim().isEmpty()) {
return List.of();
}
return Arrays.asList(selectedTargets.split(",")); //$NON-NLS-1$
}

/**
* Gets the list of configured repository URLs from preferences.
*
* @param store the preference store
* @return the list of repository URLs
*/
private List<String> getConfiguredRepositories(IPreferenceStore store) {
String repositories = store.getString(IPreferenceConstants.SOURCE_LOOKUP_REPOSITORIES);
if (repositories == null || repositories.trim().isEmpty()) {
return List.of();
}
return Arrays.asList(repositories.split(",")); //$NON-NLS-1$
}
}
1 change: 1 addition & 0 deletions ui/org.eclipse.pde.ui/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ preferences.target.name = Target Platform
preferences.compilers.name = Compilers
preferences.editor.name = Editors
preferences.bnd.templaterepo.name = Bnd Template Repositories
preferences.sourcelookup.name = Source Lookups

preferenceKeywords.PDE=Plug-in plugin Development PDE
preferenceKeywords.MainPreferencePage=java search target source dependencies JUnit launch workspace configuration plug-in fragment bundle
Expand Down
7 changes: 7 additions & 0 deletions ui/org.eclipse.pde.ui/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@
id="org.eclipse.pde.ui.LaunchingPreferencePage"
name="Launching">
</page>
<page
category="org.eclipse.pde.ui.MainPreferencePage"
class="org.eclipse.pde.internal.ui.preferences.SourceLookupPreferencePage"
id="org.eclipse.pde.ui.SourceLookupPreferencePage"
name="%preferences.sourcelookup.name">
<keywordReference id="org.eclipse.pde.ui.pde"/>
</page>
</extension>
<extension
point="org.eclipse.ui.keywords">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,23 @@ public interface IPreferenceConstants extends ILaunchingPreferenceConstants {
*/
public static final String TEST_PLUGIN_PATTERN = "Preferences.MainPage.testPluginPattern";//$NON-NLS-1$

// Source Lookup preference page
/**
* Boolean preference whether additional source lookups are enabled
*/
public static final String SOURCE_LOOKUP_ENABLED = "Preferences.SourceLookup.enabled"; //$NON-NLS-1$
/**
* String preference storing comma-separated ordered list of source lookup strategies
* Possible values: REPOSITORIES, TARGETS, INDEX, SITES
*/
public static final String SOURCE_LOOKUP_ORDER = "Preferences.SourceLookup.order"; //$NON-NLS-1$
/**
* String preference storing comma-separated list of selected target platform names for source lookup
*/
public static final String SOURCE_LOOKUP_SELECTED_TARGETS = "Preferences.SourceLookup.selectedTargets"; //$NON-NLS-1$
/**
* String preference storing comma-separated list of repository URLs for source lookup
*/
public static final String SOURCE_LOOKUP_REPOSITORIES = "Preferences.SourceLookup.repositories"; //$NON-NLS-1$

}
Original file line number Diff line number Diff line change
Expand Up @@ -3444,4 +3444,22 @@ public class PDEUIMessages extends NLS {

public static String AddMatchingVersion_RequireBundle;

public static String SourceLookupPreferencePage_description;
public static String SourceLookupPreferencePage_enableSourceLookup;
public static String SourceLookupPreferencePage_orderGroup;
public static String SourceLookupPreferencePage_orderDescription;
public static String SourceLookupPreferencePage_up;
public static String SourceLookupPreferencePage_down;
public static String SourceLookupPreferencePage_targetsGroup;
public static String SourceLookupPreferencePage_repositoriesGroup;
public static String SourceLookupPreferencePage_addRepository;
public static String SourceLookupPreferencePage_removeRepository;
public static String SourceLookupPreferencePage_addRepositoryTitle;
public static String SourceLookupPreferencePage_addRepositoryMessage;
public static String SourceLookupPreferencePage_unnamedTarget;
public static String SourceLookupPreferencePage_strategy_REPOSITORIES;
public static String SourceLookupPreferencePage_strategy_TARGETS;
public static String SourceLookupPreferencePage_strategy_INDEX;
public static String SourceLookupPreferencePage_strategy_SITES;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2728,4 +2728,22 @@ ProjectUpdateChange_configure_nature_and_builder=Update natures and builder
ProjectUpdateChange_convert_manifest_to_bnd=Convert MANIFEST.MF to bnd instructions
ProjectUpdateChange_convert_build_to_bnd=Convert build.properties to bnd instructions
ProjectUpdateChange_set_pde_preference=Set {0} in preferences
StatePage_title=Target State
StatePage_title=Target State
# Source Lookup Preference Page
SourceLookupPreferencePage_description=Configure source lookup settings for resolving source code
SourceLookupPreferencePage_enableSourceLookup=Enable additional source lookups
SourceLookupPreferencePage_orderGroup=Source Lookup Order
SourceLookupPreferencePage_orderDescription=Configure the order in which source lookups are performed (top to bottom):
SourceLookupPreferencePage_up=Up
SourceLookupPreferencePage_down=Down
SourceLookupPreferencePage_targetsGroup=Search in locations of the selected Targets
SourceLookupPreferencePage_repositoriesGroup=Search in these repositories
SourceLookupPreferencePage_addRepository=Add...
SourceLookupPreferencePage_removeRepository=Remove
SourceLookupPreferencePage_addRepositoryTitle=Add Repository
SourceLookupPreferencePage_addRepositoryMessage=Enter repository URL:
SourceLookupPreferencePage_unnamedTarget=<unnamed>
SourceLookupPreferencePage_strategy_REPOSITORIES=Configured Repositories
SourceLookupPreferencePage_strategy_TARGETS=Selected Target Platforms
SourceLookupPreferencePage_strategy_INDEX=Eclipse Index
SourceLookupPreferencePage_strategy_SITES=Available Software Sites
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ public void initializeDefaultPreferences() {
store.setDefault(IPreferenceConstants.WORKSPACE_PLUGINS_OVERRIDE_TARGET, true);
store.setDefault(IPreferenceConstants.DISABLE_API_ANALYSIS_BUILDER, false);
store.setDefault(IPreferenceConstants.TEST_PLUGIN_PATTERN, ICoreConstants.TEST_PLUGIN_PATTERN_DEFAULTVALUE);

// Source Lookup defaults
store.setDefault(IPreferenceConstants.SOURCE_LOOKUP_ENABLED, false);
// Default order: configured repositories, selected target, eclipse index, available software sites
store.setDefault(IPreferenceConstants.SOURCE_LOOKUP_ORDER, "REPOSITORIES,TARGETS,INDEX,SITES"); //$NON-NLS-1$
store.setDefault(IPreferenceConstants.SOURCE_LOOKUP_SELECTED_TARGETS, ""); //$NON-NLS-1$
store.setDefault(IPreferenceConstants.SOURCE_LOOKUP_REPOSITORIES, ""); //$NON-NLS-1$
}

}
Loading