/* * 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.editors; import org.jkiss.dbeaver.Log; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.widgets.*; import org.jkiss.dbeaver.model.edit.DBECommandReflector; import org.jkiss.dbeaver.model.edit.prop.DBECommandProperty; import org.jkiss.dbeaver.model.edit.prop.DBEPropertyHandler; import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.utils.CommonUtils; import java.util.Calendar; import java.util.Date; /** * Abstract object command */ public class ControlPropertyCommandListener<OBJECT_TYPE extends DBSObject> { private static final Log log = Log.getLog(ControlPropertyCommandListener.class); private final AbstractDatabaseObjectEditor<OBJECT_TYPE> objectEditor; private final Widget widget; private final DBEPropertyHandler<OBJECT_TYPE> handler; private Object originalValue; //private Object newValue; private DBECommandProperty<OBJECT_TYPE> curCommand; public static <OBJECT_TYPE extends DBSObject> void create( AbstractDatabaseObjectEditor<OBJECT_TYPE> objectEditor, Widget widget, DBEPropertyHandler<OBJECT_TYPE> handler) { new ControlPropertyCommandListener<>(objectEditor, widget, handler); } public ControlPropertyCommandListener( AbstractDatabaseObjectEditor<OBJECT_TYPE> objectEditor, Widget widget, DBEPropertyHandler<OBJECT_TYPE> handler) { this.objectEditor = objectEditor; this.widget = widget; this.handler = handler; WidgetListener listener = new WidgetListener(); widget.addListener(SWT.FocusIn, listener); widget.addListener(SWT.FocusOut, listener); widget.addListener(SWT.Modify, listener); widget.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { //widget.removeListener(); } }); } private Object readWidgetValue() { if (widget == null || widget.isDisposed()) { return null; } if (widget instanceof Text) { return ((Text)widget).getText(); } else if (widget instanceof Combo) { return ((Combo)widget).getText(); } else if (widget instanceof Button) { return ((Button)widget).getSelection(); } else if (widget instanceof Spinner) { return ((Spinner)widget).getSelection(); } else if (widget instanceof List) { return ((List)widget).getSelection(); } else if (widget instanceof DateTime) { DateTime dateTime = (DateTime) widget; Calendar cl = Calendar.getInstance(); cl.set(Calendar.YEAR, dateTime.getYear()); cl.set(Calendar.MONTH, dateTime.getMonth()); cl.set(Calendar.DAY_OF_MONTH, dateTime.getDay()); cl.set(Calendar.HOUR_OF_DAY, dateTime.getHours()); cl.set(Calendar.MINUTE, dateTime.getMinutes()); cl.set(Calendar.SECOND, dateTime.getSeconds()); cl.set(Calendar.MILLISECOND, 0); return cl.getTime(); } else { log.warn("Control " + widget + " is not supported"); return null; } } private void writeWidgetValue(Object value) { if (widget == null || widget.isDisposed()) { return; } if (widget instanceof Text) { ((Text)widget).setText(CommonUtils.toString(value)); } else if (widget instanceof Combo) { ((Combo)widget).setText(CommonUtils.toString(value)); } else if (widget instanceof Button) { ((Button)widget).setSelection(value != null && Boolean.TRUE.equals(value)); } else if (widget instanceof Spinner) { ((Spinner)widget).setSelection(CommonUtils.toInt(value)); } else if (widget instanceof List) { ((List)widget).setSelection((String[])value); } else if (widget instanceof DateTime) { DateTime dateTime = (DateTime) widget; Calendar cl = Calendar.getInstance(); cl.setTime((Date)value); dateTime.setYear(cl.get(Calendar.YEAR)); dateTime.setMonth(cl.get(Calendar.MONTH)); dateTime.setDay(cl.get(Calendar.DAY_OF_MONTH)); dateTime.setHours(cl.get(Calendar.HOUR_OF_DAY)); dateTime.setMinutes(cl.get(Calendar.MINUTE)); dateTime.setSeconds(cl.get(Calendar.SECOND)); } else { // not supported log.warn("Control " + widget + " is not supported"); } } private class WidgetListener implements Listener { @Override public void handleEvent(Event event) { switch (event.type) { case SWT.FocusIn: { originalValue = readWidgetValue(); break; } case SWT.FocusOut: { // Forgot current command if (curCommand != null) { curCommand = null; } break; } case SWT.Modify: { final Object newValue = readWidgetValue(); DBECommandReflector<OBJECT_TYPE, DBECommandProperty<OBJECT_TYPE>> commandReflector = new DBECommandReflector<OBJECT_TYPE, DBECommandProperty<OBJECT_TYPE>>() { @Override public void redoCommand(DBECommandProperty<OBJECT_TYPE> command) { writeWidgetValue(command.getNewValue()); } @Override public void undoCommand(DBECommandProperty<OBJECT_TYPE> command) { writeWidgetValue(command.getOldValue()); } }; if (curCommand == null) { if (!CommonUtils.equalObjects(newValue, originalValue)) { curCommand = new DBECommandProperty<>(objectEditor.getDatabaseObject(), handler, originalValue, newValue);; objectEditor.addChangeCommand(curCommand, commandReflector); } } else { if (CommonUtils.equalObjects(originalValue, newValue)) { objectEditor.removeChangeCommand(curCommand); curCommand = null; } else { curCommand.setNewValue(newValue); objectEditor.updateChangeCommand(curCommand, commandReflector); } } break; } } } } }