/* ********************************************************************** **
** 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.jface.action.IAction;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.rssowl.core.Owl;
import org.rssowl.core.internal.persist.pref.DefaultPreferences;
import org.rssowl.core.persist.IBookMark;
import org.rssowl.core.persist.IFolder;
import org.rssowl.core.persist.IFolderChild;
import org.rssowl.core.persist.IMark;
import org.rssowl.core.persist.IModelFactory;
import org.rssowl.core.persist.INews;
import org.rssowl.core.persist.ISearchCondition;
import org.rssowl.core.persist.ISearchField;
import org.rssowl.core.persist.ISearchMark;
import org.rssowl.core.persist.SearchSpecifier;
import org.rssowl.core.persist.dao.DynamicDAO;
import org.rssowl.core.persist.pref.IPreferenceScope;
import org.rssowl.core.util.CoreUtils;
import org.rssowl.ui.internal.FolderNewsMark;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.dialogs.AggregateNewsDialog;
import org.rssowl.ui.internal.dialogs.SearchMarkDialog;
import org.rssowl.ui.internal.util.ModelUtils;
import org.rssowl.ui.internal.views.explorer.BookMarkExplorer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Aggregates all bookmarks of a selected folder to be displayed in the
* feedview. Asks the user to either use a saved search or
* {@link FolderNewsMark} to display.
*
* @author bpasero
*/
public class AggregateFolderAction implements IObjectActionDelegate {
private ISelection fSelection;
private IWorkbenchPart fTargetPart;
/** Leave for Reflection */
public AggregateFolderAction() {}
/*
* @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
*/
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
fTargetPart = targetPart;
}
/*
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
public void run(IAction action) {
if (!fSelection.isEmpty() && fSelection instanceof IStructuredSelection) {
Object firstElem = ((IStructuredSelection) fSelection).getFirstElement();
/* Aggregate News of Folder */
if (firstElem instanceof IFolder) {
IPreferenceScope preferences = Owl.getPreferenceService().getGlobalScope();
boolean aggregateAsSearch = preferences.getBoolean(DefaultPreferences.AGGREGATE_NEWS_AS_SEARCH);
boolean askUserForAggregationOption = !preferences.getBoolean(DefaultPreferences.REMEMBER_AGGREGATE_NEWS_OPTION);
/* Ask user for Aggregation Mode if required */
if (askUserForAggregationOption) {
AggregateNewsDialog dialog = new AggregateNewsDialog(fTargetPart.getSite().getShell(), ((IFolder) firstElem).getName());
int res = dialog.open();
/* Check for Cancellation */
if (res == IDialogConstants.CANCEL_ID)
return;
aggregateAsSearch = (res == IDialogConstants.YES_ID);
}
/* Create Search on Folder */
if (aggregateAsSearch)
createAndOpenSearch((IFolder) firstElem);
/* Otherwise directly aggregate */
else
aggregateFolder((IFolder) firstElem);
}
}
}
private void createAndOpenSearch(IFolder folder) {
ISearchMark locationSearch = findSearch(folder);
if (locationSearch == null) {
IModelFactory factory = Owl.getModelFactory();
List<ISearchCondition> conditions = new ArrayList<ISearchCondition>();
ISearchField locationField = factory.createSearchField(INews.LOCATION, INews.class.getName());
conditions.add(factory.createSearchCondition(locationField, SearchSpecifier.IS, ModelUtils.toPrimitive(Collections.singletonList((IFolderChild) folder))));
SearchMarkDialog dialog = new SearchMarkDialog(fTargetPart.getSite().getShell(), folder.getParent(), folder, conditions, true, folder.getProperties());
if (dialog.open() == IDialogConstants.OK_ID)
locationSearch = dialog.getSearchMark();
else
return;
}
/* Open Search and Reload Bookmarks that have never been reloaded before */
if (locationSearch != null) {
StructuredSelection selection = new StructuredSelection(locationSearch);
/* Ensure Selected */
BookMarkExplorer explorer = OwlUI.getOpenedBookMarkExplorer();
if (explorer != null)
explorer.getViewSite().getSelectionProvider().setSelection(selection);
/* Open */
OwlUI.openInFeedView(fTargetPart.getSite().getPage(), selection);
/* Reload if necessary */
List<IBookMark> bookMarksToReload = new ArrayList<IBookMark>();
fillBookMarksToReload(bookMarksToReload, folder);
if (!bookMarksToReload.isEmpty())
new ReloadTypesAction(new StructuredSelection(bookMarksToReload.toArray()), fTargetPart.getSite().getShell()).run();
}
}
private void fillBookMarksToReload(List<IBookMark> bookMarksToReload, IFolder folder) {
List<IMark> marks = folder.getMarks();
for (IMark mark : marks) {
if (mark instanceof IBookMark) {
if ((((IBookMark) mark).getMostRecentNewsDate() == null))
bookMarksToReload.add((IBookMark) mark);
}
}
List<IFolder> childs = folder.getFolders();
for (IFolder child : childs) {
fillBookMarksToReload(bookMarksToReload, child);
}
}
private ISearchMark findSearch(IFolderChild folder) {
Collection<ISearchMark> existingSearches = DynamicDAO.loadAll(ISearchMark.class);
for (ISearchMark search : existingSearches) {
List<ISearchCondition> conditions = search.getSearchConditions();
if (conditions.size() == 1) {
ISearchCondition condition = conditions.get(0);
/* Check on Search Field */
ISearchField field = condition.getField();
if (field.getId() != INews.LOCATION)
continue;
/* Check on Search Specifier */
SearchSpecifier specifier = condition.getSpecifier();
if (specifier != SearchSpecifier.IS)
continue;
/* Check on Search Value */
Object value = condition.getValue();
if (!(value instanceof Long[][]))
continue;
Long[][] valueLong = (Long[][]) value;
if (valueLong.length == 0)
continue;
if (valueLong[CoreUtils.FOLDER].length != 1)
continue;
if (valueLong[CoreUtils.FOLDER][0] != null && valueLong[CoreUtils.FOLDER][0].equals(folder.getId()))
return search;
}
}
return null;
}
/* Create in-memory Newsmark */
private void aggregateFolder(final IFolder folder) {
BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() {
public void run() {
FolderNewsMark folderNewsMark = new FolderNewsMark(folder);
StructuredSelection newSelection = new StructuredSelection(folderNewsMark);
/* Open in Feedview */
OwlUI.openInFeedView(fTargetPart.getSite().getPage(), newSelection);
}
});
}
/*
* @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
*/
public void selectionChanged(IAction action, ISelection selection) {
fSelection = selection;
}
}