/*
* 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.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
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.ui.part.ViewPart;
import org.jampa.Activator;
import org.jampa.controllers.Controller;
import org.jampa.controllers.events.EventConstants;
import org.jampa.gui.actions.radio.NewRadioAction;
import org.jampa.gui.actions.radio.PlayRadioAction;
import org.jampa.gui.actions.radio.RemoveRadioAction;
import org.jampa.gui.dialogs.RadioItemPropertiesDialog;
import org.jampa.gui.translations.Messages;
import org.jampa.model.IAudioItem;
import org.jampa.model.IPlaylist;
import org.jampa.model.SortMode;
import org.jampa.model.radio.CategoryRadioItem;
import org.jampa.model.radio.IRadioItem;
import org.jampa.model.radio.RadioItem;
import org.jampa.preferences.PreferenceConstants;
import org.jampa.utils.ApplicationUtils;
public class RadioView extends ViewPart implements PropertyChangeListener {
public static String ID = "Jampa.RadioView"; //$NON-NLS-1$
private Image _radioImage;
private Image _radioFavoriteImage;
private Image _radioPlayingImage;
private Image _radioPausedImage;
private Image _radioFavoritePlayingImage;
private Image _radioFavoritePausedImage;
private Image _radioFolderImage;
private Image _radioFolderFavoriteImage;
private Image _radioFolderPlayingImage;
private Image _radioFolderPausedImage;
private Image _radioFolderFavoritePlayingImage;
private Image _radioFolderFavoritePausedImage;
private Image _playImage;
private Image _favoriteImage;
private Image _addImage;
private Image _removeImage;
private Action _ascendingSortMode;
private Action _descendingSortMode;
private Action _onlyShowFavoritesAction;
private Action _addRadioAction;
private Action _removeAction;
private boolean _onlyShowFavorites;
private TreeViewer treeViewer = null;
private Composite _parent;
private Menu _viewMenu = null;
class ViewContentProvider implements ITreeContentProvider {
private final Object[] EMPTY_ARRAY = new Object[0];
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
// do nothing
}
public void dispose() {
// do nothing
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof IRadioItem) {
IRadioItem item = (IRadioItem) parentElement;
return item.getChildren(_onlyShowFavorites).toArray();
}
return EMPTY_ARRAY;
}
@Override
public Object getParent(Object element) {
if (element instanceof IRadioItem) {
return ((IRadioItem) element).getParent();
}
return null;
}
@Override
public boolean hasChildren(Object element) {
if (element instanceof IRadioItem) {
return ((IRadioItem) element).hasChildren();
}
return false;
}
@Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
}
class ViewLabelProvider extends LabelProvider implements ILabelProvider {
public Image getImage(Object obj) {
IRadioItem item = (IRadioItem) obj;
if (item instanceof RadioItem) {
if (item.isFavorite()) {
if (((IAudioItem) item).isBoPlaying()) {
if (Controller.getInstance().getEngine().isPaused()) {
return _radioFavoritePausedImage;
} else {
return _radioFavoritePlayingImage;
}
} else {
return _radioFavoriteImage;
}
} else {
if (((IAudioItem) item).isBoPlaying()) {
if (Controller.getInstance().getEngine().isPaused()) {
return _radioPausedImage;
} else {
return _radioPlayingImage;
}
} else {
return _radioImage;
}
}
} else {
if (item.isFavorite()) {
if (((IPlaylist) item).hasAudioItemPlaying()) {
if (Controller.getInstance().getEngine().isPaused()) {
return _radioFolderFavoritePausedImage;
} else {
return _radioFolderFavoritePlayingImage;
}
} else {
return _radioFolderFavoriteImage;
}
} else {
if (((IPlaylist) item).hasAudioItemPlaying()) {
if (Controller.getInstance().getEngine().isPaused()) {
return _radioFolderPausedImage;
} else {
return _radioFolderPlayingImage;
}
} else {
return _radioFolderImage;
}
}
}
}
public String getText(Object element) {
return ((IRadioItem) element).getName();
}
}
public RadioView() {
_onlyShowFavorites = Controller.getInstance().getPreferenceStore().getBoolean(PreferenceConstants.RADIOVIEW_SHOW_FAVORITES);
Activator.getDefault();
_radioImage = Activator.getImageDescriptor("/icons/radio_16.png").createImage(); //$NON-NLS-1$
_radioFavoriteImage = Activator.getImageDescriptor("/icons/radio_favorite_16.png").createImage(); //$NON-NLS-1$
_radioPlayingImage = Activator.getImageDescriptor("/icons/radio_playing_16.png").createImage(); //$NON-NLS-1$
_radioPausedImage = Activator.getImageDescriptor("/icons/radio_paused_16.png").createImage(); //$NON-NLS-1$
_radioFavoritePlayingImage = Activator.getImageDescriptor("/icons/radio_favorite_playing_16.png").createImage(); //$NON-NLS-1$
_radioFavoritePausedImage = Activator.getImageDescriptor("/icons/radio_favorite_paused_16.png").createImage(); //$NON-NLS-1$
_radioFolderImage = Activator.getImageDescriptor("/icons/radio_folder_16.png").createImage(); //$NON-NLS-1$
_radioFolderFavoriteImage = Activator.getImageDescriptor("/icons/radio_folder_favorite_16.png").createImage(); //$NON-NLS-1$
_radioFolderPlayingImage = Activator.getImageDescriptor("/icons/radio_folder_playing_16.png").createImage(); //$NON-NLS-1$
_radioFolderPausedImage = Activator.getImageDescriptor("/icons/radio_folder_paused_16.png").createImage(); //$NON-NLS-1$
_radioFolderFavoritePlayingImage = Activator.getImageDescriptor("/icons/radio_folder_favorite_playing_16.png").createImage(); //$NON-NLS-1$
_radioFolderFavoritePausedImage = Activator.getImageDescriptor("/icons/radio_folder_favorite_paused_16.png").createImage(); //$NON-NLS-1$
_playImage = Activator.getImageDescriptor("/icons/playing_16.png").createImage(); //$NON-NLS-1$
_favoriteImage = Activator.getImageDescriptor("/icons/radio_mark_favorite_16.png").createImage(); //$NON-NLS-1$
_addImage = Activator.getImageDescriptor("/icons/add_radio_16.png").createImage(); //$NON-NLS-1$
_removeImage = Activator.getImageDescriptor("/icons/delete_16.png").createImage(); //$NON-NLS-1$
}
@Override
public void createPartControl(Composite parent) {
_parent = parent;
setPartName(Messages.getString("RadioView.Title")); //$NON-NLS-1$
if (ApplicationUtils.doesEngineSupportPodcasts()) {
treeViewer = new TreeViewer(_parent);
treeViewer.setContentProvider(new ViewContentProvider());
treeViewer.setLabelProvider(new ViewLabelProvider());
treeViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
processDoubleClick();
}
});
buildMenu(_parent);
buildActions();
updateTreeViewer();
Controller.getInstance().getEventController().addAudioItemChangeListener(this);
Controller.getInstance().getEventController().addRadioChangeListeners(this);
} else {
this.setContentDescription(String.format(Messages.getString("RadioView.PodcastsNotSupported"), //$NON-NLS-1$
Controller.getInstance().getEngine().getEngineType()));
}
}
private void updateTreeViewer() {
// Saved expanded elements.
TreePath[] savedTreePaths = treeViewer.getExpandedTreePaths();
int savedHorizontalValue = -1;
int savedVerticalValue = -1;
if (treeViewer.getTree().getHorizontalBar() != null) {
savedHorizontalValue = treeViewer.getTree().getHorizontalBar().getSelection();
}
if (treeViewer.getTree().getVerticalBar() != null) {
savedVerticalValue = treeViewer.getTree().getVerticalBar().getSelection();
}
// Disable redraw
treeViewer.getControl().setRedraw(false);
treeViewer.setInput(Controller.getInstance().getRadioController().getRootCategory());
// Restore expanded elements.
treeViewer.setExpandedTreePaths(savedTreePaths);
// Redraw
treeViewer.getControl().setRedraw(true);
treeViewer.refresh();
if ((treeViewer.getTree().getHorizontalBar() != null) &&
(savedHorizontalValue != -1)) {
treeViewer.getTree().getHorizontalBar().setSelection(savedHorizontalValue);
}
if ((treeViewer.getTree().getVerticalBar() != null) &&
(savedVerticalValue != -1)) {
treeViewer.getTree().getVerticalBar().setSelection(savedVerticalValue);
}
}
private void changeSortMode(Action action) {
if (action == _ascendingSortMode) {
_descendingSortMode.setChecked(!_ascendingSortMode.isChecked());
} else if (action == _descendingSortMode) {
_ascendingSortMode.setChecked(!_descendingSortMode.isChecked());
}
if (_ascendingSortMode.isChecked()) {
Controller.getInstance().getRadioController().getRootCategory().setSortMode(SortMode.Ascending);
} else if (_descendingSortMode.isChecked()) {
Controller.getInstance().getRadioController().getRootCategory().setSortMode(SortMode.Descending);
}
updateTreeViewer();
}
private void changeShowFavoriteMode() {
_onlyShowFavorites = !_onlyShowFavorites;
Controller.getInstance().getPreferenceStore().setValue(PreferenceConstants.RADIOVIEW_SHOW_FAVORITES, _onlyShowFavorites);
_onlyShowFavoritesAction.setChecked(_onlyShowFavorites);
updateTreeViewer();
}
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("RadioView.MenuPlay")); //$NON-NLS-1$
playItem.setImage(_playImage);
playItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Object selection = ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
RadioItem itemToPlay = null;
if (selection instanceof CategoryRadioItem) {
itemToPlay = (RadioItem) ((CategoryRadioItem) selection).getChildren().get(0);
} else {
itemToPlay = (RadioItem) selection;
}
new PlayRadioAction(itemToPlay).run();
}
});
new MenuItem(_viewMenu, SWT.SEPARATOR);
MenuItem markFavoriteItem = new MenuItem(_viewMenu, SWT.PUSH);
markFavoriteItem.setText(Messages.getString("RadioView.MarkAsFavorite"));
markFavoriteItem.setImage(_favoriteImage);
markFavoriteItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setSelectionFavorite((IStructuredSelection) treeViewer.getSelection(), true);
}
});
MenuItem unmarkFavoriteItem = new MenuItem(_viewMenu, SWT.PUSH);
unmarkFavoriteItem.setText(Messages.getString("RadioView.UnmarkAsFavorite"));
unmarkFavoriteItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setSelectionFavorite((IStructuredSelection) treeViewer.getSelection(), false);
}
});
new MenuItem(_viewMenu, SWT.SEPARATOR);
MenuItem addRadioItem = new MenuItem(_viewMenu, SWT.PUSH);
addRadioItem.setText(Messages.getString("RadioView.AddRadio")); //$NON-NLS-1$
addRadioItem.setImage(_addImage);
addRadioItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
addRadio((IStructuredSelection) treeViewer.getSelection());
}
});
MenuItem removeRadioItem = new MenuItem(_viewMenu, SWT.PUSH);
removeRadioItem.setText(Messages.getString("RadioView.RemoveRadioItem")); //$NON-NLS-1$
removeRadioItem.setImage(_removeImage);
removeRadioItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
removeSelection((IStructuredSelection) treeViewer.getSelection());
}
});
new MenuItem(_viewMenu, SWT.SEPARATOR);
MenuItem propertiesItem = new MenuItem(_viewMenu, SWT.PUSH);
propertiesItem.setText(Messages.getString("RadioView.Properties")); //$NON-NLS-1$
propertiesItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Object selection = ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
new RadioItemPropertiesDialog(parent.getShell(), (IRadioItem) selection).open();
}
});
treeViewer.getTree().addListener(SWT.MenuDetect, new Listener() {
public void handleEvent(Event event) {
_viewMenu.setVisible(true);
}
});
}
private void buildActions() {
_ascendingSortMode = new Action(Messages.getString("RadioView.AscendingSortAction")) { //$NON-NLS-1$
public void run() {
changeSortMode(_ascendingSortMode);
}
};
_ascendingSortMode.setImageDescriptor(Activator.getImageDescriptor("/icons/sort_asc_16.png")); //$NON-NLS-1$
_ascendingSortMode.setChecked(SortMode.getValueOf(Controller.getInstance().getPreferenceStore().getString(PreferenceConstants.RADIOVIEW_SORT_MODE)) == SortMode.Ascending ? true : false);
_descendingSortMode = new Action(Messages.getString("RadioView.DescendingSortAction")) { //$NON-NLS-1$
public void run() {
changeSortMode(_descendingSortMode);
}
};
_descendingSortMode.setImageDescriptor(Activator.getImageDescriptor("/icons/sort_desc_16.png")); //$NON-NLS-1$
_descendingSortMode.setChecked(SortMode.getValueOf(Controller.getInstance().getPreferenceStore().getString(PreferenceConstants.RADIOVIEW_SORT_MODE)) == SortMode.Descending ? true : false);
_onlyShowFavoritesAction = new Action(Messages.getString("RadioView.OnlyShowFavorite")) { //$NON-NLS-1$
public void run() {
changeShowFavoriteMode();
}
};
_onlyShowFavoritesAction.setImageDescriptor(Activator.getImageDescriptor("/icons/favorites_16.png"));
_onlyShowFavoritesAction.setChecked(_onlyShowFavorites);
_addRadioAction = new Action(Messages.getString("RadioView.AddRadio")) { //$NON-NLS-1$
public void run() {
addRadio((IStructuredSelection) treeViewer.getSelection());
}
};
_addRadioAction.setImageDescriptor(Activator.getImageDescriptor("/icons/add_radio_16.png"));
_removeAction = new Action(Messages.getString("RadioView.RemoveRadioItem")) { //$NON-NLS-1$
public void run() {
removeSelection((IStructuredSelection) treeViewer.getSelection());
}
};
_removeAction.setImageDescriptor(Activator.getImageDescriptor("/icons/delete_16.png"));
// Toolbar
IToolBarManager rootMenuManager = getViewSite().getActionBars().getToolBarManager();
rootMenuManager.removeAll();
rootMenuManager.add(_ascendingSortMode);
rootMenuManager.add(_descendingSortMode);
rootMenuManager.add(new Separator());
rootMenuManager.add(_onlyShowFavoritesAction);
rootMenuManager.add(new Separator());
rootMenuManager.add(_addRadioAction);
rootMenuManager.add(_removeAction);
}
private void processDoubleClick() {
Object selection = ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
if (selection instanceof CategoryRadioItem) {
treeViewer.setExpandedState(selection, !treeViewer.getExpandedState(selection));
} else if (selection instanceof RadioItem) {
new PlayRadioAction((RadioItem) selection).run();
}
}
private void addRadio(IStructuredSelection selection) {
Object selectedObj = selection.getFirstElement();
IRadioItem selectedRadioItem;
if (selectedObj != null) {
if (selectedObj instanceof CategoryRadioItem) {
selectedRadioItem = (IRadioItem) selectedObj;
} else if (selectedObj instanceof RadioItem) {
selectedRadioItem = ((IRadioItem) selectedObj).getParent();
} else {
selectedRadioItem = null;
}
} else {
selectedRadioItem = null;
}
new NewRadioAction(_parent.getShell(), selectedRadioItem).run();
}
private void setSelectionFavorite(IStructuredSelection selection, boolean newValue) {
Object obj;
Iterator<?> selectionIter = selection.iterator();
while (selectionIter.hasNext()) {
obj = selectionIter.next();
if (obj instanceof CategoryRadioItem) {
Iterator<IRadioItem> iter = ((CategoryRadioItem) obj).getChildren().iterator();
while (iter.hasNext()) {
iter.next().setFavorite(newValue);
}
} else if (obj instanceof IRadioItem) {
((IRadioItem) obj).setFavorite(newValue);
}
}
Controller.getInstance().getEventController().fireRadioChange(EventConstants.EVT_RADIO_CHANGE_FAVORITES, null, null);
}
private void removeSelection(IStructuredSelection selection) {
if (!selection.isEmpty()) {
boolean confirm = MessageDialog.openConfirm(_parent.getShell(),
Messages.getString("RadioView.RemoveTitle"), //$NON-NLS-1$
Messages.getString("RadioView.RemoveQuestion")); //$NON-NLS-1$
if (confirm) {
Object obj;
List<IRadioItem> items = new ArrayList<IRadioItem>();
Iterator<?> iter = selection.iterator();
while (iter.hasNext()) {
obj = iter.next();
if ((obj != null) &&
(obj instanceof IRadioItem)) {
items.add((IRadioItem) obj);
}
}
new RemoveRadioAction(items).run();
}
}
}
private void onRefreshView() {
if ((Controller.getInstance().getEngine().isPlaying()) &&
(Controller.getInstance().getPlaylistController().getCurrentAudioItem() != null) &&
(Controller.getInstance().getPlaylistController().getCurrentAudioItem() instanceof RadioItem)) {
if (Controller.getInstance().getEngine().isPaused()) {
this.setTitleImage(_radioPausedImage);
} else {
this.setTitleImage(_radioPlayingImage);
}
} else {
this.setTitleImage(_radioImage);
}
treeViewer.refresh();
}
@Override
public void setFocus() {
if (treeViewer != null) {
treeViewer.getControl().setFocus();
}
}
public void dispose() {
_radioImage.dispose();
_radioFavoriteImage.dispose();
_radioPlayingImage.dispose();
_radioPausedImage.dispose();
_radioFavoritePlayingImage.dispose();
_radioFavoritePausedImage.dispose();
_radioFolderImage.dispose();
_radioFolderFavoriteImage.dispose();
_radioFolderPlayingImage.dispose();
_radioFolderPausedImage.dispose();
_radioFolderFavoritePlayingImage.dispose();
_radioFolderFavoritePausedImage.dispose();
_playImage.dispose();
_favoriteImage.dispose();
_addImage.dispose();
_removeImage.dispose();
Controller.getInstance().getEventController().removeAudioItemChangeListener(this);
Controller.getInstance().getEventController().removeRadioChangeListeners(this);
super.dispose();
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
class ViewRefresher implements Runnable {
public void run() {
onRefreshView();
}
}
if ((evt.getPropertyName().equals(EventConstants.EVT_RADIO_ADD)) ||
(evt.getPropertyName().equals(EventConstants.EVT_RADIO_REMOVE))) {
Display.getDefault().asyncExec(new ViewRefresher());
}
if ((evt.getPropertyName().equals(EventConstants.EVT_RADIO_CHANGE)) ||
(evt.getPropertyName().equals(EventConstants.EVT_RADIO_CHANGE_FAVORITES)) ||
(evt.getPropertyName().equals(EventConstants.EVT_PLAY_NEW_AUDIO_ITEM)) ||
(evt.getPropertyName().equals(EventConstants.EVT_STOP_PLAYBACK)) ||
(evt.getPropertyName().equals(EventConstants.EVT_PAUSE_PLAYBACK))) {
Display.getDefault().asyncExec(new ViewRefresher());
}
}
}