/*
* Jampa
* Copyright (C) 2008-2009 J. Devauchelle and contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 3 as published by the Free Software Foundation.
*
* 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 General Public License for more details.
*/
package org.jampa.gui.views;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.Util;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.part.ViewPart;
import org.jampa.Activator;
import org.jampa.controllers.Controller;
import org.jampa.controllers.events.EventConstants;
import org.jampa.gui.actions.PlayAction;
import org.jampa.gui.dialogs.PodcastItemPropertiesDialog;
import org.jampa.gui.translations.Messages;
import org.jampa.model.IAudioItem;
import org.jampa.model.podcasts.Podcast;
import org.jampa.model.podcasts.PodcastItem;
import org.jampa.net.podcast.PodcastItemDownloaderJob;
import org.jampa.net.podcast.PodcastUpdaterJob;
import org.jampa.utils.ApplicationUtils;
import org.jampa.utils.Utils;
public class PodcastView extends ViewPart implements PropertyChangeListener {
public static String ID = "Jampa.PodcastView"; //$NON-NLS-1$
private TableViewer viewer = null;
private String _id;
private Podcast _thePodcast;
private Image _playImage;
private Image _pauseImage;
private Image _podcastReadImage;
private Image _podcastUnreadImage;
private Image _podcastCachedReadImage;
private Image _podcastCachedUnreadImage;
private Image _titleImage;
private Image _titlePlayImage;
private Image _titlePauseImage;
private Image _markReadImage;
private Image _markUnreadImage;
private Action _markReadAction;
private Action _markUnreadAction;
private Action _refreshAction;
private Menu _viewMenu = null;
class ViewContentProvider implements IStructuredContentProvider {
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
// do nothing
}
public void dispose() {
// do nothing
}
public Object[] getElements(Object parent) {
return Controller.getInstance().getPlaylistController().getPodcastData(_id);
}
}
class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
private Image getPlayImage(Object obj) {
if (Controller.getInstance().getEngine().isPaused())
return _pauseImage;
else
return _playImage;
}
private Image getReadImage(Object obj) {
PodcastItem item = (PodcastItem) obj;
if (item.isRead()) {
if (item.doesTemporaryFileExists()) {
return _podcastCachedReadImage;
} else {
return _podcastReadImage;
}
} else {
if (item.doesTemporaryFileExists()) {
return _podcastCachedUnreadImage;
} else {
return _podcastUnreadImage;
}
}
}
public Image getColumnImage(Object obj, int index) {
if (index == 0) {
if (((IAudioItem) obj).isBoPlaying())
return getPlayImage(obj);
else
return null;
} else if (index == 1) {
return getReadImage(obj);
} else
return null;
}
public String getColumnText(Object obj, int index) {
String result;
switch (index) {
case 1 : result = ""; break;//Boolean.toString(((PodcastItem) obj).isRead()); break;
case 2 : result = ((PodcastItem) obj).getPropertiesList().get(PodcastItem.PODCAST_NAME); break;
case 3 : result = ((PodcastItem) obj).getDisplayDate(); break;
case 4 : result = Utils.seconds2String(((PodcastItem) obj).getDuration()); break;
default : result = ""; //$NON-NLS-1$
}
return result;
}
}
public PodcastView() {
Activator.getDefault();
ImageDescriptor playImageDescriptor = Activator.getImageDescriptor("/icons/playing_16.png"); //$NON-NLS-1$
_playImage = playImageDescriptor.createImage();
ImageDescriptor pauseImageDescriptor = Activator.getImageDescriptor("/icons/pause_16.png"); //$NON-NLS-1$
_pauseImage = pauseImageDescriptor.createImage();
ImageDescriptor titleImageDescriptor = Activator.getImageDescriptor("/icons/rss_16.png"); //$NON-NLS-1$
_titleImage = titleImageDescriptor.createImage();
ImageDescriptor podcastReadImageDescriptor = Activator.getImageDescriptor("/icons/rss_check_16.png"); //$NON-NLS-1$
_podcastReadImage = podcastReadImageDescriptor.createImage();
ImageDescriptor podcastUnreadImageDescriptor = Activator.getImageDescriptor("/icons/rss_16.png"); //$NON-NLS-1$
_podcastUnreadImage = podcastUnreadImageDescriptor.createImage();
ImageDescriptor titlePlayImageDescriptor = Activator.getImageDescriptor("/icons/rss_play_16.png"); //$NON-NLS-1$
_podcastCachedReadImage = Activator.getImageDescriptor("/icons/rss_check_cached_16.png").createImage(); //$NON-NLS-1$
_podcastCachedUnreadImage = Activator.getImageDescriptor("/icons/rss_cached_16.png").createImage(); //$NON-NLS-1$
_titlePlayImage = titlePlayImageDescriptor.createImage();
ImageDescriptor titlePauseImageDescriptor = Activator.getImageDescriptor("/icons/rss_pause_16.png"); //$NON-NLS-1$
_titlePauseImage = titlePauseImageDescriptor.createImage();
ImageDescriptor markReadImageDescriptor = Activator.getImageDescriptor("/icons/podcast_mark_read_16.png"); //$NON-NLS-1$
_markReadImage = markReadImageDescriptor.createImage();
ImageDescriptor markUnreadImageDescriptor = Activator.getImageDescriptor("/icons/podcast_mark_unread_16.png"); //$NON-NLS-1$
_markUnreadImage = markUnreadImageDescriptor.createImage();
}
@Override
public void createPartControl(Composite parent) {
_id = this.getViewSite().getSecondaryId();
_thePodcast = Controller.getInstance().getPlaylistController().getPodcastByName(_id);
this.setPartName(getViewTitle());
if (ApplicationUtils.doesEngineSupportPodcasts()) {
if ((Controller.getInstance().getPlaylistController().getCurrentPlaylist() != null) &&
(Controller.getInstance().getPlaylistController().getCurrentPlaylist().getName().equals(_id))) {
if (Controller.getInstance().getEngine().isPaused())
this.setTitleImage(_titlePauseImage);
else
this.setTitleImage(_titlePlayImage);
} else {
this.setTitleImage(_titleImage);
}
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
TableLayout layout = new TableLayout();
layout.addColumnData(new ColumnWeightData(5, 20, true));
layout.addColumnData(new ColumnWeightData(10, 25, true));
layout.addColumnData(new ColumnWeightData(250, 150, true));
layout.addColumnData(new ColumnWeightData(200, 150, true));
layout.addColumnData(new ColumnWeightData(200, 150, true));
viewer.getTable().setLayout(layout);
// Lines visible is ugly under Windows.
if (!Util.isWindows()) {
viewer.getTable().setLinesVisible(true);
}
viewer.getTable().setHeaderVisible(true);
TableColumn columnIcon = new TableColumn(viewer.getTable(), SWT.NONE);
columnIcon.setText(""); //$NON-NLS-1$
TableColumn readTitle = new TableColumn(viewer.getTable(), SWT.NONE);
readTitle.setText(""); //$NON-NLS-1$
TableColumn columnTitle = new TableColumn(viewer.getTable(), SWT.NONE);
columnTitle.setText(Messages.getString("PodcastView.Title")); //$NON-NLS-1$
TableColumn dateTitle = new TableColumn(viewer.getTable(), SWT.NONE);
dateTitle.setText(Messages.getString("PodcastView.Date")); //$NON-NLS-1$
TableColumn durationTitle = new TableColumn(viewer.getTable(), SWT.NONE);
durationTitle.setText(Messages.getString("PodcastView.Duration")); //$NON-NLS-1$
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setInput(getViewSite());
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
ISelection selection = viewer.getSelection();
Object obj = ((IStructuredSelection)selection).getFirstElement();
new PlayAction(_thePodcast, (PodcastItem) obj).run();
}
});
buildMenu(parent);
buildActions();
Controller.getInstance().getEventController().addAudioItemChangeListener(this);
Controller.getInstance().getEventController().addPodcastsUpdateChangeListener(this);
} else {
this.setContentDescription(String.format(Messages.getString("PodcastListView.PodcastsNotSupported"), //$NON-NLS-1$
Controller.getInstance().getEngine().getEngineType()));
}
}
private void setSelectionReadState(boolean newState) {
Object obj;
ISelection selection = viewer.getSelection();
Iterator<?> iter = ((IStructuredSelection)selection).iterator();
while (iter.hasNext()) {
obj = iter.next();
if ((obj != null) &&
(obj instanceof PodcastItem)) {
((PodcastItem) obj).setRead(newState);
}
}
Controller.getInstance().getEventController().fireAudioItemChange(EventConstants.EVT_ITEM_CHANGE_IN_PLAYLIST, null, null);
}
private void downloadSelection() {
Object obj;
ISelection selection = viewer.getSelection();
Iterator<?> iter = ((IStructuredSelection) selection).iterator();
while (iter.hasNext()) {
obj = iter.next();
if ((obj != null) &&
(obj instanceof PodcastItem)) {
new PodcastItemDownloaderJob(_thePodcast, (PodcastItem) obj, false).schedule();
}
}
}
private void buildActions() {
_markReadAction = new Action(Messages.getString("PodcastView.MarkRead")) { //$NON-NLS-1$
public void run() {
_thePodcast.setReadStatus(true);
Controller.getInstance().getEventController().fireAudioItemChange(EventConstants.EVT_ITEM_CHANGE_IN_PLAYLIST, null, null);
}
};
_markReadAction.setImageDescriptor(Activator.getImageDescriptor("/icons/podcast_mark_read_16.png"));
_markUnreadAction = new Action(Messages.getString("PodcastView.MarkUnread")) { //$NON-NLS-1$
public void run() {
_thePodcast.setReadStatus(false);
Controller.getInstance().getEventController().fireAudioItemChange(EventConstants.EVT_ITEM_CHANGE_IN_PLAYLIST, null, null);
}
};
_markUnreadAction.setImageDescriptor(Activator.getImageDescriptor("/icons/podcast_mark_unread_16.png"));
_refreshAction = new Action(Messages.getString("PodcastView.Refresh")) { //$NON-NLS-1$
public void run() {
List<Podcast> tmpList = new ArrayList<Podcast>();
tmpList.add(_thePodcast);
new PodcastUpdaterJob(tmpList).schedule();
}
};
_refreshAction.setImageDescriptor(Activator.getImageDescriptor("/icons/refresh_podcast_16.png"));
// Toolbar
IToolBarManager rootMenuManager = getViewSite().getActionBars().getToolBarManager();
rootMenuManager.removeAll();
rootMenuManager.add(_markReadAction);
rootMenuManager.add(_markUnreadAction);
rootMenuManager.add(new Separator());
rootMenuManager.add(_refreshAction);
}
private void buildMenu(final Composite parent) {
if (_viewMenu != null) {
_viewMenu.dispose();
}
_viewMenu = new Menu(parent.getShell(), SWT.POP_UP);
MenuItem playItem = new MenuItem(_viewMenu, SWT.PUSH);
playItem.setText(Messages.getString("PodcastView.MenuPlay")); //$NON-NLS-1$
playItem.setImage(_playImage);
playItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ISelection selection = viewer.getSelection();
Object obj = ((IStructuredSelection)selection).getFirstElement();
new PlayAction(_thePodcast, (PodcastItem) obj).run();
}
});
new MenuItem(_viewMenu, SWT.SEPARATOR);
MenuItem markRead = new MenuItem(_viewMenu, SWT.PUSH);
markRead.setText(Messages.getString("PodcastView.MarkAsRead")); //$NON-NLS-1$
markRead.setImage(_markReadImage);
markRead.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setSelectionReadState(true);
}
});
MenuItem markUnread = new MenuItem(_viewMenu, SWT.PUSH);
markUnread.setText(Messages.getString("PodcastView.MarkAsUnread")); //$NON-NLS-1$
markUnread.setImage(_markUnreadImage);
markUnread.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setSelectionReadState(false);
}
});
new MenuItem(_viewMenu, SWT.SEPARATOR);
MenuItem downloadItem = new MenuItem(_viewMenu, SWT.PUSH);
downloadItem.setText(Messages.getString("PodcastView.Download")); //$NON-NLS-1$
downloadItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
downloadSelection();
}
});
new MenuItem(_viewMenu, SWT.SEPARATOR);
MenuItem propertiesItem = new MenuItem(_viewMenu, SWT.PUSH);
propertiesItem.setText(Messages.getString("PodcastView.Properties")); //$NON-NLS-1$
propertiesItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ISelection selection = viewer.getSelection();
Object obj = ((IStructuredSelection)selection).getFirstElement();
new PodcastItemPropertiesDialog(parent.getShell(), (PodcastItem) obj).open();
}
});
viewer.getTable().addListener(SWT.MenuDetect, new Listener() {
public void handleEvent(Event event) {
_viewMenu.setVisible(true);
}
});
}
private String getViewTitle() {
String result = _id;
int unreadCount = _thePodcast.getUnreadItemsCount();
if (unreadCount > 0) {
result += " (" + Integer.toString(unreadCount) + ")";
}
return result;
}
public void dispose() {
_playImage.dispose();
_pauseImage.dispose();
_podcastReadImage.dispose();
_podcastUnreadImage.dispose();
_podcastCachedReadImage.dispose();
_podcastCachedUnreadImage.dispose();
_titleImage.dispose();
_titlePlayImage.dispose();
_titlePauseImage.dispose();
_markReadImage.dispose();
_markUnreadImage.dispose();
Controller.getInstance().getEventController().removeAudioItemChangeListener(this);
Controller.getInstance().getEventController().removePodcastsUpdateChangeListener(this);
super.dispose();
}
@Override
public void setFocus() {
if (viewer != null) {
viewer.getControl().setFocus();
}
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
class refreshViewer implements Runnable {
public void run() {
viewer.refresh();
setPartName(getViewTitle());
}
}
class iconUpdater implements Runnable {
private Image _image;
public iconUpdater(Image image) {
_image = image;
}
public void run() {
setTitleImage(_image);
}
}
if ((evt.getPropertyName().equals(EventConstants.EVT_PLAY_NEW_AUDIO_ITEM)) ||
(evt.getPropertyName().equals(EventConstants.EVT_STOP_PLAYBACK)) ||
(evt.getPropertyName().equals(EventConstants.EVT_PAUSE_PLAYBACK)) ||
(evt.getPropertyName().equals(EventConstants.EVT_ITEM_CHANGE_IN_PLAYLIST)) ||
(evt.getPropertyName().equals(EventConstants.EVT_PODCAST_DOWNLOAD_END))) {
if ((Controller.getInstance().getPlaylistController().getCurrentPlaylist() != null) &&
(Controller.getInstance().getPlaylistController().getCurrentPlaylist().getName().equals(_id))) {
if (evt.getPropertyName().equals(EventConstants.EVT_PLAY_NEW_AUDIO_ITEM)) {
Display.getDefault().asyncExec(new iconUpdater(_titlePlayImage));
}
if (evt.getPropertyName().equals(EventConstants.EVT_PAUSE_PLAYBACK)) {
if (Controller.getInstance().getEngine().isPaused())
Display.getDefault().asyncExec(new iconUpdater(_titlePauseImage));
else
Display.getDefault().asyncExec(new iconUpdater(_titlePlayImage));
}
} else {
Display.getDefault().asyncExec(new iconUpdater(_titleImage));
}
if (evt.getPropertyName().equals(EventConstants.EVT_STOP_PLAYBACK)) {
Display.getDefault().asyncExec(new iconUpdater(_titleImage));
}
Display.getDefault().asyncExec(new refreshViewer());
}
}
}