/* * MainWindowObject.java * * Copyright (C) 2009-16 by RStudio, Inc. * * Unless you have received this program directly from RStudio pursuant * to the terms of a commercial license agreement with RStudio, then * this program is licensed to you under the terms of version 3 of the * GNU Affero General Public License. This program is distributed WITHOUT * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. * */ package org.rstudio.studio.client.workbench; import org.rstudio.studio.client.workbench.addins.Addins.RAddins; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.user.client.Window; /** * This class can be used to get / set fields on the main window from satellite * windows. You should only use this when passing along POD JavaScript objects * or 'primitive' Java types that GWT can easily handle, e.g. String, Integer. */ public class MainWindowObject<T> { private interface DefaultProvider<V> { V defaultValue(); } private MainWindowObject(String key, DefaultProvider<T> provider) { key_ = key; provider_ = provider; } public final void set(T value) { JavaScriptObject rstudioObject = getRStudioObject(getRStudioMainWindow()); setImpl(key_, value, rstudioObject); } @SuppressWarnings("unchecked") public final T get() { JavaScriptObject rstudioObject = getRStudioObject(getRStudioMainWindow()); if (!hasImpl(key_, rstudioObject)) return provider_.defaultValue(); // Work around JDK 1.6 compiler issues with casting from JSO to T JavaScriptObject object = getImpl(key_, rstudioObject); T casted = (T) object; return casted; } // Private Methods ---- private static final native <T> void setImpl(String key, T value, JavaScriptObject object) /*-{ object[key] = value; }-*/; private static final native JavaScriptObject getImpl(String key, JavaScriptObject object) /*-{ return object[key]; }-*/; private static final native boolean hasImpl(String key, JavaScriptObject object) /*-{ return object.hasOwnProperty(key); }-*/; private static final native Window getRStudioMainWindow() /*-{ for (var wnd = $wnd; wnd != null; wnd = wnd.opener) if (!!wnd.$RStudio) return wnd; return $wnd; }-*/; private static final native JavaScriptObject getRStudioObject(Window wnd) /*-{ return wnd.$RStudio; }-*/; private final String key_; private final DefaultProvider<T> provider_; // Helper Classes ---- public static final MainWindowObject<String> lastFocusedEditor() { return new MainWindowObject<String>(LAST_FOCUSED_EDITOR, new DefaultProvider<String>() { @Override public String defaultValue() { return ""; } }); } public static final MainWindowObject<String> lastFocusedWindow() { return new MainWindowObject<String>(LAST_FOCUSED_WINDOW, new DefaultProvider<String>() { @Override public String defaultValue() { return ""; } }); } public static final MainWindowObject<String> lastFocusedSourceWindow() { return new MainWindowObject<String>(LAST_FOCUSED_SOURCE_WINDOW, new DefaultProvider<String>() { @Override public String defaultValue() { return ""; } }); } public static final MainWindowObject<RAddins> rAddins() { return new MainWindowObject<RAddins>(R_ADDINS, new DefaultProvider<RAddins>() { @Override public RAddins defaultValue() { return RAddins.createDefault(); } }); } private static final String LAST_FOCUSED_EDITOR = "last_focused_editor"; private static final String LAST_FOCUSED_WINDOW = "last_focused_window"; private static final String LAST_FOCUSED_SOURCE_WINDOW = "last_focused_source_window"; private static final String R_ADDINS = "r_addins"; }