blob: 95569ac24f695ecdbecf9e797fca844c92fed531 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Movidius Inc. and others
*
* All rights reserved. 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:
* Robert Kiss - Initial API and implementation
* Mikael Ferland - Enable resizing of symbol provider dialogs
*
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.symbols;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferencePageContainer;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tracecompass.internal.tmf.ui.symbols.Messages;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
/**
* This class shall be used to configure one or more {@link ISymbolProvider}. It
* receives an array of {@link ISymbolProviderPreferencePage} and creates a
* dialog that can be used to configure the corresponding providers. If the
* {@link #open()} method exits with {@link IDialogConstants#OK_ID} the caller
* shall assume that the corresponding {@link ISymbolProvider}'s have a new
* configuration.
*
*
* @author Robert Kiss
* @since 2.0
*/
public class SymbolProviderConfigDialog extends TitleAreaDialog implements IPreferencePageContainer {
private ISymbolProviderPreferencePage[] fPreferencePages;
private CTabItem[] fPageTabs;
private CTabFolder fTabFolder;
private IRunnableWithProgress configJob = (monitor) -> {
// saving the configuration is fast and need UI access
SymbolProviderConfigDialog.this.getContents().getDisplay().syncExec(() -> {
for (int i = 0; i < fPreferencePages.length; i++) {
ISymbolProviderPreferencePage page = fPreferencePages[i];
page.saveConfiguration();
}
});
monitor.beginTask(Messages.SymbolProviderConfigDialog_loadingConfigurations, fPreferencePages.length * 100);
try {
for (int i = 0; i < fPreferencePages.length; i++) {
ISymbolProviderPreferencePage page = fPreferencePages[i];
page.getSymbolProvider().loadConfiguration(monitor);
monitor.worked(100);
}
} finally {
monitor.done();
}
};
/**
* Create a new dialog that will use the given shall and preference pages.
*
* @param parentShell
* The parent shell
* @param pages
* the pages that provides the configuration UI for
* {@link ISymbolProvider}'s. The array shall not be empty and
* shall not contain null elements.
*
*/
public SymbolProviderConfigDialog(Shell parentShell, ISymbolProviderPreferencePage... pages) {
super(parentShell);
fPreferencePages = pages;
}
@Override
protected Control createDialogArea(Composite parent) {
getShell().setText(Messages.SymbolProviderConfigDialog_title);
setTitle(Messages.SymbolProviderConfigDialog_title);
setMessage(Messages.SymbolProviderConfigDialog_message);
Composite composite = (Composite) super.createDialogArea(parent);
composite.setLayout(new GridLayout());
// if we have one single provider that we don't need a tab
if (fPreferencePages.length == 1) {
attachPreference(composite, fPreferencePages[0]);
updateMessage(0);
} else {
fTabFolder = new CTabFolder(composite, SWT.NONE);
fTabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));
fPageTabs = new CTabItem[fPreferencePages.length];
for (int i = 0; i < fPreferencePages.length; i++) {
ISymbolProviderPreferencePage page = fPreferencePages[i];
fPageTabs[i] = new CTabItem(fTabFolder, SWT.NONE);
fPageTabs[i].setText(page.getTitle());
Composite child = new Composite(fTabFolder, SWT.NONE);
child.setLayout(new GridLayout());
child.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true));
fPageTabs[i].setControl(child);
attachPreference(child, page);
updateMessage(i);
}
fTabFolder.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateMessage(fTabFolder.indexOf((CTabItem) e.item));
}
});
}
return composite;
}
@Override
protected boolean isResizable() {
return true;
}
@Override
public boolean isHelpAvailable() {
return false;
}
private void attachPreference(Composite composite, ISymbolProviderPreferencePage page) {
page.setContainer(this);
page.createControl(composite);
page.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
}
@Override
public IPreferenceStore getPreferenceStore() {
// not used
return null;
}
@Override
public void updateTitle() {
// not used
}
@Override
public void updateButtons() {
// nothing to do
}
@Override
protected void okPressed() {
boolean cancel = false;
try {
new ProgressMonitorDialog(getShell()).run(true, false, configJob);
} catch (InvocationTargetException e) {
setMessage(e.getMessage(), IMessageProvider.ERROR);
cancel = true;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (!cancel) {
super.okPressed();
}
TmfSignalManager.dispatchSignal(new TmfSymbolProviderUpdatedSignal(this));
}
@Override
public void updateMessage() {
if (fTabFolder == null) {
updateMessage(0);
return;
}
int curSelectionIndex = fTabFolder.getSelectionIndex();
if (curSelectionIndex >= 0) {
updateMessage(curSelectionIndex);
}
}
private void updateMessage(int pageIndex) {
ISymbolProviderPreferencePage currentPage = fPreferencePages[pageIndex];
String message = currentPage.getMessage();
String errorMessage = currentPage.getErrorMessage();
int messageType = IMessageProvider.NONE;
if (errorMessage != null) {
message = errorMessage;
messageType = IMessageProvider.ERROR;
}
setMessage(message, messageType);
if (fPreferencePages.length > 1) {
// update the corresponding tab icon
if (messageType == IMessageProvider.ERROR) {
fPageTabs[pageIndex].setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_ERROR_TSK));
} else {
fPageTabs[pageIndex].setImage(null);
}
}
}
}