提交 fd880e45 编写于 作者: S serge-rider

#3278 Database notifications model

上级 1b96f70d
......@@ -136,8 +136,6 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.e4.ui.workbench.renderers.swt,
org.eclipse.e4.ui.css.core,
org.eclipse.e4.ui.css.swt,
org.eclipse.mylyn.commons.notifications.core,
org.eclipse.mylyn.commons.notifications.ui,
org.jkiss.dbeaver.runtime.ide.core,
org.jkiss.dbeaver.runtime.ide.ui
Bundle-Localization: OSGI-INF/l10n/bundle
......@@ -3762,14 +3762,16 @@
<extension point="org.eclipse.mylyn.commons.notifications.ui.notifications">
<category id="org.jkiss.dbeaver.notifications.database.category" label="Database"/>
<sink id="org.jkiss.dbeaver.notifications.sink.Popup" class="org.jkiss.dbeaver.ui.notifications.DatabaseNotificationSink" label="Desktop Popup"/>
<event categoryId="org.jkiss.dbeaver.notifications.database.category" id="org.jkiss.dbeaver.notifications.event.commit" label="Commit">
<defaultHandler sinkId="org.eclipse.mylyn.commons.notifications.sink.Popup"/>
<defaultHandler sinkId="org.jkiss.dbeaver.notifications.sink.Popup"/>
<description>
This event is triggered when transaction was committed.
</description>
</event>
<event categoryId="org.jkiss.dbeaver.notifications.database.category" id="org.jkiss.dbeaver.notifications.event.rollback" label="Rollback">
<defaultHandler sinkId="org.eclipse.mylyn.commons.notifications.sink.Popup"/>
<defaultHandler sinkId="org.jkiss.dbeaver.notifications.sink.Popup"/>
<description>
This event is triggered when transaction was rolled back.
</description>
......
......@@ -18,21 +18,17 @@ package org.jkiss.dbeaver.ui.actions.datasource;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.mylyn.commons.notifications.core.AbstractNotification;
import org.eclipse.mylyn.commons.notifications.ui.NotificationsUi;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.DBPMessageType;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.qm.QMTransactionState;
import org.jkiss.dbeaver.model.qm.QMUtils;
import org.jkiss.dbeaver.runtime.TasksJob;
import org.jkiss.dbeaver.ui.actions.AbstractDataSourceHandler;
import org.jkiss.dbeaver.ui.notifications.DatabaseNotification;
import org.jkiss.dbeaver.ui.notifications.NotificationUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
public class DataSourceCommitHandler extends AbstractDataSourceHandler
{
......@@ -57,16 +53,12 @@ public class DataSourceCommitHandler extends AbstractDataSourceHandler
throw new InvocationTargetException(e);
}
AbstractNotification notification = new DatabaseNotification(
NotificationUtils.sendNotification(
context.getDataSource(),
"commit",
"Transaction has been committed\n\n" +
"Query count: " + txnInfo.getUpdateCount() + "\n" +
"Duration: " + RuntimeUtils.formatExecutionTime(System.currentTimeMillis() - txnInfo.getTransactionStartTime()) + "\n",
DBPMessageType.WARNING, null);
NotificationsUi.getService().notify(
Collections.singletonList(notification));
"Duration: " + RuntimeUtils.formatExecutionTime(System.currentTimeMillis() - txnInfo.getTransactionStartTime()) + "\n");
/*
NotificationPopupMessage.showMessage(
context.getDataSource(),
......
......@@ -16,6 +16,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.ui.views,
org.eclipse.ui.workbench.texteditor,
org.eclipse.mylyn.commons.ui,
org.eclipse.mylyn.commons.notifications.core,
org.eclipse.mylyn.commons.notifications.ui,
org.jkiss.dbeaver.model
Export-Package: org.jkiss.dbeaver.ui,
......
package org.jkiss.dbeaver.ui.notifications;
import org.eclipse.mylyn.internal.commons.notifications.ui.popup.NotificationPopup;
import org.eclipse.swt.widgets.Shell;
public class DatabaseNotificationPopup extends NotificationPopup {
public DatabaseNotificationPopup(Shell parent) {
super(parent);
setDelayClose(3000);
}
}
\ No newline at end of file
package org.jkiss.dbeaver.ui.notifications;
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.preference.IPreferenceStore;
import org.eclipse.jface.window.Window;
import org.eclipse.mylyn.commons.notifications.core.AbstractNotification;
import org.eclipse.mylyn.commons.notifications.core.NotificationSink;
import org.eclipse.mylyn.commons.notifications.core.NotificationSinkEvent;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import java.util.*;
public class DatabaseNotificationSink extends NotificationSink {
private static final long DELAY_OPEN = 200;
private static final boolean runSystem = true;
private final WeakHashMap<Object, Object> cancelledTokens = new WeakHashMap<>();
private final Set<AbstractNotification> notifications = new HashSet<>();
private final Set<AbstractNotification> currentlyNotifying = Collections.synchronizedSet(notifications);
private final Job openJob = new Job("Database notifications") {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
if (Platform.isRunning() && PlatformUI.getWorkbench() != null
&& PlatformUI.getWorkbench().getDisplay() != null
&& !PlatformUI.getWorkbench().getDisplay().isDisposed()) {
PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
collectNotifications();
if (popup != null && popup.getReturnCode() == Window.CANCEL) {
List<AbstractNotification> notifications = popup.getNotifications();
for (AbstractNotification notification : notifications) {
if (notification.getToken() != null) {
cancelledTokens.put(notification.getToken(), null);
}
}
}
currentlyNotifying.removeIf(notification -> notification.getToken() != null
&& cancelledTokens.containsKey(notification.getToken()));
synchronized (DatabaseNotificationSink.class) {
if (currentlyNotifying.size() > 0) {
// popup.close();
showPopup();
}
}
});
}
} finally {
if (popup != null) {
schedule(popup.getDelayClose() / 2);
}
}
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
};
private DatabaseNotificationPopup popup;
public DatabaseNotificationSink() {
openJob.setSystem(runSystem);
}
private void cleanNotified() {
currentlyNotifying.clear();
}
/** public for testing */
private void collectNotifications() {
}
/**
* public for testing purposes
*/
public Set<AbstractNotification> getNotifications() {
synchronized (DatabaseNotificationSink.class) {
return currentlyNotifying;
}
}
private boolean isAnimationsEnabled() {
IPreferenceStore store = PlatformUI.getPreferenceStore();
return store.getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS);
}
@Override
public void notify(NotificationSinkEvent event) {
currentlyNotifying.addAll(event.getNotifications());
if (!openJob.cancel()) {
try {
openJob.join();
} catch (InterruptedException e) {
// ignore
}
}
openJob.schedule(DELAY_OPEN);
}
private void showPopup() {
if (popup != null) {
popup.close();
}
Shell shell = new Shell(PlatformUI.getWorkbench().getDisplay());
popup = new DatabaseNotificationPopup(shell);
popup.setFadingEnabled(isAnimationsEnabled());
List<AbstractNotification> toDisplay = new ArrayList<>(currentlyNotifying);
Collections.sort(toDisplay);
popup.setContents(toDisplay);
cleanNotified();
popup.setBlockOnOpen(false);
popup.open();
}
}
\ No newline at end of file
package org.jkiss.dbeaver.ui.notifications;
import org.eclipse.mylyn.commons.ui.dialogs.AbstractNotificationPopup;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.utils.GeneralUtils;
public abstract class NotificationPopup extends AbstractNotificationPopup {
public NotificationPopup(Display display) {
super(display);
}
public NotificationPopup(Display display, int style) {
super(display, style);
}
}
\ No newline at end of file
......@@ -2,8 +2,6 @@ package org.jkiss.dbeaver.ui.notifications;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
......@@ -11,14 +9,14 @@ import org.eclipse.ui.PlatformUI;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.utils.GeneralUtils;
public class NotificationPopupMessage extends NotificationPopup {
public class NotificationPopupMessage extends DatabaseNotificationPopup {
private final DBPDataSource dataSource;
private String messageText;
private int iconType;
public NotificationPopupMessage(DBPDataSource dataSource, String text, int iconType) {
super(PlatformUI.getWorkbench().getDisplay());
super(PlatformUI.getWorkbench().getDisplay().getActiveShell());
this.dataSource = dataSource;
this.messageText = text;
......
package org.jkiss.dbeaver.ui.notifications;
import org.eclipse.mylyn.commons.notifications.core.AbstractNotification;
import org.eclipse.mylyn.commons.notifications.ui.NotificationsUi;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPMessageType;
import java.util.Collections;
public abstract class NotificationUtils {
public static void sendNotification(DBPDataSource dataSource, String id, String text) {
sendNotification(dataSource, id, text, null, null);
}
public static void sendNotification(DBPDataSource dataSource, String id, String text, DBPMessageType messageType, Runnable feedback) {
AbstractNotification notification = new DatabaseNotification(
dataSource,
id,
text,
messageType,
feedback);
NotificationsUi.getService().notify(
Collections.singletonList(notification));
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册