/* ********************************************************************** **
** Copyright notice **
** **
** (c) 2005-2009 RSSOwl Development Team **
** http://www.rssowl.org/ **
** **
** All rights reserved **
** **
** This program and the accompanying materials are made available under **
** the terms of the Eclipse Public License v1.0 which accompanies this **
** distribution, and is available at: **
** http://www.rssowl.org/legal/epl-v10.html **
** **
** A copy is found in the file epl-v10.html and important notices to the **
** license from the team is found in the textfile LICENSE.txt distributed **
** in this package. **
** **
** This copyright notice MUST APPEAR in all copies of the file! **
** **
** Contributors: **
** RSSOwl Development Team - initial API and implementation **
** **
** ********************************************************************** */
package org.rssowl.ui.internal.actions;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.rssowl.core.persist.INews;
import org.rssowl.core.persist.INewsMark;
import org.rssowl.core.persist.reference.FeedLinkReference;
import org.rssowl.core.persist.reference.NewsBinReference;
import org.rssowl.core.persist.reference.NewsReference;
import org.rssowl.core.util.CoreUtils;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.editors.feed.FeedView;
import org.rssowl.ui.internal.editors.feed.FeedViewInput;
import org.rssowl.ui.internal.editors.feed.PerformAfterInputSet;
import org.rssowl.ui.internal.util.EditorUtils;
import org.rssowl.ui.internal.views.explorer.BookMarkExplorer;
import java.util.ArrayList;
import java.util.List;
/**
* The <code>OpenNewsAction</code> will open a given Selection of
* <code>INews</code> in the <code>FeedView</code> opening the related BookMark
* and adjusting the selection.
*
* @author bpasero
*/
public class OpenNewsAction extends Action {
private IStructuredSelection fSelection;
private Shell fShellToMinimize;
private boolean fRestoreWindow;
/**
* @param selection
*/
public OpenNewsAction(IStructuredSelection selection) {
this(selection, null);
}
/**
* @param selection
* @param shellToMinimize The <code>Shell</code> to minimize (e.g. a Dialog)
* when executing this action, or <code>NULL</code> if none.
*/
public OpenNewsAction(IStructuredSelection selection, Shell shellToMinimize) {
Assert.isTrue(selection != null && !selection.isEmpty());
fSelection = selection;
fShellToMinimize = shellToMinimize;
setText(Messages.OpenNewsAction_OPEN);
}
/**
* @param restoreWindow <code>true</code> if the window should be restored and
* <code>false</code> otherwise.
*/
public void setRestoreWindow(boolean restoreWindow) {
fRestoreWindow = restoreWindow;
}
/*
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
internalRun();
}
/*
* @see org.eclipse.jface.action.Action#runWithEvent(org.eclipse.swt.widgets.Event)
*/
@Override
public void runWithEvent(Event event) {
internalRun();
}
private void internalRun() {
/* Require a Page */
IWorkbenchPage page = OwlUI.getPage();
if (page == null)
return;
/* Restore Window */
if (fRestoreWindow)
OwlUI.restoreWindow(page);
int openedEditors = 0;
int maxOpenEditors = EditorUtils.getOpenEditorLimit();
/* Convert selection to List of News (1 per Feed and Bin) */
List<?> list = fSelection.toList();
List<FeedLinkReference> handledFeeds = new ArrayList<FeedLinkReference>(list.size() / 2);
List<Long> handledBins = new ArrayList<Long>(list.size() / 2);
List<INews> newsToOpen = new ArrayList<INews>(list.size());
for (Object selection : list) {
if (selection instanceof INews) {
INews news = (INews) selection;
/* News in a Bin */
if (news.getParentId() != 0) {
if (!handledBins.contains(news.getParentId())) {
newsToOpen.add(news);
handledBins.add(news.getParentId());
}
}
/* News in a Feed */
else {
FeedLinkReference feedRef = news.getFeedReference();
if (!handledFeeds.contains(feedRef)) {
newsToOpen.add(news);
handledFeeds.add(feedRef);
}
}
}
}
/* Minimize Shell if present */
if (newsToOpen.size() > 0 && fShellToMinimize != null)
fShellToMinimize.setMinimized(true);
/* Open Bookmarks belonging to the News */
INewsMark lastOpenedNewsMark = null;
for (int i = 0; i < newsToOpen.size() && openedEditors < maxOpenEditors; i++) {
INews news = newsToOpen.get(i);
INewsMark newsmark;
if (news.getParentId() != 0)
newsmark = new NewsBinReference(news.getParentId()).resolve();
else
newsmark = CoreUtils.getBookMark(news.getFeedReference());
/* Open and Select */
if (newsmark != null) {
openAndSelect(page, news, newsmark);
openedEditors++;
lastOpenedNewsMark = newsmark;
}
}
/* Reveal Newsmark of last opened News */
BookMarkExplorer explorer = OwlUI.getOpenedBookMarkExplorer();
if (explorer != null && lastOpenedNewsMark != null && !explorer.isLinkingEnabled()) {
explorer.reveal(lastOpenedNewsMark, false);
}
}
private void openAndSelect(IWorkbenchPage page, INews news, INewsMark newsmark) {
PerformAfterInputSet perform = PerformAfterInputSet.selectNews(new NewsReference(news.getId()));
perform.setActivate(false);
/* Open this Bookmark */
FeedViewInput fvInput = new FeedViewInput(newsmark, perform);
FeedView feedview = null;
/* First check if input already shown */
IEditorPart existingEditor = page.findEditor(fvInput);
if (existingEditor != null && existingEditor instanceof FeedView) {
feedview = (FeedView) existingEditor;
/* Set Selection and bring to front */
existingEditor.getSite().getPage().activate(existingEditor);
feedview.setSelection(new StructuredSelection(news));
}
/* Otherwise open the Input in a new Editor */
else
OwlUI.openInFeedView(page, new StructuredSelection(newsmark), true, false, perform);
}
}