Eclipse plugin development editor font - java

I am using Eclipse 3.7.0 for plugin development and I am using Xtext 2.9.2. My editor preferences isn't working correctly.
On windows 7, 8, 10 this happens:
.
On 64 bit builds, I am not able to change editor font. Hitting the change button does nothing but change the mouse to the busy/sandclock for a second and then back again to normal.
The same 64 bit builds were tested on windows XP and everything works as it should.
On 32 bit builds, everything works as expected and the windows font picker dialog appears.
This is how I create the preference page:
#Override
protected void createFieldEditors() {
// Add show font preference
fontField = new FontFieldEditor(JFaceResources.TEXT_FONT, EDIT_EDITOR_FONT_LABEL, getFieldEditorParent());
addField(fontField);
fontField.setPreferenceStore(getPreferenceStore());
// initialize the font preference with the default resources font if not initialized
String defaultFont = getPreferenceStore().getDefaultString(JFaceResources.TEXT_FONT);
if(defaultFont.isEmpty()) {
font= JFaceResources.getTextFont();
if (font != null) {
FontData[] data= font.getFontData();
if (data != null && data.length > 0) {
PreferenceConverter.setDefault(getPreferenceStore(), JFaceResources.TEXT_FONT, data[0]);
}
}
}
}
The .log file is empty and has nothing that is beneficial.
While debugging, I went to org.eclipse.swt.widgets.FontDialog.java and found that this line always returns false without the dialog appearing. From what I understand this call should be blocking and will only return when the dialog is closed either by X, OK or Cancel buttons but it returns immediately with false.
/* Open the dialog */
boolean success = OS.ChooseFont (lpcf)
I also tried something as minimal as this example and same thing happens.

Months passed and I figured out what was causing the issue.
Basically we have a JNI layer which loads some dll that requires MSVCR90.dll. This requires embedding MSVCR90.dll manifest into eclipse.exe used for our RCP, this is done using mt.exe provided by Microsoft Visual Studio.
While building I accidentally didn't embed the MSVCR90.dll manifest, this resulted into the error during loading the dll which says that MSVCR90.dll is missing. I however noticed that the treeview styling looked correct.
This was also the answer to my other question Eclipse RCP Jface/SWT TreeViewer on Windows 10. The manifest also affected the UI look and feel treeviews and progressbars didn't look like the ones provided by the OS.

Related

Detect dark windows taskbar

