/*
* 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.MenuManager;
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.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
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.playlist.OpenAndPlayPlaylistAction;
import org.jampa.gui.actions.playlist.OpenPlaylistAction;
import org.jampa.gui.actions.playlist.PlayPlaylistAction;
import org.jampa.gui.translations.Messages;
import org.jampa.logging.Log;
import org.jampa.model.playlists.Playlist;
import org.jampa.preferences.PreferenceConstants;
public class PlaylistOverview extends ViewPart implements PropertyChangeListener {
public static final String ID = "Jampa.PlaylistOverview"; //$NON-NLS-1$
private TableViewer viewer;
private Image _playlistImage;
private Image _playlistPlayImage;
private Image _playlistPauseImage;
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().getPlaylistList();
}
}
class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
public Image getImage(Object obj) {
Playlist playlist = (Playlist) obj;
if (Controller.getInstance().getPlaylistController().getCurrentPlaylist() == playlist) {
if (Controller.getInstance().getEngine().isPaused()) {
return _playlistPauseImage;
} else {
return _playlistPlayImage;
}
} else {
return _playlistImage;
}
}
public Image getColumnImage(Object obj, int index) {
switch(index) {
case 0 : return getImage(obj);
case 1 : return null;
case 2 : return null;
default : return getImage(obj);
}
}
public String getColumnText(Object obj, int index) {
switch(index) {
case 0 : return ((Playlist) obj).getName();
case 1 : return Integer.toString(((Playlist) obj).getItemsCount());
case 2 : return ((Playlist) obj).getFormatedDate();
default : return ((Playlist) obj).getName();
}
}
}
public PlaylistOverview() {
Activator.getDefault();
ImageDescriptor playlistImageDescriptor = Activator.getImageDescriptor("/icons/playlist_16.png"); //$NON-NLS-1$
_playlistImage = playlistImageDescriptor.createImage();
ImageDescriptor titlePlayImageDescriptor = Activator.getImageDescriptor("/icons/playlistplay_16.png"); //$NON-NLS-1$
_playlistPlayImage = titlePlayImageDescriptor.createImage();
ImageDescriptor titlePauseImageDescriptor = Activator.getImageDescriptor("/icons/playlistpause_16.png"); //$NON-NLS-1$
_playlistPauseImage = titlePauseImageDescriptor.createImage();
}
@Override
public void createPartControl(Composite parent) {
this.setPartName(Messages.getString("PlaylistOverview.Title")); //$NON-NLS-1$
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
TableLayout layout = new TableLayout();
layout.addColumnData(new ColumnWeightData(60, 10, true));
layout.addColumnData(new ColumnWeightData(20, 10, true));
layout.addColumnData(new ColumnWeightData(20, 10, true));
viewer.getTable().setLayout(layout);
// Lines visible is ugly under Windows.
if (!Util.isWindows()) {
viewer.getTable().setLinesVisible(true);
}
viewer.getTable().setHeaderVisible(true);
TableColumn columnName = new TableColumn(viewer.getTable(), SWT.NONE);
columnName.setText(Messages.getString("PlaylistOverview.Name")); //$NON-NLS-1$
TableColumn columnCount = new TableColumn(viewer.getTable(), SWT.NONE);
columnCount.setText(Messages.getString("PlaylistOverview.Count")); //$NON-NLS-1$
TableColumn columnDate = new TableColumn(viewer.getTable(), SWT.NONE);
columnDate.setText(Messages.getString("PlaylistOverview.Date")); //$NON-NLS-1$
columnName.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Controller.getInstance().getPlaylistController().sortPlaylistList(1);
}
});
columnCount.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Controller.getInstance().getPlaylistController().sortPlaylistList(2);
}
});
columnDate.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Controller.getInstance().getPlaylistController().sortPlaylistList(3);
}
});
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();
if (obj != null) {
String param = Controller.getInstance().getPreferenceStore().getString(PreferenceConstants.PLAYLISTSVIEW_DOUBLECLICK_ACTION);
if (param.equals("2")) { //$NON-NLS-1$
new OpenAndPlayPlaylistAction(((Playlist) obj).getName()).run();
} else if (param.equals("1")) { //$NON-NLS-1$
new PlayPlaylistAction(((Playlist) obj).getName()).run();
} else {
new OpenPlaylistAction(((Playlist) obj).getName()).run();
}
}
}
});
// Popup menu
MenuManager menuManager = new MenuManager();
Menu menu = menuManager.createContextMenu(viewer.getTable());
// Set the MenuManager
viewer.getTable().setMenu(menu);
getSite().registerContextMenu(menuManager, viewer);
// Make the selection available
getSite().setSelectionProvider(viewer);
buildDND();
// Register listener
Controller.getInstance().getEventController().addPlaylistChangeListener(this);
Controller.getInstance().getEventController().addAudioItemChangeListener(this);
}
private void buildDND() {
// Drag source
Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
DragSource source = new DragSource(viewer.getTable(), DND.DROP_MOVE);
source.setTransfer(types);
source.addDragListener(new DragSourceAdapter() {
public void dragSetData(DragSourceEvent event) {
event.data = PlaylistOverview.ID;
}
public void dragStart(DragSourceEvent event) {
event.data = PlaylistOverview.ID;
Controller.getInstance().getDNDController().setSource(PlaylistOverview.ID);
}
public void dragFinished(DragSourceEvent event) {
Controller.getInstance().getDNDController().setSource(null);
}
});
// Drop target
DropTarget target = new DropTarget(viewer.getTable(), DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);
target.setTransfer(types);
target.addDropListener(new DropTargetAdapter() {
public void dragEnter(DropTargetEvent event) {
if (event.detail == DND.DROP_DEFAULT) {
if ((event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
}
}
}
public void dragOver(DropTargetEvent event) {
if ((Controller.getInstance().getDNDController().isLibraryViewSource()) ||
(Controller.getInstance().getDNDController().isDiskViewSource())) {
// Insertion can be made only on a playlist item.
Point pt = Display.getCurrent().map(null, viewer.getTable(), event.x, event.y);
TableItem item = viewer.getTable().getItem(pt);
if (item != null) {
event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
event.detail = DND.DROP_COPY;
}
else {
event.feedback = DND.FEEDBACK_NONE;
event.detail = DND.DROP_NONE;
}
} else if (Controller.getInstance().getDNDController().isPlaylistListViewSource()) {
Point pt = Display.getCurrent().map(null, viewer.getTable(), event.x, event.y);
TableItem item = viewer.getTable().getItem(pt);
if (item != null) {
event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
event.detail = DND.DROP_MOVE;
} else {
event.feedback = DND.FEEDBACK_NONE;
event.detail = DND.DROP_NONE;
}
} else {
// Source is not allowed, no drop feedback.
event.feedback = DND.FEEDBACK_NONE;
event.detail = DND.DROP_NONE;
}
}
public void drop(DropTargetEvent event) {
if (Controller.getInstance().getDNDController().isLibraryViewSource()) {
// Drag from Library view.
// Get the current item.
Point pt = Display.getCurrent().map(null, viewer.getTable(), event.x, event.y);
TableItem item = viewer.getTable().getItem(pt);
Log.getInstance(PlaylistView.class).debug("Drop from Library View to playlist: " + item.getText()); //$NON-NLS-1$
if (Controller.getInstance().getDNDController().getLibrarySelection() != null) {
Controller.getInstance().getPlaylistController().addItemToPlaylist(item.getText(), Controller.getInstance().getDNDController().getLibrarySelection(), false);
}
} else if (Controller.getInstance().getDNDController().isDiskViewSource()) {
// Drag from Disk view.
// Get the current item.
Point pt = Display.getCurrent().map(null, viewer.getTable(), event.x, event.y);
TableItem item = viewer.getTable().getItem(pt);
Log.getInstance(PlaylistView.class).debug("Drop from Disk View to playlist: " + item.getText()); //$NON-NLS-1$
if (Controller.getInstance().getDNDController().getDiskSelection() != null) {
Controller.getInstance().getPlaylistController().addDiskItemsToPlaylist(item.getText(), Controller.getInstance().getDNDController().getDiskSelection(), false);
}
} else if (Controller.getInstance().getDNDController().isPlaylistListViewSource()) {
// Get the current item.
Point pt = Display.getCurrent().map(null, viewer.getTable(), event.x, event.y);
TableItem item = viewer.getTable().getItem(pt);
Playlist sourcePlaylist = (Playlist) ((IStructuredSelection) viewer.getSelection()).getFirstElement();
int toIndex;
if (item != null) {
Playlist playlist = Controller.getInstance().getPlaylistController().getPlaylistByName(((Playlist) item.getData()).getName());
toIndex = playlist.getPosition();
} else {
toIndex = -1;
}
if (toIndex != -1) {
List<Playlist> tmpList = new ArrayList<Playlist>();
ISelection selection = viewer.getSelection();
Iterator<?> iter = ((IStructuredSelection) selection).iterator();
while (iter.hasNext()) {
tmpList.add((Playlist) iter.next());
}
// If moving up, move in reverse order to keep the initial order.
if (toIndex < sourcePlaylist.getPosition()) {
for (int i = tmpList.size() - 1; i >= 0; i--) {
Controller.getInstance().getPlaylistController().movePlaylist(tmpList.get(i), toIndex);
}
} else {
for (int i = 0; i < tmpList.size(); i++) {
Controller.getInstance().getPlaylistController().movePlaylist(tmpList.get(i), toIndex);
}
}
}
}
}
});
}
@Override
public void setFocus() {
viewer.getControl().setFocus();
}
public void dispose() {
_playlistImage.dispose();
_playlistPlayImage.dispose();
_playlistPauseImage.dispose();
// Unregister listener
Controller.getInstance().getEventController().removePlaylistChangeListener(this);
Controller.getInstance().getEventController().removeAudioItemChangeListener(this);
super.dispose();
}
@Override
public void propertyChange(PropertyChangeEvent arg0) {
if ((arg0.getPropertyName().equals(EventConstants.EVT_ADD_PLAYLIST)) ||
(arg0.getPropertyName().equals(EventConstants.EVT_REMOVE_PLAYLIST)) ||
(arg0.getPropertyName().equals(EventConstants.EVT_SORT_PLAYLIST_LIST)) ||
(arg0.getPropertyName().equals(EventConstants.EVT_ITEM_CHANGE_IN_PLAYLIST)) ||
(arg0.getPropertyName().equals(EventConstants.EVT_PLAY_NEW_AUDIO_ITEM)) ||
(arg0.getPropertyName().equals(EventConstants.EVT_STOP_PLAYBACK)) ||
(arg0.getPropertyName().equals(EventConstants.EVT_PAUSE_PLAYBACK))) {
class refreshViewer implements Runnable {
public void run() {
viewer.refresh();
}
}
Display.getDefault().asyncExec(new refreshViewer());
}
}
}
/*
GridLayout mainGL = new GridLayout();
mainGL.numColumns = 1;
GridData actionGroupGD = new GridData();
actionGroupGD.grabExcessHorizontalSpace = true;
actionGroupGD.horizontalAlignment = SWT.FILL;
parent.setLayout(mainGL);
GridLayout actionGroupGL = new GridLayout();
actionGroupGL.numColumns = 3;
Group actionGroup = new Group(parent, SWT.NONE);
actionGroup.setLayout(actionGroupGL);
actionGroup.setLayoutData(actionGroupGD);
actionGroup.setText("Playlists actions");
Label newPLLabel = new Label(actionGroup, SWT.NONE);
newPLLabel.setText("New playlist name:");
GridData newPLNameGD = new GridData();
newPLNameGD.grabExcessHorizontalSpace = true;
newPLNameGD.horizontalAlignment = SWT.FILL;
newPLText = new Text(actionGroup, SWT.BORDER);
newPLText.setLayoutData(newPLNameGD);
Button newPLBtn = new Button(actionGroup, SWT.NONE);
newPLBtn.setText("Create playlist");
newPLBtn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent arg0) {
new CreatePlaylistAction(newPLText.getText()).run();
}
});
Label deletePLLabel = new Label(actionGroup, SWT.NONE);
deletePLLabel.setText("Delete playlist:");
GridData deletePLNameGD = new GridData();
deletePLNameGD.grabExcessHorizontalSpace = true;
deletePLNameGD.horizontalAlignment = SWT.FILL;
deletePLText = new Text(actionGroup, SWT.READ_ONLY | SWT.BORDER);
deletePLText.setLayoutData(deletePLNameGD);
deletePLText.setEditable(false);
deletePLText.setBackground(parent.getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
Button deletePLBtn = new Button(actionGroup, SWT.NONE);
deletePLBtn.setText("Delete playlist");
deletePLBtn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent arg0) {
ISelection selection = viewer.getSelection();
Object obj = ((IStructuredSelection)selection).getFirstElement();
if (obj != null) {
new RemovePlaylistAction(((Playlist) obj).getName()).run();
}
}
});
GridData playlistGroupGD = new GridData();
playlistGroupGD.grabExcessHorizontalSpace = true;
playlistGroupGD.grabExcessVerticalSpace = true;
playlistGroupGD.horizontalAlignment = SWT.FILL;
playlistGroupGD.verticalAlignment = SWT.FILL;
Group playlistGroup = new Group(parent, SWT.NONE);
playlistGroup.setLayoutData(playlistGroupGD);
playlistGroup.setText("User playlists");
FillLayout fl = new FillLayout();
playlistGroup.setLayout(fl);
*/
/*
private Text newPLText;
private Text deletePLText;
*/