diff options
Diffstat (limited to 'src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/MOTODEVVideosView.java')
-rw-r--r-- | src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/MOTODEVVideosView.java | 1077 |
1 files changed, 1077 insertions, 0 deletions
diff --git a/src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/MOTODEVVideosView.java b/src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/MOTODEVVideosView.java new file mode 100644 index 0000000..f5fc912 --- /dev/null +++ b/src/plugins/videos/src/com/motorola/studio/android/videos/ui/views/MOTODEVVideosView.java @@ -0,0 +1,1077 @@ +/* + * 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); + } + + } + +}
\ No newline at end of file |