/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
*
* Licensed 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.jkiss.dbeaver.ui.dialogs;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWizard;
import org.jkiss.dbeaver.ui.ICompositeDialogPage;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.utils.ArrayUtils;
import java.lang.reflect.InvocationTargetException;
/**
* MultiPageWizardDialog
*/
public class MultiPageWizardDialog extends TitleAreaDialog implements IWizardContainer {
private IWizard wizard;
private Composite pageArea;
private Tree pagesTree;
private IDialogPage prevPage;
private ProgressMonitorPart monitorPart;
private SashForm wizardSash;
private volatile int runningOperations = 0;
public MultiPageWizardDialog(IWorkbenchWindow window, IWizard wizard)
{
this(window, wizard, null);
}
public MultiPageWizardDialog(IWorkbenchWindow window, IWizard wizard, IStructuredSelection selection)
{
super(window.getShell());
this.wizard = wizard;
this.wizard.setContainer(this);
// Initialize wizard
if (wizard instanceof IWorkbenchWizard) {
if (selection == null) {
if (window.getSelectionService().getSelection() instanceof IStructuredSelection) {
selection = (IStructuredSelection)window.getSelectionService().getSelection();
}
}
((IWorkbenchWizard)wizard).init(window.getWorkbench(), selection);
}
}
public IWizard getWizard()
{
return wizard;
}
@Override
protected boolean isResizable()
{
return true;
}
@Override
protected int getShellStyle()
{
return SWT.TITLE | SWT.MAX | SWT.RESIZE | SWT.APPLICATION_MODAL;
}
@Override
protected Control createContents(Composite parent)
{
Control contents = super.createContents(parent);
updateButtons();
return contents;
}
@Override
protected Control createDialogArea(Composite parent)
{
Composite composite = (Composite)super.createDialogArea(parent);
wizard.addPages();
wizardSash = new SashForm(composite, SWT.HORIZONTAL);
wizardSash.setLayoutData(new GridData(GridData.FILL_BOTH));
pagesTree = new Tree(wizardSash, SWT.SINGLE);
pagesTree.setLayoutData(new GridData(GridData.FILL_BOTH));
Composite pageContainer = UIUtils.createPlaceholder(wizardSash, 2);
// Vertical separator
new Label(pageContainer, SWT.SEPARATOR | SWT.VERTICAL)
.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
pageArea = UIUtils.createPlaceholder(pageContainer, 1);
GridData gd = new GridData(GridData.FILL_BOTH);
pageArea.setLayoutData(gd);
pageArea.setLayout(new GridLayout(1, true));
wizardSash.setWeights(new int[]{300, 700});
Point maxSize = new Point(0, 0);
IWizardPage[] pages = wizard.getPages();
for (IWizardPage page : pages) {
addPage(null, page, maxSize);
}
gd = (GridData) pageArea.getLayoutData();
gd.widthHint = 500;
gd.heightHint = 400;
pagesTree.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e)
{
changePage();
}
});
// Select first page
pagesTree.select(pagesTree.getItem(0));
changePage();
// Set title and image from first page
IDialogPage firstPage = (IDialogPage) pagesTree.getItem(0).getData();
setTitle(firstPage.getTitle());
setTitleImage(firstPage.getImage());
setMessage(firstPage.getMessage());
// Horizontal separator
new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR)
.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// Progress monitor
monitorPart = new ProgressMonitorPart(composite, null, true) {
@Override
public void setCanceled(boolean b) {
super.setCanceled(b);
if (b) {
cancelCurrentOperation();
}
}
};
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.grabExcessHorizontalSpace = true;
gd.horizontalIndent = 20;
gd.verticalIndent = 0;
monitorPart.setLayoutData(gd);
monitorPart.setVisible(false);
return composite;
}
protected void cancelCurrentOperation() {
}
private TreeItem addPage(TreeItem parentItem, IDialogPage page, Point maxSize)
{
TreeItem item = parentItem == null ?
new TreeItem(pagesTree, SWT.NONE) :
new TreeItem(parentItem, SWT.NONE);
item.setText(page.getTitle());
item.setData(page);
// Ad sub pages
if (page instanceof ICompositeDialogPage) {
IDialogPage[] subPages = ((ICompositeDialogPage) page).getSubPages();
if (!ArrayUtils.isEmpty(subPages)) {
for (IDialogPage subPage : subPages) {
addPage(item, subPage, maxSize);
}
item.setExpanded(true);
}
}
return item;
}
private void changePage()
{
pageArea.setRedraw(false);
try {
TreeItem[] selection = pagesTree.getSelection();
if (selection.length != 1) {
return;
}
TreeItem newItem = selection[0];
if (prevPage == newItem.getData()) {
return;
}
GridData gd;
if (prevPage != null) {
gd = (GridData) prevPage.getControl().getLayoutData();
gd.exclude = true;
prevPage.setVisible(false);
}
boolean pageCreated = false;
IDialogPage page = (IDialogPage) newItem.getData();
Control pageControl = page.getControl();
if (pageControl == null) {
// Create page contents
page.createControl(pageArea);
pageControl = page.getControl();
//Point pageSize = pageControl.computeSize(SWT.DEFAULT, SWT.DEFAULT);
//if (pageSize.x > maxSize.x) maxSize.x = pageSize.x;
//if (pageSize.y > maxSize.y) maxSize.y = pageSize.y;
gd = (GridData) pageControl.getLayoutData();
if (gd == null) {
gd = new GridData(GridData.FILL_BOTH);
pageControl.setLayoutData(gd);
}
gd.exclude = false;
pageCreated = true;
}
gd = (GridData) pageControl.getLayoutData();
gd.exclude = false;
page.setVisible(true);
setTitle(page.getTitle());
setMessage(page.getDescription());
prevPage = page;
pageArea.layout();
if (pageCreated) {
UIUtils.resizeShell(getWizard().getContainer().getShell());
}
} finally {
pageArea.setRedraw(true);
}
}
@Override
protected void buttonPressed(int buttonId)
{
if (buttonId == IDialogConstants.CANCEL_ID) {
getWizard().performCancel();
} else if (buttonId == IDialogConstants.OK_ID) {
if (!getWizard().performFinish()) {
return;
}
}
super.buttonPressed(buttonId);
}
@Override
public IWizardPage getCurrentPage()
{
TreeItem[] selection = pagesTree.getSelection();
if (ArrayUtils.isEmpty(selection)) {
return null;
}
IDialogPage page = (IDialogPage)selection[0].getData();
return page instanceof IWizardPage ? (IWizardPage) page : null;
}
@Override
public void showPage(IWizardPage page)
{
for (TreeItem item : pagesTree.getItems()) {
if (item.getData() == page) {
pagesTree.setSelection(item);
changePage();
break;
}
for (TreeItem child : item.getItems()) {
if (child.getData() == page) {
pagesTree.setSelection(child);
changePage();
return;
}
}
}
}
@Override
public void updateButtons()
{
boolean complete = true;
for (TreeItem item : pagesTree.getItems()) {
if (item.getData() instanceof IWizardPage) {
IWizardPage page = (IWizardPage) item.getData();
if (page.getControl() != null && !page.isPageComplete()) {
complete = false;
break;
}
}
}
Button button = getButton(IDialogConstants.OK_ID);
if (button != null && !button.isDisposed()) {
button.setEnabled(complete);
}
}
@Override
public void updateMessage()
{
}
@Override
public void updateTitleBar()
{
}
@Override
public void updateWindowTitle()
{
}
public boolean close() {
if (runningOperations > 0) {
return false;
}
return super.close();
}
@Override
public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException
{
// Code copied from WizardDialog
if (monitorPart != null) {
monitorPart.setVisible(true);
monitorPart.layout();
monitorPart.attachToCancelComponent(null);
}
ControlEnableState pageEnableState = ControlEnableState.disable(wizardSash);
ControlEnableState buttonsEnableState = ControlEnableState.disable(getButtonBar());
try {
runningOperations++;
ModalContext.run(runnable, true, monitorPart, getShell().getDisplay());
} finally {
runningOperations--;
buttonsEnableState.restore();
pageEnableState.restore();
if (monitorPart != null) {
monitorPart.done();
monitorPart.setVisible(false);
}
}
}
}