1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 18:56:02 +02:00

Bug 481978 - UI to add Qt installs. Installs are now persisted.

Change-Id: I1fa75b71615959df314a9aaca5f01e17069ec35f
This commit is contained in:
Doug Schaefer 2015-11-11 21:55:06 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent 2d6e4f4b8a
commit 2e6c6216fb
19 changed files with 613 additions and 73 deletions

View file

@ -24,4 +24,5 @@ Export-Package: org.eclipse.cdt.internal.qt.core;x-friends:="org.eclipse.cdt.qt.
org.eclipse.cdt.internal.qt.core.build;x-friends:="org.eclipse.cdt.qt.ui",
org.eclipse.cdt.internal.qt.core.index;x-friends:="org.eclipse.cdt.qt.ui.tests",
org.eclipse.cdt.internal.qt.core.parser;x-friends:="org.eclipse.cdt.qt.ui",
org.eclipse.cdt.internal.qt.core.project;x-friends:="org.eclipse.cdt.qt.ui"
org.eclipse.cdt.internal.qt.core.project;x-friends:="org.eclipse.cdt.qt.ui",
org.eclipse.cdt.qt.core

View file

@ -5,33 +5,43 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.qt.core.build;
package org.eclipse.cdt.internal.qt.core;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Path;
import org.eclipse.cdt.internal.qt.core.QtPlugin;
import org.eclipse.cdt.qt.core.IQtInstall;
import org.eclipse.core.runtime.Platform;
public class QtInstall {
public class QtInstall implements IQtInstall {
private final String name;
private final Path qmakePath;
private String spec;
public QtInstall(Path qmakePath) {
public QtInstall(String name, Path qmakePath) {
this.name = name;
this.qmakePath = qmakePath;
}
@Override
public String getName() {
return name;
}
@Override
public Path getQmakePath() {
return qmakePath;
}
@Override
public Path getLibPath() {
return qmakePath.resolve("../lib"); //$NON-NLS-1$
}
@Override
public boolean supports(String os, String arch) {
switch (getSpec()) {
case "macx-clang": //$NON-NLS-1$
@ -42,16 +52,22 @@ public class QtInstall {
return false;
}
public static String getSpec(String qmakePath) throws IOException {
Process proc = new ProcessBuilder(qmakePath, "-query", "QMAKE_XSPEC").start(); //$NON-NLS-1$ //$NON-NLS-2$
try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
String line = reader.readLine();
if (line != null) {
return line.trim();
}
}
return null;
}
@Override
public String getSpec() {
if (spec == null) {
try {
Process proc = new ProcessBuilder(getQmakePath().toString(), "-query", "QMAKE_XSPEC").start(); //$NON-NLS-1$ //$NON-NLS-2$
try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
String line = reader.readLine();
if (line != null) {
spec = line.trim();
}
}
spec = getSpec(getQmakePath().toString());
} catch (IOException e) {
QtPlugin.log(e);
}

View file

@ -0,0 +1,91 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.qt.core;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.qt.core.IQtInstall;
import org.eclipse.cdt.qt.core.IQtInstallManager;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
public class QtInstallManager implements IQtInstallManager {
private Map<String, IQtInstall> installs;
private Preferences getPreferences() {
return InstanceScope.INSTANCE.getNode(QtPlugin.ID).node("qtInstalls"); //$NON-NLS-1$
}
private void initInstalls() {
if (installs == null) {
installs = new HashMap<>();
try {
Preferences prefs = getPreferences();
for (String key : prefs.keys()) {
installs.put(key, new QtInstall(key, Paths.get(prefs.get(key, "/")))); //$NON-NLS-1$
}
} catch (BackingStoreException e) {
QtPlugin.log(e);
}
}
}
private void saveInstalls() {
try {
Preferences prefs = getPreferences();
// Remove ones that aren't valid
for (String key : prefs.keys()) {
if (installs.get(key) == null) {
prefs.remove(key);
}
}
// Add new ones
for (String key : installs.keySet()) {
if (prefs.get(key, null) == null) {
prefs.put(key, installs.get(key).getQmakePath().toString());
}
}
} catch (BackingStoreException e) {
QtPlugin.log(e);
}
}
@Override
public Collection<IQtInstall> getInstalls() {
initInstalls();
return Collections.unmodifiableCollection(installs.values());
}
@Override
public void addInstall(IQtInstall qt) {
initInstalls();
installs.put(qt.getName(), qt);
saveInstalls();
}
@Override
public IQtInstall getInstall(String name) {
initInstalls();
return installs.get(name);
}
@Override
public void removeInstall(IQtInstall install) {
installs.remove(install.getName());
saveInstalls();
}
}

View file

@ -11,6 +11,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.internal.qt.core.index.QMakeProjectInfoManager;
import org.eclipse.cdt.qt.core.IQtInstallManager;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
@ -23,8 +24,8 @@ import org.osgi.framework.ServiceReference;
public class QtPlugin extends Plugin {
public static final String ID = "org.eclipse.cdt.qt.core";
public static final String SIGNAL_SLOT_TAGGER_ID = ID + ".signalslot.tagger";
public static final String ID = "org.eclipse.cdt.qt.core"; //$NON-NLS-1$
public static final String SIGNAL_SLOT_TAGGER_ID = ID + ".signalslot.tagger"; //$NON-NLS-1$
public static final int SignalSlot_Mask_signal = 1;
public static final int SignalSlot_Mask_slot = 2;
@ -39,7 +40,7 @@ public class QtPlugin extends Plugin {
* project from which they are created. This name is used to store the
* property.
*/
public static final QualifiedName QTINDEX_PROP_NAME = new QualifiedName(ID, "qtindex");
public static final QualifiedName QTINDEX_PROP_NAME = new QualifiedName(ID, "qtindex"); //$NON-NLS-1$
private static QtPlugin instance;
@ -69,6 +70,9 @@ public class QtPlugin extends Plugin {
}
};
context.addBundleListener(bundleListener);
context.registerService(IQtInstallManager.class, new QtInstallManager(), null);
super.start(context);
}

View file

@ -26,6 +26,8 @@ import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.qt.core.QtPlugin;
import org.eclipse.cdt.qt.core.IQtInstall;
import org.eclipse.cdt.qt.core.IQtInstallManager;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
@ -37,7 +39,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
public class QtBuildConfiguration extends CBuildConfiguration {
private QtInstall qtInstall;
private IQtInstall qtInstall;
private String launchMode;
private Map<String, String> properties;
@ -76,14 +78,14 @@ public class QtBuildConfiguration extends CBuildConfiguration {
// return it if it exists already
for (IBuildConfiguration config : project.getBuildConfigs()) {
QtBuildConfiguration qtConfig = config.getAdapter(QtBuildConfiguration.class);
QtInstall qtInstall = qtConfig.getQtInstall();
IQtInstall qtInstall = qtConfig.getQtInstall();
if (qtInstall != null && qtInstall.supports(os, arch) && launchMode.equals(qtConfig.getLaunchMode())) {
return qtConfig;
}
}
// Nope, create it
for (QtInstall qtInstall : QtInstallManager.instance.getInstalls()) {
for (IQtInstall qtInstall : QtPlugin.getService(IQtInstallManager.class).getInstalls()) {
if (qtInstall.supports(os, arch)) {
Set<String> configNames = new HashSet<>();
for (IBuildConfiguration config : project.getBuildConfigs()) {
@ -108,7 +110,7 @@ public class QtBuildConfiguration extends CBuildConfiguration {
return null;
}
public QtInstall getQtInstall() {
public IQtInstall getQtInstall() {
if (qtInstall == null) {
// TODO set based on settings
}
@ -122,7 +124,7 @@ public class QtBuildConfiguration extends CBuildConfiguration {
return launchMode;
}
private void setup(QtInstall qtInstall, String launchMode) {
private void setup(IQtInstall qtInstall, String launchMode) {
this.qtInstall = qtInstall;
this.launchMode = launchMode;
// TODO save settings

View file

@ -1,46 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.qt.core.build;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.Platform;
public class QtInstallManager {
public static final QtInstallManager instance = new QtInstallManager();
private List<QtInstall> installs;
private static boolean isWin = Platform.getOS().equals(Platform.OS_WIN32);
public List<QtInstall> getInstalls() {
if (installs == null) {
installs = new ArrayList<>();
// TODO hack to get going
File qtDir = new File(System.getProperty("user.home"), "Qt/5.5");
if (!qtDir.isDirectory() && isWin) {
qtDir = new File("C:/Qt/5.5");
}
if (qtDir.isDirectory()) {
for (File dir : qtDir.listFiles()) {
Path qmakePath = dir.toPath().resolve(isWin ? "bin/qmake.exe" : "bin/qmake");
if (qmakePath.toFile().canExecute()) {
installs.add(new QtInstall(qmakePath));
}
}
}
}
return installs;
}
}

View file

@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.qt.core;
import java.nio.file.Path;
/**
* Represents an installation of the Qt SDK. Qt installs are defined by the path
* to the qmake executable.
*
* @noimplement
*/
public interface IQtInstall {
String getName();
Path getQmakePath();
String getSpec();
boolean supports(String os, String arch);
Path getLibPath();
}

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.qt.core;
import java.util.Collection;
/**
* The manager for Qt installs.
*
* @noimplement
*/
public interface IQtInstallManager {
public Collection<IQtInstall> getInstalls();
public void addInstall(IQtInstall install);
public IQtInstall getInstall(String name);
public void removeInstall(IQtInstall install);
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>

View file

@ -1,7 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -17,7 +17,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.cdt.ui,
org.eclipse.cdt.core,
org.eclipse.cdt.qt.core
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.cdt.internal.qt.ui.assist;x-friends:="org.eclipse.cdt.qt.ui.tests",
org.eclipse.cdt.internal.qt.ui.pro.parser;x-friends:="org.eclipse.cdt.qt.ui.tests"

View file

@ -14,3 +14,5 @@ qtHighlighting.extName=Qt Semantic Highlighting
qtHighlighting.displayName=Qt Keywords
newProject.name=Qt Project
preferences.qt.name=Qt

View file

@ -72,4 +72,12 @@
extensions="qml">
</participant>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
<page
class="org.eclipse.cdt.internal.qt.ui.preferences.QtPreferencePage"
id="org.eclipse.cdt.qt.ui.preferencePage.qt"
name="%preferences.qt.name">
</page>
</extension>
</plugin>

View file

@ -0,0 +1,34 @@
package org.eclipse.cdt.internal.qt.ui;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.qt.ui.messages"; //$NON-NLS-1$
public static String NewQtInstallWizardPage_0;
public static String NewQtInstallWizardPage_1;
public static String NewQtInstallWizardPage_10;
public static String NewQtInstallWizardPage_11;
public static String NewQtInstallWizardPage_2;
public static String NewQtInstallWizardPage_3;
public static String NewQtInstallWizardPage_4;
public static String NewQtInstallWizardPage_5;
public static String NewQtInstallWizardPage_6;
public static String NewQtInstallWizardPage_7;
public static String NewQtInstallWizardPage_8;
public static String NewQtInstallWizardPage_9;
public static String QtPreferencePage_0;
public static String QtPreferencePage_1;
public static String QtPreferencePage_2;
public static String QtPreferencePage_3;
public static String QtPreferencePage_4;
public static String QtPreferencePage_5;
public static String QtPreferencePage_6;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
private Messages() {
}
}

View file

@ -19,6 +19,7 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* The activator class controls the plug-in life cycle
@ -50,10 +51,12 @@ public class QtUIPlugin extends AbstractUIPlugin {
super.start(context);
plugin = this;
// Use a save participant to grab any changed resources while this plugin was inactive
// Use a save participant to grab any changed resources while this
// plugin was inactive
QtResourceChangeListener resourceManager = new QtResourceChangeListener();
ISaveParticipant saveParticipant = new QtWorkspaceSaveParticipant();
ISavedState lastState = ResourcesPlugin.getWorkspace().addSaveParticipant(QtUIPlugin.PLUGIN_ID, saveParticipant);
ISavedState lastState = ResourcesPlugin.getWorkspace().addSaveParticipant(QtUIPlugin.PLUGIN_ID,
saveParticipant);
if (lastState != null) {
lastState.processResourceChangeEvents(resourceManager);
}
@ -115,4 +118,11 @@ public class QtUIPlugin extends AbstractUIPlugin {
public static void log(int code, String msg, Throwable e) {
getDefault().getLog().log(new Status(code, PLUGIN_ID, msg, e));
}
public static <T> T getService(Class<T> service) {
BundleContext context = plugin.getBundle().getBundleContext();
ServiceReference<T> ref = context.getServiceReference(service);
return ref != null ? context.getService(ref) : null;
}
}

View file

@ -0,0 +1,19 @@
NewQtInstallWizardPage_0=NewQtInstall
NewQtInstallWizardPage_1=New Qt Install
NewQtInstallWizardPage_10=Must specify a name for the install
NewQtInstallWizardPage_11=Install name already exists
NewQtInstallWizardPage_2=Name:
NewQtInstallWizardPage_3=Location:
NewQtInstallWizardPage_4=Browse...
NewQtInstallWizardPage_5=Select location of qmake
NewQtInstallWizardPage_6=qmake.exe
NewQtInstallWizardPage_7=qmake
NewQtInstallWizardPage_8=Get Qt Spec
NewQtInstallWizardPage_9=mkspec:
QtPreferencePage_0=Qt Installs
QtPreferencePage_1=Name
QtPreferencePage_2=Location
QtPreferencePage_3=Add
QtPreferencePage_4=Remove
QtPreferencePage_5=Remove Qt Install
QtPreferencePage_6=Are you sure you want to remove the selected Qt installs?

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.qt.ui.preferences;
import java.util.Map;
import org.eclipse.cdt.qt.core.IQtInstall;
import org.eclipse.jface.wizard.Wizard;
public class NewQtInstallWizard extends Wizard {
private final NewQtInstallWizardPage page;
private IQtInstall install;
public NewQtInstallWizard(Map<String, IQtInstall> existing) {
page = new NewQtInstallWizardPage(existing);
}
@Override
public void addPages() {
addPage(page);
}
@Override
public boolean performFinish() {
install = page.getInstall();
return true;
}
public IQtInstall getInstall() {
return install;
}
}

View file

@ -0,0 +1,129 @@
package org.eclipse.cdt.internal.qt.ui.preferences;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Map;
import org.eclipse.cdt.internal.qt.core.QtInstall;
import org.eclipse.cdt.internal.qt.ui.Messages;
import org.eclipse.cdt.qt.core.IQtInstall;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class NewQtInstallWizardPage extends WizardPage {
private Text nameText;
private Text locationText;
private Text specText;
private final Map<String, IQtInstall> existing;
public NewQtInstallWizardPage(Map<String, IQtInstall> existing) {
super(Messages.NewQtInstallWizardPage_0, Messages.NewQtInstallWizardPage_1, null);
this.existing = existing;
}
@Override
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
comp.setLayout(new GridLayout(2, false));
Label nameLabel = new Label(comp, SWT.NONE);
nameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
nameLabel.setText(Messages.NewQtInstallWizardPage_2);
nameText = new Text(comp, SWT.BORDER);
nameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
nameText.addModifyListener(e -> validate());
Label locationLabel = new Label(comp, SWT.NONE);
locationLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
locationLabel.setText(Messages.NewQtInstallWizardPage_3);
Composite locationComp = new Composite(comp, SWT.NONE);
locationComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = layout.marginWidth = 0;
locationComp.setLayout(layout);
locationText = new Text(locationComp, SWT.BORDER);
locationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
locationText.addModifyListener(e -> validate());
Button locationButton = new Button(locationComp, SWT.PUSH);
locationButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
locationButton.setText(Messages.NewQtInstallWizardPage_4);
locationButton.addListener(SWT.Selection, e -> {
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
dialog.setText(Messages.NewQtInstallWizardPage_5);
dialog.setFilterExtensions(
new String[] { Platform.getOS().equals(Platform.OS_WIN32) ? Messages.NewQtInstallWizardPage_6 : Messages.NewQtInstallWizardPage_7 });
String selected = dialog.open();
if (selected != null) {
locationText.setText(selected);
new Job(Messages.NewQtInstallWizardPage_8) {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
String spec = QtInstall.getSpec(selected);
getControl().getDisplay().asyncExec(() -> {
specText.setText(spec);
if (nameText.getText().isEmpty() && !existing.containsKey(spec)) {
nameText.setText(spec);
}
});
return Status.OK_STATUS;
} catch (IOException e) {
return Status.CANCEL_STATUS;
}
}
}.schedule();
}
});
Label specLabel = new Label(comp, SWT.NONE);
specLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
specLabel.setText(Messages.NewQtInstallWizardPage_9);
specText = new Text(comp, SWT.READ_ONLY | SWT.BORDER);
specText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
setControl(comp);
validate();
}
private void validate() {
setPageComplete(false);
String name = nameText.getText().trim();
if (name.isEmpty()) {
setErrorMessage(Messages.NewQtInstallWizardPage_10);
return;
}
if (existing.containsKey(name)) {
setErrorMessage(Messages.NewQtInstallWizardPage_11);
return;
}
setPageComplete(true);
setErrorMessage(null);
}
IQtInstall getInstall() {
return new QtInstall(nameText.getText(), Paths.get(locationText.getText()));
}
}

View file

@ -0,0 +1,174 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.qt.ui.preferences;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.qt.ui.Messages;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.qt.core.IQtInstall;
import org.eclipse.cdt.qt.core.IQtInstallManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
public class QtPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
private IQtInstallManager manager;
private Table installTable;
private Button removeButton;
private Map<String, IQtInstall> installsToAdd = new HashMap<>();
private Map<String, IQtInstall> installsToRemove = new HashMap<>();
@Override
public void init(IWorkbench workbench) {
manager = QtUIPlugin.getService(IQtInstallManager.class);
}
@Override
protected Control createContents(Composite parent) {
Composite control = new Composite(parent, SWT.NONE);
control.setLayout(new GridLayout());
Group installsGroup = new Group(control, SWT.NONE);
installsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
installsGroup.setText(Messages.QtPreferencePage_0);
installsGroup.setLayout(new GridLayout(2, false));
Composite installTableComp = new Composite(installsGroup, SWT.NONE);
installTableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
installTable = new Table(installTableComp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
installTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
installTable.setHeaderVisible(true);
installTable.setLinesVisible(true);
installTable.addListener(SWT.Selection, e -> {
TableItem[] items = installTable.getSelection();
removeButton.setEnabled(items.length > 0);
});
TableColumn nameColumn = new TableColumn(installTable, SWT.NONE);
nameColumn.setText(Messages.QtPreferencePage_1);
TableColumn locationColumn = new TableColumn(installTable, SWT.NONE);
locationColumn.setText(Messages.QtPreferencePage_2);
TableColumnLayout tableLayout = new TableColumnLayout();
tableLayout.setColumnData(nameColumn, new ColumnWeightData(25, 50, true));
tableLayout.setColumnData(locationColumn, new ColumnWeightData(75, 150, true));
installTableComp.setLayout(tableLayout);
Composite buttonsComp = new Composite(installsGroup, SWT.NONE);
buttonsComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
buttonsComp.setLayout(new GridLayout());
Button addButton = new Button(buttonsComp, SWT.PUSH);
addButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
addButton.setText(Messages.QtPreferencePage_3);
addButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
NewQtInstallWizard wizard = new NewQtInstallWizard(getInstalls());
WizardDialog dialog = new WizardDialog(getShell(), wizard);
if (dialog.open() == Window.OK) {
IQtInstall install = wizard.getInstall();
installsToAdd.put(install.getName(), install);
updateTable();
}
}
});
removeButton = new Button(buttonsComp, SWT.PUSH);
removeButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
removeButton.setText(Messages.QtPreferencePage_4);
removeButton.setEnabled(false);
removeButton.addListener(SWT.Selection, e -> {
if (MessageDialog.openConfirm(getShell(), Messages.QtPreferencePage_5,
Messages.QtPreferencePage_6)) {
for (TableItem item : installTable.getSelection()) {
IQtInstall install = (IQtInstall) item.getData();
installsToRemove.put(install.getName(), install);
updateTable();
}
}
});
updateTable();
return control;
}
private Map<String, IQtInstall> getInstalls() {
Map<String, IQtInstall> installs = new HashMap<>();
for (IQtInstall install : manager.getInstalls()) {
installs.put(install.getName(), install);
}
for (IQtInstall install : installsToAdd.values()) {
installs.put(install.getName(), install);
}
for (IQtInstall install : installsToRemove.values()) {
installs.remove(install.getName());
}
return installs;
}
private void updateTable() {
List<IQtInstall> sorted = new ArrayList<>(getInstalls().values());
Collections.sort(sorted, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
installTable.clearAll();
for (IQtInstall install : sorted) {
TableItem item = new TableItem(installTable, SWT.NONE);
item.setText(0, install.getName());
item.setText(1, install.getQmakePath().toString());
item.setData(install);
}
}
@Override
public boolean performOk() {
for (IQtInstall install : installsToAdd.values()) {
manager.addInstall(install);
}
for (IQtInstall install : installsToRemove.values()) {
manager.removeInstall(install);
}
return true;
}
}