/*
* 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.core;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.*;
import org.eclipse.ui.services.IDisposable;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.DBeaverPreferences;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.access.DBAAuthInfo;
import org.jkiss.dbeaver.model.runtime.*;
import org.jkiss.dbeaver.runtime.DummyRunnableContext;
import org.jkiss.dbeaver.runtime.RunnableContextDelegate;
import org.jkiss.dbeaver.runtime.ui.DBUICallback;
import org.jkiss.dbeaver.runtime.ui.DBUserInterface;
import org.jkiss.dbeaver.ui.*;
import org.jkiss.dbeaver.ui.dialogs.connection.BaseAuthDialog;
import org.jkiss.dbeaver.ui.views.process.ProcessPropertyTester;
import org.jkiss.dbeaver.ui.views.process.ShellProcessView;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* DBeaver UI core
*/
public class DBeaverUI implements DBUICallback {
private static final Log log = Log.getLog(DBeaverUI.class);
private static DBeaverUI instance;
private SharedTextColors sharedTextColors;
private TrayIconHandler trayItem;
private final List<IDisposable> globalDisposables = new ArrayList<>();
public static DBeaverUI getInstance() {
if (instance == null) {
instance = new DBeaverUI();
instance.initialize();
}
return instance;
}
static void disposeUI() {
if (instance != null) {
try {
instance.dispose();
} catch (Throwable e) {
log.error(e);
}
}
}
public static SharedTextColors getSharedTextColors() {
return getInstance().sharedTextColors;
}
public static void run(
IRunnableContext runnableContext,
boolean fork,
boolean cancelable,
final DBRRunnableWithProgress runnableWithProgress)
throws InvocationTargetException, InterruptedException {
runnableContext.run(fork, cancelable, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
runnableWithProgress.run(RuntimeUtils.makeMonitor(monitor));
}
});
}
private void dispose() {
this.sharedTextColors.dispose();
if (trayItem != null) {
trayItem.hide();
}
List<IDisposable> dispList = new ArrayList<>(globalDisposables);
Collections.reverse(dispList);
for (IDisposable disp : dispList) {
try {
disp.dispose();
} catch (Exception e) {
log.error(e);
}
globalDisposables.remove(disp);
}
}
private void initialize() {
this.sharedTextColors = new SharedTextColors();
this.trayItem = new TrayIconHandler();
DBUserInterface.setInstance(this);
// Register context listener
WorkbenchContextListener.registerInWorkbench();
/* // Global focus lister for debug
Display.getCurrent().addFilter(SWT.FocusIn, new Listener() {
@Override
public void handleEvent(Event event) {
System.out.println("FOCUS TO: " + event.widget);
}
});
*/
}
public static AbstractUIJob runUIJob(String jobName, final DBRRunnableWithProgress runnableWithProgress) {
return runUIJob(jobName, 0, runnableWithProgress);
}
public static AbstractUIJob runUIJob(String jobName, int timeout, final DBRRunnableWithProgress runnableWithProgress) {
AbstractUIJob job = new AbstractUIJob(jobName) {
@Override
public IStatus runInUIThread(DBRProgressMonitor monitor) {
try {
runnableWithProgress.run(monitor);
} catch (InvocationTargetException e) {
return GeneralUtils.makeExceptionStatus(e);
} catch (InterruptedException e) {
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
};
job.setSystem(true);
job.schedule(timeout);
return job;
}
@NotNull
public static IWorkbenchWindow getActiveWorkbenchWindow() {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
if (window != null) {
return window;
}
IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
if (windows.length > 0) {
return windows[0];
}
throw new IllegalStateException("No workbench window");
}
public static Shell getActiveWorkbenchShell() {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
if (window != null) {
return window.getShell();
} else {
return Display.getDefault().getActiveShell();
}
}
public static Display getDisplay() {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
if (window != null) {
return window.getShell().getDisplay();
} else {
return Display.getDefault();
}
}
/*
public static void runWithProgress(IWorkbenchPartSite site, final DBRRunnableWithProgress runnable)
throws InvocationTargetException, InterruptedException
{
IActionBars actionBars = null;
if (site instanceof IViewSite) {
actionBars = ((IViewSite) site).getActionBars();
} else if (site instanceof IEditorSite) {
actionBars = ((IEditorSite) site).getActionBars();
}
IStatusLineManager statusLineManager = null;
if (actionBars != null) {
statusLineManager = actionBars.getStatusLineManager();
}
if (statusLineManager == null) {
runInProgressService(runnable);
} else {
IProgressMonitor progressMonitor = statusLineManager.getProgressMonitor();
runnable.run(new DefaultProgressMonitor(progressMonitor));
}
}
*/
public static DBRRunnableContext getDefaultRunnableContext() {
IWorkbench workbench = PlatformUI.getWorkbench();
if (workbench != null && workbench.getActiveWorkbenchWindow() != null) {
return new RunnableContextDelegate(workbench.getActiveWorkbenchWindow());
} else {
return new DBRRunnableContext() {
@Override
public void run(boolean fork, boolean cancelable, DBRRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
runnable.run(new VoidProgressMonitor());
}
};
}
}
/**
* Runs task in Eclipse progress service.
* NOTE: this call can't be canceled if it will block in IO
*/
public static void runInProgressService(final DBRRunnableWithProgress runnable)
throws InvocationTargetException, InterruptedException {
getDefaultRunnableContext().run(true, true, new DBRRunnableWithProgress() {
@Override
public void run(DBRProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
runnable.run(monitor);
}
});
}
/**
* Runs task in Eclipse progress dialog.
* NOTE: this call can't be canceled if it will block in IO
*/
public static void runInProgressDialog(final DBRRunnableWithProgress runnable) throws InvocationTargetException {
try {
IRunnableContext runnableContext;
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
if (workbenchWindow != null) {
runnableContext = new ProgressMonitorDialog(workbench.getActiveWorkbenchWindow().getShell());
} else {
runnableContext = workbench.getProgressService();
}
runnableContext.run(true, true, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
runnable.run(RuntimeUtils.makeMonitor(monitor));
}
});
} catch (InterruptedException e) {
// do nothing
}
}
public static void runInUI(IRunnableContext context, final DBRRunnableWithProgress runnable) {
try {
PlatformUI.getWorkbench().getProgressService().runInUI(context, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
runnable.run(RuntimeUtils.makeMonitor(monitor));
}
}, DBeaverActivator.getWorkspace().getRoot());
} catch (InvocationTargetException e) {
UIUtils.showErrorDialog(null, null, null, e.getTargetException());
} catch (InterruptedException e) {
// do nothing
}
}
public static void runInUI(final DBRRunnableWithProgress runnable) {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
IRunnableContext context = window != null ? window : DummyRunnableContext.INSTANCE;
runInUI(context, runnable);
}
public static void asyncExec(Runnable runnable) {
try {
getDisplay().asyncExec(runnable);
} catch (Exception e) {
log.debug(e);
}
}
public static void syncExec(Runnable runnable) {
try {
getDisplay().syncExec(runnable);
} catch (Exception e) {
log.debug(e);
}
}
public static <T> T syncExec(RunnableWithResult<T> runnable) {
try {
getDisplay().syncExec(runnable);
return runnable.getResult();
} catch (Exception e) {
log.debug(e);
return null;
}
}
public static void notifyAgent(String message, int status) {
if (!DBeaverCore.getGlobalPreferenceStore().getBoolean(DBeaverPreferences.AGENT_LONG_OPERATION_NOTIFY)) {
// Notifications disabled
return;
}
getInstance().trayItem.notify(message, status);
}
@Override
public void showError(@NotNull String title, @Nullable String message, @NotNull IStatus status) {
UIUtils.showErrorDialog(null, title, message, status);
}
@Override
public void showError(@NotNull String title, @Nullable String message, @NotNull Throwable e) {
UIUtils.showErrorDialog(null, title, message, e);
}
@Override
public void showError(@NotNull String title, @Nullable String message) {
UIUtils.showErrorDialog(null, title, message);
}
@Override
public DBAAuthInfo promptUserCredentials(String prompt, String userName, String userPassword, boolean passwordOnly) {
// Ask user
final Shell shell = DBeaverUI.getActiveWorkbenchShell();
final BaseAuthDialog authDialog = new BaseAuthDialog(shell, prompt, passwordOnly);
if (!passwordOnly) {
authDialog.setUserName(userName);
}
authDialog.setUserPassword(userPassword);
if (new UIConfirmation() {
@Override
public Boolean runTask() {
return (authDialog.open() == IDialogConstants.OK_ID);
}
}.execute()) {
return authDialog.getAuthInfo();
}
return null;
}
@Override
public void executeProcess(final DBRProcessDescriptor processDescriptor) {
processDescriptor.setProcessListener(new DBRProcessListener() {
@Override
public void onProcessStarted() {
ProcessPropertyTester.firePropertyChange(ProcessPropertyTester.PROP_RUNNING);
}
@Override
public void onProcessTerminated(int resultCode) {
ProcessPropertyTester.firePropertyChange(ProcessPropertyTester.PROP_RUNNING);
}
});
// Direct execute
try {
processDescriptor.execute();
} catch (DBException e) {
showError("Execute process", processDescriptor.getName(), e);
}
if (processDescriptor.getCommand().isShowProcessPanel()) {
asyncExec(new Runnable() {
@Override
public void run() {
try {
final ShellProcessView processView =
(ShellProcessView) DBeaverUI.getActiveWorkbenchWindow().getActivePage().showView(
ShellProcessView.VIEW_ID,
ShellProcessView.getNextId(),
IWorkbenchPage.VIEW_VISIBLE
);
processView.initProcess(processDescriptor);
} catch (PartInitException e) {
log.error(e);
}
}
});
}
}
}