/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2014 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.server.ngclient; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; import org.json.JSONObject; import org.sablo.websocket.CurrentWindow; import org.sablo.websocket.IServerService; import com.servoy.j2db.RuntimeWindowManager; import com.servoy.j2db.persistence.Form; import com.servoy.j2db.scripting.JSWindow; import com.servoy.j2db.scripting.RuntimeWindow; /** * @author jcompagner * */ @SuppressWarnings("nls") public class NGRuntimeWindowManager extends RuntimeWindowManager implements IServerService { public static final String WINDOW_SERVICE = "$windowService"; private String lastCurrentWindow = null; /** * @param application */ public NGRuntimeWindowManager(INGApplication application) { super(application); application.getWebsocketSession().registerServerService(WINDOW_SERVICE, this); } /* * (non-Javadoc) * * @see com.servoy.j2db.server.ngclient.IService#executeMethod(java.lang.String, java.util.Map) */ @Override public Object executeMethod(String methodName, JSONObject args) { switch (methodName) { case "windowClosing" : { NGRuntimeWindow window = getWindow(args.optString("window")); if (window != null) { return Boolean.valueOf(window.hide()); } break; } case "touchForm" : { String formName = args.optString("name"); if (formName != null) { Form form = application.getFormManager().getPossibleForm(formName); if (form == null) { form = application.getFlattenedSolution().getForm(formName); if (form != null) { // new form, add it in form manager application.getFormManager().addForm(form, false); } } if (form != null) { NGClientWindow.getCurrentWindow().touchForm(application.getFlattenedSolution().getFlattenedForm(form), formName, true); } } break; } case "resize" : { String windowName = args.has("name") ? args.optString("name") : null; JSONObject size = args.optJSONObject("size"); if (size != null) { NGRuntimeWindow window = windowName == null ? (NGRuntimeWindow)getMainApplicationWindow() : getWindow(windowName); if (window != null) window.updateSize(size.optInt("width"), size.optInt("height")); } break; } case "move" : { String windowName = args.optString("name"); JSONObject location = args.optJSONObject("location"); if (windowName != null && location != null) { NGRuntimeWindow window = getWindow(windowName); if (window != null) window.updateLocation(location.optInt("x"), location.optInt("y")); } break; } } return null; } /* * (non-Javadoc) * * @see com.servoy.j2db.RuntimeWindowManager#getMainApplicationWindow() */ @Override protected RuntimeWindow getMainApplicationWindow() { String windowId = CurrentWindow.exists() ? CurrentWindow.get().getUuid() : null; return windowId != null ? getWindow(windowId) : null; } /* * (non-Javadoc) * * @see com.servoy.j2db.RuntimeWindowManager#getWindow(java.lang.String) */ @Override public NGRuntimeWindow getWindow(String windowName) { return windowName == null ? (NGRuntimeWindow)getMainApplicationWindow() : (NGRuntimeWindow)super.getWindow(windowName); } @Override public NGRuntimeWindow getCurrentWindow() { // This will return a the last used if no current window is set // so that code that is run through a scheduler or databroadcast will have a current container in scripting // getCurrentWindowName will return null so that the system can still know the difference. (NGEvent that resets the current window) NGRuntimeWindow currentWindow = (NGRuntimeWindow)super.getCurrentWindow(); return currentWindow != null ? currentWindow : getWindow(lastCurrentWindow); } @Override public String getCurrentWindowName() { // this will return null if there is no current active window set. // getCurrentWindow above does behave a bit different it will always return the last used window // if there is no current window set, this way Scheduler jobs or other runnables that can run (on data broadcast) // will just use the last used window as the current one return super.getCurrentWindowName(); } /* * (non-Javadoc) * * @see com.servoy.j2db.RuntimeWindowManager#setCurrentWindowName(java.lang.String) */ @Override public void setCurrentWindowName(String currentWindowName) { if (currentWindowName != null) lastCurrentWindow = currentWindowName; super.setCurrentWindowName(currentWindowName); } @Override protected RuntimeWindow createWindowInternal(String windowName, int type, RuntimeWindow parent) { ((INGApplication)application).getWebsocketSession().getClientService(NGRuntimeWindowManager.WINDOW_SERVICE).executeAsyncServiceCall("create", new Object[] { windowName, String.valueOf(type) }); if (parent == null && CurrentWindow.exists()) { // try to always just set the current parent if it is null // this way we can later on use this to set the window back. parent = getWindow(CurrentWindow.get().getUuid()); } return new NGRuntimeWindow((INGApplication)application, windowName, type, parent); } @Override protected List<String> getOrderedContainers() { // return them unordered for now, we do not have the order info in ngclient yet return new ArrayList<String>(windows.keySet()); } public void createMainWindow(String windowsUUID) { if (getWindow(windowsUUID) == null) { RuntimeWindow mainApplicationWindow = createWindow(windowsUUID, JSWindow.WINDOW, null); mainApplicationWindow.setLocation(0, 0); //default values, that never change setCurrentWindowName(windowsUUID); } } public void destroy(boolean keepMainApplicationWindow) { List<Entry<String, RuntimeWindow>> copy = new ArrayList<>(windows.entrySet()); for (Entry<String, RuntimeWindow> we : copy) { RuntimeWindow rw = we.getValue(); if (rw != null) { if (rw instanceof NGRuntimeWindow) { ((NGRuntimeWindow)rw).setController(null); } if (keepMainApplicationWindow && rw.equals(getMainApplicationWindow())) { continue; } if (rw instanceof NGRuntimeWindow) { rw.destroy(); } } windows.remove(we.getKey()); } } }