For theming purposes, I'm looking to detect the color of the Windows taskbar (in my case, for a tray icon).
I'm using Java, but any solutions are welcome as I'd happily convert them over as needed.
My first attempt was to read the registry.
This worked great for desktops that provided this value, but falls
short when the registry
does not provide it.
My second attempt was to take a screenshot of the taskbar and try to guess if it's dark or light themed.
This even works when autohide is on. Unfortunately it returns a black background regardless of what I do:
WinDef.HWND tray = User32.INSTANCE.FindWindow("Shell_TrayWnd", null);
BufferedImage bi = GDI32Util.getScreenshot(tray);
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(null, new JLabel((new ImageIcon(bi)))));
Assuming I don't want to rely on the white/black color of the Windows logo, is there a way to detect this?
Related:
How can I detect Windows 10 light/dark mode?
How do I get the mode (Light/Dark) of the PC in C#?
How can I get whether Windows 10 Anniversary Update or later is using its light or dark theme in a WPF app?
Similar (10 year old) question on MSDN
So far, I have not encountered the lack of SystemUsesLightTheme and AppsUseLightTheme in the registry.
But I think recreating the key-values is worth trying.
Here is code sample(C++):
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <Windows.h>
using namespace std;
int main() {
HKEY key;
if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"), &key) != ERROR_SUCCESS)
{
cout << "unable to open registry";
}
DWORD value_data = 0;
if (RegSetValueEx(key, TEXT("SystemUsesLightTheme"), 0, REG_DWORD, (const BYTE*)&value_data, sizeof(value_data)) != ERROR_SUCCESS)
{
RegCloseKey(key);
cout << "Unable to set registry value value_name";
}
else
{
cout << "value_name was set" << endl;
}
}
When the documented registry entries are missing, it appears something in the OS is coded to fallback the following settings:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize\
If AppsUseLightTheme is missing, assume it's 1
... and then make the dark/light Windowing decisions based on this value.
If SystemUsesLightTheme is missing, assume it's 0
... and then make the dark/light Taskbar/SystemTray decisions based on the this value.
The glory details...
Although fresh Windows Home installs defaults to the Light theme, these fresh installers also set the registry keys properly, so the combination of a missing registry key and a light taskbar is extremely unlikely (and probably impossible). To a similar point, studying modern OSs may -- improperly -- suggest the defaults come from the file C:\Windows\resources\Themes\aero.theme**, but don't be fooled! Older OSs didn't have a differentiating entry either... More below.
Instinct would suggest that the CurrentTheme or perhaps the InstallTheme registry values would serve as a sane fallback value, but changing these values appear to be for historical purposes and do not appear to actually change the light/dark theme.
reg query HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes /v InstallTheme
>>> returns the path to aero.theme
type %SystemRoot%\resources\Themes\aero.theme |find "SystemMode"
>>> returns SystemMode=dark
Even changing the InstallTheme for the entire machine (HKEY_LOCAL_MACHINE) doesn't modify this behavior of preferring SystemMode=dark (note, even this entry wasn't available in older Windows 10 versions. For example, Windows 10 v1507 doesn't have this entry in the theme file either).
Chasing the aero.theme hit some dead ends too. Attempts to directly modify aero.theme failed due to permissions, but copying aero.theme to the Desktop and changing SystemMode=dark to SystemMode=light and then double-clicking the theme file will make the taskbar go white, but only on newer Windows versions that supported the light theme.
So, yes, I have to agree with #strive-sun-msft the SystemUsesLightTheme registry entry is the best location. When testing, even the Task Bar itself monitors this, deleting it will reset it back to black. Unfortunately that fallback black Task Bar color remains to be a mystery. I can only assume it's hard-coded into the task bar itself.
Another workaround for this behavior is to just install the aero.theme file again by running it if the registry entries are missing. On newer Windows 10 versions, simply running this file will create the missing entries. Unfortunately, this doesn't work on older Windows 10 versions and worse, this will reset any custom preferences set by the user.
So the least intrusive way to detect the color of the taskbar is to read the registry and if the keys are missing, simply assume the theme Windows 10 shipped with is still in effect: Dark Taskbar, Light Windows.
You can use the Windows Registry Value SystemUsesLightTheme that is available at this Registry Path: Software\Microsoft\Windows\CurrentVersion\Themes\Personalize
for detecting the dark/light theme.
I found a library called JRegistry that allows you to access
this value.
RegistryKey windowsPersonalizeKey = new RegistryKey("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
RegistryValue systemUsesLightThemeValue = windowsPersonalizeKey.getValue("SystemUsesLightTheme");
if (systemUsesLightThemeValue != null) {
//this value is available
//getting the actual value
byte[] data = systemUsesLightThemeValue.getByteData();
byte actualValue = data[0];
boolean windows10Dark = actualValue == 0;
if (windows10Dark) {
//the theme is dark
} else {
// the theme is light
}
}
Also, if you want to listen to this value dynamically:
RegistryKey registryKey = new RegistryKey("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
RegistryWatcher.addRegistryListener((RegistryEvent registryEvent) -> {
RegistryKey changedKey = registryEvent.getKey();
if (changedKey.equals(registryKey)) {
RegistryValue value = changedKey.getValue("SystemUsesLightTheme");
//....
}
});
RegistryWatcher.watchKey(registryKey);

Eclipse RCP 4.x - Defining workspace location

I know that this question was asked many times, but I didn't find an exact answer which would fulfill my desires :)
Long story short:
I've got simple E4 application, product project, feature and main plugin with simple trim window.
Works, after exporting works too.
Now. I add lifeCycleURI property, create bundleclass for it and create simple dialog with Text area and a Button. Run it\export it and it works, before running main Trim Window dialog is shown. Fine.. Cool etc.
But I want to enter location eg. C:\TEST and after clicking button I want it to be my workspace area for the application (with .metedata and so on). HOW ???
Of course I've tried with :
Location instanceLocation = Platform.getInstanceLocation();
instanceLocation.set(new URL("file", null, "C:\TEST"), false);
But... It says that I can't change location cause it is already set... Tried to use above in Activator. The same. Tried to add
-data #noDefault in products Launching Arguments ... The same...
I always try to accomplish my tasks by myself but this.... this... ehh... Help ?
You should be able to do this in the #PostContextCreate method of the life cycle class. Don't specify the '-data' argument
#PostContextCreate
public void postContextCreate()
{
Location instanceLoc = Platform.getInstanceLocation();
// Stop if location is set
if (instanceLoc.isSet())
return;
File file = new File("C:\\TEST");
instanceLocation.set(file.toURL(), false);
}
Note: You need '\\' in your file path.
This is adapted from code which I use in my e4 RCP.
If you are currently testing the application from within Eclipse you will need to clear the workspace location in the 'Run Configuration' for the application. Open 'Run > Run Configurations', find your application and clear the 'Location' field on the 'Main' tab.

How can I prevent the Charm bar from showing up in my Java application?

I've got a Java swing program that runs in full screen mode. It's effectively a kiosk program in that I want it to lock out everything else while it's running. This is running on a Windows 8.1 tablet, so of course the tablet is touchscreen, and therefore if you do an "edge swipe" (drag your finger from the right) the charms bar pops up and you can get to the Start screen from there. Is there some way to disable this from happening in Java? (Or is there some third-party solution not involving Java that can work in tandem to achieve the same result?)
You can disable edge gestures while your app is active and full screen by setting the System.EdgeGesture.DisableTouchWhenFullScreen property on the window.
I don't know if Java provides a direct way to set this (probably not), but you should be able to set this from a JNI.
Here's a C++ snippet from the DisableTouchWhenFullScreen docs:
HRESULT SetTouchDisableProperty(HWND hwnd, BOOL fDisableTouch)
{
IPropertyStore* pPropStore;
HRESULT hrReturnValue = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pPropStore));
if (SUCCEEDED(hrReturnValue))
{
PROPVARIANT var;
var.vt = VT_BOOL;
var.boolVal = fDisableTouch ? VARIANT_TRUE : VARIANT_FALSE;
hrReturnValue = pPropStore->SetValue(PKEY_EdgeGesture_DisableTouchWhenFullscreen, var);
pPropStore->Release();
}
return hrReturnValue;
}
What I ended up doing was to write a batch script that kills explorer.exe and then re-spawns it after the app exits, based on this answer on Super User.

