/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright 2008 Pentaho Corporation. All rights reserved.
*
* Created Mar 25, 2008
* @author Michael D'Amour
*/
package org.pentaho.mantle.client.solutionbrowser.tabs;
import java.util.Set;
import java.util.Stack;
import org.pentaho.mantle.client.objects.SolutionFileInfo;
import org.pentaho.mantle.client.solutionbrowser.filelist.FileItem;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.IFrameElement;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.NamedFrame;
import com.google.gwt.user.client.ui.VerticalPanel;
public class IFrameTabPanel extends VerticalPanel {
private String url;
private String name;
private CustomFrame frame;
private SolutionFileInfo fileInfo;
private FormPanel form;
private boolean saveEnabled, editContentEnabled, editContentSelected;
// We hold onto a Javascript object that gets various notifications of PUC events.
// (edit content button clicked, etc.)
protected JavaScriptObject jsCallback;
private Set<String> overlayIds;
public IFrameTabPanel() {
this.name = "" + System.currentTimeMillis();
this.frame = new CustomFrame(name, "about:blank");
add(frame);
}
public IFrameTabPanel(String url) {
this.url = url;
this.name = "" + System.currentTimeMillis();
this.frame = new CustomFrame(name, url); //$NON-NLS-1$
add(frame);
}
public IFrameTabPanel(String name, String url) {
this.url = url;
this.name = name;
setSaveEnabled(url.endsWith("analysisview.xaction")); //$NON-NLS-1$
frame = new CustomFrame(name, url);
frame.getElement().setAttribute("id", name); //$NON-NLS-1$
frame.setWidth("100%"); //$NON-NLS-1$
frame.setHeight("100%"); //$NON-NLS-1$
add(frame);
}
public void reload() {
if (form != null) {
form.submit();
} else {
// frame.setUrl(getCurrentUrl());
reloadFrame(frame.getElement());
}
}
public native void reloadFrame(Element frameElement)
/*-{
frameElement.contentWindow.location.reload();
}-*/;
public void back() {
frame.back();
}
public void setFileInfo(SolutionFileInfo info) {
fileInfo = info;
}
public void setFileInfo(FileItem item) {
SolutionFileInfo fileInfo = new SolutionFileInfo();
fileInfo.setName(item.getName());
fileInfo.setSolution(item.getSolution());
fileInfo.setPath(item.getPath());
setFileInfo(fileInfo);
}
public SolutionFileInfo getFileInfo() {
return fileInfo;
}
/*
* frame.getUrl returns the original URL, but not the current one. This method accesses the DOM directly to get that URL
*/
private String getCurrentUrl() {
return IFrameElement.as(this.frame.getElement()).getContentDocument().getURL();
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public void openTabInNewWindow() {
Window.open(getCurrentUrl(), "_blank", ""); //$NON-NLS-1$ //$NON-NLS-2$
}
public NamedFrame getFrame() {
return frame;
}
public void setFrame(CustomFrame frame) {
this.frame = frame;
}
public FormPanel getForm() {
return form;
}
public void setForm(FormPanel form) {
this.form = form;
}
public class CustomFrame extends NamedFrame {
private boolean ignoreNextHistoryAdd = false;
private Stack<String> history = new Stack<String>();
private CustomFrame(String name) {
super(name);
}
private CustomFrame(String name, String url) {
super(name);
setUrl(url);
}
public void back() {
if (!history.empty()) {
ignoreNextHistoryAdd = true;
frame.setUrl(history.pop());
}
}
public void addHistory(String url) {
if (ignoreNextHistoryAdd || url.equals("about:blank")) { //$NON-NLS-1$
ignoreNextHistoryAdd = false;
return;
}
history.add(url);
}
@Override
protected void onAttach() {
super.onAttach();
attachEventListeners(frame.getElement(), this);
}
public native void attachEventListeners(Element ele, CustomFrame frame)
/*-{
var iwind = ele.contentWindow; //IFrame's window instance
var funct = function(event){
event = iwind.parent.translateInnerMouseEvent(ele, event);
iwind.parent.sendMouseEvent(event);
}
// Hooks up mouse and unload events
$wnd.hookEvents = function(wind){
try{
if(wind == null){
wind = $wnd.watchWindow
}
wind.onmouseup = funct;
wind.onmousedown = funct;
wind.onmousemove = funct;
wind.onunload = unloader;
wind.mantleEventsIn = true;
$wnd.watchWindow = null;
} catch(e){
//You're most likely here because of Cross-site scripting permissions... consuming
}
}
// IFrame URL watching code
// Called on iFrame unload, calls containing Window to start monitoring it for Url change
var unloader = function(event){
frame.@org.pentaho.mantle.client.solutionbrowser.tabs.IFrameTabPanel$CustomFrame::addHistory(Ljava/lang/String;)(iwind.location.href);
$wnd.startIFrameWatcher(iwind);
}
// Starts the watching loop.
$wnd.startIFrameWatcher = function(wind){
$wnd.watchWindow = wind;
$wnd.setTimeout("rehookEventsTimer()", 300);
}
// loop that's started when an iFrame unloads, when the url changes it adds back in the hooks
$wnd.rehookEventsTimer = function(){
if($wnd.watchWindow.mantleEventsIn == undefined){
//location changed hook back up event interceptors
$wnd.setTimeout("hookEvents()", 300);
} else {
$wnd.setTimeout("rehookEventsTimer()", 300);
}
}
// Scope helper funct.
function rehookEventsTimer(){
$wnd.rehookEventsTimer();
}
//Hook up the mouse and unload event handlers for iFrame being created
$wnd.hookEvents(iwind);
}-*/;
}
public boolean isSaveEnabled() {
return saveEnabled;
}
public void setSaveEnabled(boolean enabled) {
saveEnabled = enabled;
}
public Set<String> getOverlayIds() {
return overlayIds;
}
public void addOverlay(String id) {
overlayIds.add(id);
}
public void setEditEnabled(boolean enable) {
this.editContentEnabled = enable;
}
public boolean isEditEnabled() {
return editContentEnabled;
}
public void setEditSelected(boolean selected) {
this.editContentSelected = selected;
}
public boolean isEditSelected() {
return this.editContentSelected;
}
/**
* Return the JavaScript callback object registered to receive notifications regarding this tab's content.
*
* @return JavaScriptObject callback
*/
public JavaScriptObject getContentCallback() {
return jsCallback;
}
public void setContentCallback(JavaScriptObject callback) {
this.jsCallback = callback;
}
}