blob: f5fc912577733deae556040a83c6d429ae45f97c [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* 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 com.motorola.studio.android.videos.ui.views;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.ControlContribution;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.BrowserFunction;
import org.eclipse.swt.browser.ProgressAdapter;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.part.ViewPart;
import org.osgi.framework.Bundle;
import com.motorola.studio.android.common.log.StudioLogger;
import com.motorola.studio.android.common.log.UsageDataConstants;
import com.motorola.studio.android.common.utilities.EclipseUtils;
import com.motorola.studio.android.videos.Activator;
import com.motorola.studio.android.videos.i18n.VideosNLS;
import com.motorola.studio.android.videos.model.Video;
import com.motorola.studio.android.videos.model.VideoManager;
import com.motorola.studio.android.videos.ui.utils.UiUtilities;
/**
* The view that contains all MOTODEV Video Tutorials
*/
public class MOTODEVVideosView extends ViewPart
{
/*
* The ID of the view as specified by the extension.
*/
public static final String ID = "com.motorola.studio.android.videos.views.MOTODEVVideosView";
/*
* View state
*/
private final String OPEN_EXTERNAL_BROWSER_PREFERENCE = "open.external.browser";
/*
* Video Manager
*/
private VideoManager videoManager;
/*
* Resource constants
*/
private final String VIDEO_WATCH_EMBED_HTML = "resources/watch_video.html";
private final String VIDEO_WATCH_EMBED_HTML_JS_LIBRARY = "resources/swfobject.js";
private final String VIEW_LOADING_ICON = "icons/loading_icon.gif";
private final String VIEW_ERROR_ICON = "icons/error_icon.png";
/*
* Containers
*/
private Composite parentComposite = null;
private Composite container = null;
private VideosListComposite videosListComposite;
private SashForm sash;
private VideoPlayerComposite videoPlayerArea;
private String videoWatchURL;
private String videoWatchJSLibraryURL;
private Boolean flashPlayerSupport = null;
private Boolean isBrowserLoaded = null;
private static Boolean openExternalBrowser = null;
public static int PLAY_LISTENER = 43214321;
private Color backgroundColor = null;
private Image viewErrorImg = null;
private String loadingImgFullPath = null;
/* (non-Javadoc)
* @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
*/
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException
{
super.init(site, memento);
try
{
Device device = getDefaultImage().getDevice();
Bundle bundle = Activator.getDefault().getBundle();
Display display = getSite().getShell().getDisplay();
/*
* Retrieve view state
*/
if (openExternalBrowser == null && memento != null)
{
openExternalBrowser = memento.getBoolean(OPEN_EXTERNAL_BROWSER_PREFERENCE);
}
/*
* Colors
*/
backgroundColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
/*
* HTML to be embedded in the browser
*/
videoWatchURL =
FileLocator.toFileURL(bundle.getEntry(VIDEO_WATCH_EMBED_HTML)).getFile();
// using the method getAbsolutePath is necessary for this to work on all systems
videoWatchJSLibraryURL =
new Path(FileLocator.toFileURL(
bundle.getEntry(VIDEO_WATCH_EMBED_HTML_JS_LIBRARY)).getFile())
.toPortableString();
/*
* Images to be used
*/
viewErrorImg =
new Image(device, FileLocator.toFileURL(bundle.getEntry(VIEW_ERROR_ICON))
.getPath());
loadingImgFullPath =
FileLocator.toFileURL(
Activator.getDefault().getBundle().getEntry(VIEW_LOADING_ICON))
.getPath();
}
catch (IOException e)
{
StudioLogger.error(this.getClass(), "Error while initializing Videos View", e);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createPartControl(Composite parent)
{
// just point to the parent so that it can be accessed by the Job that will be created
parentComposite = parent;
clearContent();
/*
* Display a loading screen while the content is not loaded
*/
displayLoadingScreen(parent);
/*
* Create a Job to load the view content
*/
Job refreshViews = new Job(VideosNLS.UI_Job_Refresh_View)
{
@Override
protected IStatus run(IProgressMonitor monitor)
{
final Boolean[] showErrorComposite = new Boolean[1];
showErrorComposite[0] = false;
final String[] errorMessage = new String[1];
errorMessage[0] = null;
/*
* Try to load the videos information.
* If an exception is thrown, log the error and prepare to show
* the error screen
*/
try
{
videoManager = VideoManager.getInstance();
videoManager.load();
videoManager.sort(VideoManager.SORT_MOST_RECENT);
}
catch (Exception e)
{
showErrorComposite[0] = true;
errorMessage[0] = VideosNLS.UI_ErrorMsg + " " + e.getLocalizedMessage();
StudioLogger.error(this.getClass(), "Error while initializing Videos View", e);
}
if (!monitor.isCanceled())
{
/*
* Run the following code in the UI thread, whether it's the
* error screen or the videos screen itself. Also, disable the
* loading composite that is being displayed
*/
Display.getDefault().asyncExec(new Runnable()
{
public void run()
{
// dispose the loading composite
clearContent();
if (showErrorComposite[0])
{
// if an error occurred, display the error screen
displayErrorScreen(parentComposite, errorMessage[0]);
}
else
{
// ... otherwise, continue with the normal workflow
displayVideosScreen(parentComposite);
}
}
});
}
return Status.OK_STATUS;
}
@Override
public boolean belongsTo(Object family)
{
// relate the Job to this view
return getTitle().equals(family);
}
};
// Schedule the job to run
refreshViews.schedule();
}
/**
* Display the videos screen
*
* @param parent the parent composite
*/
private void displayVideosScreen(Composite parent)
{
// Create the main composite container
container = new Composite(parent, SWT.NONE);
container.setLayoutData(new GridData(GridData.FILL_BOTH));
container.setLayout(new GridLayout(1, false));
sash = new SashForm(container, SWT.VERTICAL | SWT.SMOOTH | SWT.BORDER);
sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// Create a global media player area, with the media player and info related to the video
createMediaPlayerAndToolbarArea(sash);
// Create videos list area
createVideosListArea(sash);
// Adjust the media player size then the view changes its size
sash.getChildren()[0].addControlListener(new ControlListener()
{
public void controlResized(ControlEvent e)
{
videoPlayerArea.adjustMediaPlayerSize(sash);
}
public void controlMoved(ControlEvent e)
{
//do nothing
}
});
sash.setWeights(new int[]
{
1, 2
});
parentComposite.layout();
}
/**
* Display the loading screen
*
* @param parent the parent composite
* @return the loading composite
*/
private void displayLoadingScreen(Composite parent)
{
container =
displayInfoScreen(parent, loadingImgFullPath, null, VideosNLS.UI_Loading, null,
false);
parentComposite.layout();
}
/**
* Display the error screen
*
* @param parent the parent composite
*/
private void displayErrorScreen(Composite parent, String error)
{
container = displayInfoScreen(parent, null, viewErrorImg, error, new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
EclipseUtils.openNetworkPreferences(getSite().getShell());
}
}, true);
parentComposite.layout();
}
/**
* Generic method that display a information message (loading, error, warning, etc) in
* the screen, being composed of an image, a text and possibly a reload button
*
* @param parent the parent composite
* @param imagePath path to the image that must be displayed
* @param image alternatively, if no path is provided (null), an Image object can be used
* @param message the message to be displayed (a Link will be used to display the message)
* @param selectionListener handler to be called when the user clicks on the message
* @param reloadButton whether a "reload" button should be displayed or not
* @return the composite created to construct the view
*/
private Composite displayInfoScreen(Composite parent, String imagePath, Image image,
String message, SelectionListener selectionListener, boolean reloadButton)
{
Composite mainComposite = new Composite(parent, SWT.NONE);
mainComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
mainComposite.setLayout(new GridLayout(1, false));
mainComposite.setBackground(backgroundColor);
Composite centeredComposite = new Composite(mainComposite, SWT.NONE);
centeredComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
centeredComposite.setLayout(new GridLayout(1, false));
centeredComposite.setBackground(backgroundColor);
/*
* Status image
*/
final Label infoImg = new Label(centeredComposite, SWT.NONE);
infoImg.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
infoImg.setBackground(backgroundColor);
// Checking the mime type doesn't work on Linux
// MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(new File(imagePath)).equals("image/gif"))
// Instead of "image/gif", it returns "application/octet-stream"
if (imagePath != null && imagePath.endsWith(".gif"))
{
UiUtilities.displayAnimatedGIF(getDefaultImage().getDevice(), imagePath, infoImg);
}
else if (image != null)
{
infoImg.setImage(image);
}
/*
* Status text
*/
Link infoText = new Link(centeredComposite, SWT.NONE);
GridData loadingTextGridData = new GridData(SWT.CENTER, SWT.NONE, true, false);
loadingTextGridData.verticalIndent = 10;
infoText.setLayoutData(loadingTextGridData);
infoText.setBackground(backgroundColor);
infoText.setText(message);
if (selectionListener != null)
{
infoText.addSelectionListener(selectionListener);
}
/*
* Reload button, if requested
*/
if (reloadButton)
{
Button button = new Button(centeredComposite, SWT.NONE);
GridData buttonGridData = new GridData(SWT.CENTER, SWT.NONE, false, false);
buttonGridData.verticalIndent = 10;
button.setLayoutData(buttonGridData);
button.setText(VideosNLS.UI_Reload);
button.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
reloadView();
}
});
}
return mainComposite;
}
/**
* Select the initial video to be displayed
* It's the first video of the first channel
*/
private void selectInitialVideo()
{
if (openExternalBrowser != null && !openExternalBrowser)
{
Video firstVideo = null;
try
{
firstVideo = videoManager.getActiveChannels().get(0).getVideos().get(0);
}
catch (Exception e)
{
StudioLogger.error(this.getClass(), "No initial video to set", e);
}
if (firstVideo != null)
{
playVideo(firstVideo);
}
videoPlayerArea.adjustVideoPlayerInitialSize();
}
}
/**
* Clear view content, i.e. remove everything being displayed
*/
private void clearContent()
{
if (container != null && !container.isDisposed())
{
container.dispose();
}
}
/**
* Try to reload the view
*/
private void reloadView()
{
createPartControl(parentComposite);
}
/**
* Create the view toolbar, with search field and a checkbox to
* define if the video must be displayed inside the view or in
* the external browser
*/
private void createToolBar()
{
ToolBarManager tbManager =
(ToolBarManager) getViewSite().getActionBars().getToolBarManager();
tbManager.add(new ToolbarContribution("MOTODEV Video Tutorials Toolbar"));
tbManager.update(true);
getViewSite().getActionBars().updateActionBars();
}
/**
* Create the area that contains the media player (browser embedded) as well as
* the information about the video being watched.
*
* Additionally, the toolbar are is also created after the browser is loaded, since
* it depends on information acquired during browser loading (such as browser compatibility
* and Flash Player availability)
*
* @param parent the parent SashForm composite
*/
private void createMediaPlayerAndToolbarArea(SashForm parent)
{
Composite newPage = new Composite(parent, SWT.BORDER);
GridLayout layout = new GridLayout(1, false);
layout.marginWidth = 1;
layout.marginHeight = 1;
newPage.setLayout(layout);
newPage.setVisible(false);
videoPlayerArea = new VideoPlayerComposite(newPage);
videoPlayerArea.createVideoPlayerArea(new Font(getDefaultImage().getDevice(), getSite()
.getShell().getDisplay().getSystemFont().getFontData()[0].getName(), 12, SWT.BOLD));
Browser browser = videoPlayerArea.getBrowser();
new FlashPlayerDetection(browser, "hasFlashPlayer");
// identify when the page is loaded
browser.addProgressListener(new ProgressAdapter()
{
@Override
public void completed(ProgressEvent event)
{
// only the first loading matters, so that we remove the listener,
// otherwise it would be called each time a new video is selected to
// be played
isBrowserLoaded = true;
videoPlayerArea.getBrowser().removeProgressListener(this);
/*
* The toolbar is only created when the embedded page is loaded
*/
createToolBar();
selectInitialVideo();
}
});
// Set the JavaScript library source (with the real path) and open the URL
File file = getVideoWatchHTML(videoWatchURL, videoWatchJSLibraryURL);
browser.setUrl(file.toString());
}
/**
* Get the HTML to be used in runtime, with the JavasScript library real path
* set. This is necessary because relative paths do not work, and loading
* the lib programmatically using JavaScript doesn't work on Linux and MacOS
* since this is a async process and the objects defined in the lib might not
* be loaded when you try to use them.
*
* @param fileURL the original HTML file
* @param javascriptSrc the JavaScript full path
* @return a file with the original HTML file, but with the JavasScript full path set
*/
private File getVideoWatchHTML(String fileURL, String javascriptSrc)
{
File tempFile = null;
BufferedReader bReader = null;
BufferedWriter bWriter = null;
FileReader fReader = null;
FileWriter fWriter = null;
try
{
// the original file
File originalFile = new File(fileURL);
// the temp file, with the same name as the original
String[] tempFileName = originalFile.getName().split("\\.");
tempFile = File.createTempFile(tempFileName[0], "." + tempFileName[1]);
tempFile.deleteOnExit();
/*
* Read the original file and copy it's content to the temp file,
* at the same time that the placeholders for the javascript library
* path is replaced by the real path(s)
*/
fReader = new FileReader(originalFile);
fWriter = new FileWriter(tempFile);
bReader = new BufferedReader(fReader);
bWriter = new BufferedWriter(fWriter);
String line;
StringBuffer stringBuffer = new StringBuffer();
while ((line = bReader.readLine()) != null)
{
stringBuffer.append(line);
}
bWriter.write(stringBuffer.toString().replace("@@JAVASCRIPT_SRC@@", javascriptSrc));
}
catch (IOException e)
{
StudioLogger.error(this.getClass(),
"Could not create the HTML to be diplayed in the Browser widget", e);
}
finally
{
// close both reader/writer
try
{
bWriter.close();
bReader.close();
fWriter.close();
fReader.close();
}
catch (IOException e)
{
StudioLogger.error(e.getMessage());
}
}
return tempFile;
}
/**
* Crate the tabs, which represent the playlists
*
* @param parent the parent composite
*/
private void createVideosListArea(Composite parent)
{
Composite newPage = new Composite(parent, SWT.NONE);
newPage.setLayout(new GridLayout(1, false));
videosListComposite =
new VideosListComposite(newPage, SWT.NONE, videoManager.getActiveChannels(),
videoManager.getDefaultChannel().getName());
videosListComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
videosListComposite.addListener(MOTODEVVideosView.PLAY_LISTENER, new Listener()
{
public void handleEvent(Event event)
{
playVideo((Video) event.data);
}
});
}
/**
* Play the video, whether using the internal or external browser
*
* @param video the video to be played
*/
private void playVideo(Video video)
{
if (openExternalBrowser == null || openExternalBrowser)
{
openVideoInExternalBrowser(video);
}
else
{
openVideoInEmbeddedBrowser(video);
}
// Log video playback
try
{
StudioLogger.collectUsageData(UsageDataConstants.WHAT_VIDEOS_PLAY,
UsageDataConstants.KIND_VIDEOS,
"Video Played: "
+ video.getId()
+ "|"
+ video.getTitle()
+ "|"
+ (openExternalBrowser != null ? openExternalBrowser.toString()
: "null"), Activator.PLUGIN_ID, Activator.getDefault()
.getBundle().getVersion().toString());
}
catch (Exception e)
{
// do nothing, just do that to be safe and to not break the functionality
// due to errors when logging usage information
}
}
/**
* Play the video using the embedded browser
*
* @param video the video to be played
*/
private void openVideoInEmbeddedBrowser(Video video)
{
videoPlayerArea.openVideo(video);
/*
* Select video in the list
*/
videosListComposite.setSelectedVideo(video);
parentComposite.layout();
/*
* Adjust size
*/
videoPlayerArea.adjustMediaPlayerSize(sash);
}
/**
* Open the external browser
*
* @param video the video to be opened
*/
private void openVideoInExternalBrowser(Video video)
{
IWorkbenchBrowserSupport browserSupport = PlatformUI.getWorkbench().getBrowserSupport();
IWebBrowser browser;
try
{
browser =
browserSupport.createBrowser(IWorkbenchBrowserSupport.LOCATION_BAR
| IWorkbenchBrowserSupport.NAVIGATION_BAR
| IWorkbenchBrowserSupport.AS_EXTERNAL, VideosNLS.UI_MOTODEV_Video
+ video.getTitle(), null, null);
browser.openURL(new URL(video.getExternalLink()));
}
catch (Exception e)
{
StudioLogger.error(this.getClass(), "Error opening video on external browser", e);
}
}
/**
* Filter videos in the UI based on the search results
*
* @param keyword search keyword
*/
private void searchAndFilter(String keyword)
{
// execute trim and remove duplicated blank spaces
keyword = removeDuplicatedBlankSpaces(keyword.trim());
// search and filter
videosListComposite.filter(videoManager.search(keyword), keyword.equals(""));
// highlight keywords
videosListComposite.highlightKeywords(keyword);
}
/**
* Remove all duplicated spaces in a given string
*
* @param text the string to have duplicated spaces removed
* @return the string passed as parameter with no duplicated spaces
*/
private String removeDuplicatedBlankSpaces(String text)
{
Pattern pattern = Pattern.compile("\\s+");
Matcher matcher = pattern.matcher(text);
matcher.find();
return matcher.replaceAll(" ");
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
@Override
public void dispose()
{
super.dispose();
if (container != null && !container.isDisposed())
{
container.dispose();
}
// cancel all jobs related to this view
Job.getJobManager().cancel(getTitle());
}
/*
* Save the view state when the workbench is closed
*
* @see org.eclipse.ui.part.ViewPart#saveState(org.eclipse.ui.IMemento)
*/
@Override
public void saveState(IMemento memento)
{
if (canPlayEmbeddedVideo() && openExternalBrowser != null)
{
memento.putBoolean(OPEN_EXTERNAL_BROWSER_PREFERENCE, openExternalBrowser);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
@Override
public void setFocus()
{
// nothing
}
/**
* Check if the browser can load web pages. Due to several problems of the
* Browser widget on Linux, we are disabling this feature on this OS for now.
*
* Some of the problems on Linux are:
* - Browser doesn't work with some proxies
* - Intermitent crashes of SWT
* - The Browser widget blinks on the screen
*
* For MacOS X, it's enabled only from Snow Leopard on (> 10.6), since the Browser
* widget might not work correctly in Leopard with Flash Player 64 bits, since the
* kernel modules themselves run in 32 bits, what causes a crash (Studio closes).
*
* @return "true" if the browser can load pages, "false" otherwise
*/
private boolean canPlayEmbeddedVideo()
{
Boolean result = false;
// for now, the correct version will only be analyzed on MacOSX
boolean correctVersion = true;
if (Platform.getOS().equals(Platform.OS_MACOSX))
{
String versionText = System.getProperty("os.version");
// Get the version as a number
float versionNumber = 0;
try
{
if (!versionText.contains("."))
{
versionNumber = Integer.parseInt(versionText);
}
else
{
String[] versionPieces = versionText.split("\\.");
versionNumber =
Float.parseFloat(versionPieces[0] + "."
+ (!versionPieces[1].equals("") ? versionPieces[1] : "0"));
}
}
catch (NumberFormatException e)
{
StudioLogger.error(this.getClass(), "Cannot get the OS version", e);
}
// Leopard = 10.5 = not supported
if (versionNumber <= 10.5)
{
correctVersion = false;
}
}
// If we are not on Linux and the MacOS X has the correct version,
// check if the browser could load the web page and, consequently,
// if the flash player is supported or not
if (!Platform.getOS().equals(Platform.OS_LINUX) && correctVersion)
{
if (isBrowserLoaded != null && isBrowserLoaded && flashPlayerSupport != null)
{
result = true;
}
}
// Log player support
try
{
StudioLogger.collectUsageData(UsageDataConstants.WHAT_VIDEOS_PLAYER_SUPPORT,
UsageDataConstants.KIND_VIDEOS, result.toString() + "|" + Platform.getOS()
+ "|" + correctVersion, Activator.PLUGIN_ID, Activator.getDefault()
.getBundle().getVersion().toString());
}
catch (Exception e)
{
// do nothing, just do that to be safe and to not break the functionality
// due to errors when logging usage information
}
return result;
}
/**
* Check if an appropriate version of Flash Player was found, which
* means that the videos can be displayed in the embedded browser
*
* @return "true" if an appropriate version of Flash Player was found, "false" otherwise
*/
private boolean hasFlashPlayer()
{
Boolean result = false;
if (isBrowserLoaded != null && isBrowserLoaded && flashPlayerSupport != null)
{
result = flashPlayerSupport;
}
// Log flash player support
try
{
StudioLogger.collectUsageData(UsageDataConstants.WHAT_VIDEOS_PLAYER_SUPPORT,
UsageDataConstants.KIND_VIDEOS, result.toString(), Activator.PLUGIN_ID,
Activator.getDefault().getBundle().getVersion().toString());
}
catch (Exception e)
{
// do nothing, just do that to be safe and to not break the functionality
// due to errors when logging usage information
}
return result;
}
/**
* Get the message that will be displayed to the user to inform that
* the appropriate version of Flash Player was not found
*
* @return the "no Flash Player" message
*/
private String getNoFlashMessage()
{
String message = VideosNLS.UI_No_Flash_Player + " ";
if (Platform.getOSArch().equals(Platform.ARCH_X86))
{
// 32 bits
message +=
NLS.bind(VideosNLS.UI_No_Flash_Player_32bits_Extension,
VideosNLS.UI_Flash_Player_Link_32bits);
}
else
{
// 64 bits
message +=
NLS.bind(VideosNLS.UI_No_Flash_Player_64bits_Extension,
VideosNLS.UI_Flash_Player_Link_64bits);
}
return message;
}
/**
* Create the toolbar, with a search field and a checkbox to
* define if the video must be displayed inside the view or in
* the external browser
*/
private class ToolbarContribution extends ControlContribution
{
protected ToolbarContribution(String id)
{
super(id);
}
@Override
protected Control createControl(Composite parent)
{
Composite toolbarComposite = new Composite(parent, SWT.NONE);
toolbarComposite.setLayout(new RowLayout(SWT.HORIZONTAL));
final Text searchText = new Text(toolbarComposite, SWT.SEARCH);
searchText.setLayoutData(new RowData(150, SWT.DEFAULT));
searchText.setMessage(VideosNLS.UI_Search);
searchText.addModifyListener(new ModifyListener()
{
public void modifyText(ModifyEvent e)
{
searchAndFilter(searchText.getText());
}
});
if (canPlayEmbeddedVideo())
{
// recover the state, if there is flash player
// if there is NO flash player, the checkbox is always selected
boolean enablement = hasFlashPlayer();
boolean selection =
!enablement ? true : openExternalBrowser != null ? openExternalBrowser
: false;
final Button openExternal = new Button(toolbarComposite, SWT.CHECK);
openExternal.setText(VideosNLS.UI_Open_External_Browser);
openExternal.setToolTipText(VideosNLS.UI_Open_External_Browser);
openExternal.setEnabled(enablement);
openExternal.setSelection(selection);
openExternalBrowser = selection;
if (!enablement)
{
Label warningImg = new Label(toolbarComposite, SWT.NONE);
warningImg.setImage(PlatformUI.getWorkbench().getSharedImages()
.getImage(ISharedImages.IMG_OBJS_WARN_TSK));
warningImg.setToolTipText(getNoFlashMessage());
}
openExternal.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
openExternalBrowser = openExternal.getSelection();
}
});
}
return toolbarComposite;
}
}
/**
* Function called from JavaScript to inform if the browser
* could find Adobe Flash Player or not
*/
private class FlashPlayerDetection extends BrowserFunction
{
@Override
public Object function(Object[] arguments)
{
flashPlayerSupport = new Boolean(arguments[0].toString());
return null;
}
public FlashPlayerDetection(Browser browser, String name)
{
super(browser, name);
}
}
}