Set the initial directory in SWT FileDialog

I'm working on an Eclipse RCP project and need to let the user select some file.
For convenience, based on some conditions, the initial directory of the file choosing dialog should be set prior to opening it.
As I'm bound to Eclipse RCP / SWT, I am working with the org.eclipse.swt.widgets.FileDialog.
The documentation of this FileDialog points out to use the setFilterPath(String string)-method which should do exactly what I need (see documentation).
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setFilterExtensions(new String [] {"*.html"});
dialog.setFilterPath("c:\\temp");
String result = dialog.open();
Unfortunately it is not working, at least not "every time".
I have currently no installation to check on it, but I'm quite sure that the feature would work totally fine on a Windows 200/XP/Vista machine.
I am working with a Windows 7 machine and I think I am suffering from the behaviour described here for lpstrInitialDir.
At least, this is exactly the behaviour I am facing: The path is good the first time I open the dialog, but the second time, the path is initially set to the last chosen path.
This seems to be convenient in most cases, but it is not in mine.
Can this be right?
If so, have I any chance on changing the behaviour according to my needs?
Thanks for any helping answer!
I ran into the same problem on Windows 10 and found a solution that seems to be working for me. A code snippet from the DirectoryDialog led to the right direction:
if (filterPath != null && filterPath.length() > 0) {
String path = filterPath.replace('/', '\\');
char[] buffer = new char[path.length() + 1];
path.getChars(0, path.length(), buffer, 0);
if (COM.SHCreateItemFromParsingName(buffer, 0, COM.IID_IShellItem, ppv) == OS.S_OK) {
IShellItem psi = new IShellItem(ppv[0]);
/*
* SetDefaultDirectory does not work if the dialog has
* persisted recently used folder. The fix is to clear the
* persisted data.
*/
fileDialog.ClearClientData();
fileDialog.SetDefaultFolder(psi);
psi.Release();
}
}
The FileDialog misses this statement 'fileDialog.ClearClientData()'. My solution is to execute the following code before setting the path and open the dialog:
long [] ppv = new long [1];
if (COM.CoCreateInstance(COM.CLSID_FileOpenDialog, 0, COM.CLSCTX_INPROC_SERVER, COM.IID_IFileOpenDialog, ppv) == OS.S_OK) {
IFileDialog fileDialog = new IFileDialog(ppv[0]);
fileDialog.ClearClientData();
fileDialog.Release();
}
Now you can set the filterpath without Windows messing things up.
I found a simple Solution for the Problem you described (I had the exact same Problem).
Just rearrange the your code like this:
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setFilterPath("c:\\temp"); // This line is switched with the following line
dialog.setFilterExtensions(new String [] {"*.html"});
String result = dialog.open();
Somehow the Order of the methods called is relevant.
Are you using the same FileDialog object when you re-open it?
I ran a few quick tests and found that, if you re-set the filterPath, the dialog opens in the correct location.
If I open the same object again, it starts in the previously selected location.

Eclipse plugin - accessing the editor

So, I’m currently developing a plugin for the eclipse IDE. In a nutshell, the plugin is a collaborative real time code editor where the editor is eclipse (which is something like Google documents but with the code and on eclipse). Meaning that when I install the plugin, I would be able to connect -using my Gmail account- eclipse to the partner’s eclipse. And when I start coding on my machine, my partner would be seeing what I write and vice versa.
The problem I’m currently facing is accessing eclipse’s editor. For example, I have to monitor all the changes in the active document so that every time a change happens, the other partner’s IDE would be notified with this change.
I found and read about the IDcoumentProvider, IDocument and IEditorInput classes and they’re somehow connected but I can’t understand this connection or how to use it. So if someone can explain this connection I would really appreciate it. Also if there is another way to achieve my goal?
You can access the IEditorPart via the IWorkbenchPage.
IEditorPart editor = ((IWorkbenchPage) PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage()).getActiveEditor();
From there, you have access to various other classes, including the editor's IEditorInput, the File loaded by that editor, or the underlying GUI Control element. (Note that depending on the kind of editor (text files, diagram, etc.) you may have to cast to different classes.)
FileEditorInput input = (FileEditorInput) editor.getEditorInput();
StyledText editorControl = ((StyledText) editor.getAdapter(Control.class));
String path = input.getFile().getRawLocationURI().getRawPath();
Now, you can add a listener to the Control, e.g. a KeyAdapter for monitoring all key strokes occurring in the respective editor.
editorControl.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
System.out.println("Editing in file " + path);
}
});
Or, if monitoring all key strokes is too much, you can register an IPropertyListener to the editor. This listener will e.g. be notified whenever the editor gets 'dirty' or when it is saved. The meaning of propId can be found in IWorkbenchPartConstants.
editor.addPropertyListener(new IPropertyListener() {
#Override
public void propertyChanged(Object source, int propId) {
if (propId == IWorkbenchPartConstants.PROP_DIRTY) {
System.out.println("'Dirty' Property Changed");
}
}
});

Categories

Resources