/* ********************************************************************** **
** 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.dialogs;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.rssowl.core.Owl;
import org.rssowl.core.internal.newsaction.MoveNewsAction;
import org.rssowl.core.persist.IEntity;
import org.rssowl.core.persist.IFilterAction;
import org.rssowl.core.persist.IModelFactory;
import org.rssowl.core.persist.INews;
import org.rssowl.core.persist.ISearch;
import org.rssowl.core.persist.ISearchCondition;
import org.rssowl.core.persist.ISearchField;
import org.rssowl.core.persist.ISearchFilter;
import org.rssowl.core.persist.ISearchMark;
import org.rssowl.core.persist.SearchSpecifier;
import org.rssowl.core.persist.dao.DynamicDAO;
import org.rssowl.core.util.CoreUtils;
import org.rssowl.core.util.Pair;
import org.rssowl.core.util.StringUtils;
import org.rssowl.ui.internal.Activator;
import org.rssowl.ui.internal.ContextMenuCreator;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.filter.NewsActionDescriptor;
import org.rssowl.ui.internal.filter.NewsActionList;
import org.rssowl.ui.internal.filter.NewsActionPresentationManager;
import org.rssowl.ui.internal.search.LocationControl;
import org.rssowl.ui.internal.search.SearchConditionList;
import org.rssowl.ui.internal.util.JobRunner;
import org.rssowl.ui.internal.util.LayoutUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* A dialog to add and update a news filter with search conditions and actions.
*
* @author bpasero
*/
public class NewsFilterDialog extends TitleAreaDialog {
/* Section for Dialogs Settings */
private static final String SETTINGS_SECTION = "org.rssowl.ui.internal.dialogs.NewsFilterDialog"; //$NON-NLS-1$
/* Action Searches */
private static final String SEARCHES_ACTION = "org.rssowl.ui.internal.dialogs.filter.SearchesAction"; //$NON-NLS-1$
/* Action Filters */
private static final String FILTERS_ACTION = "org.rssowl.ui.internal.dialogs.filter.FiltersAction"; //$NON-NLS-1$
private LocalResourceManager fResources;
private final ISearchFilter fEditedFilter;
private final List<Integer> fExcludedConditions = getExcludedConditions();
private LocationControl fLocationControl;
private SearchConditionList fSearchConditionList;
private NewsActionPresentationManager fNewsActionPresentationManager = NewsActionPresentationManager.getInstance();
private Button fMatchAllRadio;
private Button fMatchAnyRadio;
private Button fMatchAllNewsRadio;
private NewsActionList fFilterActionList;
private Text fNameInput;
private int fFilterPosition;
private ISearch fPresetSearch;
private boolean fPresetMatchAll;
private List<IFilterAction> fPresetActions;
private ISearchFilter fAddedFilter;
/**
* @param parentShell the Shell to create this Dialog on.
*/
public NewsFilterDialog(Shell parentShell) {
this(parentShell, (ISearchFilter) null);
}
/**
* @param parentShell the Shell to create this Dialog on.
* @param filter the {@link ISearchFilter} to edit or <code>null</code> if
* none.
*/
public NewsFilterDialog(Shell parentShell, ISearchFilter filter) {
super(parentShell);
fEditedFilter = filter;
fResources = new LocalResourceManager(JFaceResources.getResources());
}
/**
* @param parentShell the Shell to create this Dialog on.
* @param presetSearch a search that is preset in the condition area.
*/
public NewsFilterDialog(Shell parentShell, ISearch presetSearch) {
this(parentShell, presetSearch, null, false);
}
/**
* @param parentShell the Shell to create this Dialog on.
* @param presetSearch a search that is preset in the condition area.
* @param presetActions a list of {@link IFilterAction} that is preset
* @param matchAll <code>true</code> to all news or <code>false</code>
* otherwise.
*/
public NewsFilterDialog(Shell parentShell, ISearch presetSearch, List<IFilterAction> presetActions, boolean matchAll) {
super(parentShell);
fPresetSearch = presetSearch;
fPresetActions = presetActions;
fPresetMatchAll = matchAll;
fEditedFilter = null;
fResources = new LocalResourceManager(JFaceResources.getResources());
}
/**
* @param filterPosition the sort order for the resulting news filter.
*/
public void setFilterPosition(int filterPosition) {
fFilterPosition = filterPosition;
}
/*
* @see org.eclipse.jface.dialogs.Dialog#okPressed()
*/
@Override
protected void okPressed() {
/* Generate Name if necessary */
if (!StringUtils.isSet(fNameInput.getText()))
onGenerateName();
/* Ensure that a Search Condition is specified if required */
if (fSearchConditionList.isEmpty() && !fMatchAllNewsRadio.getSelection()) {
setErrorMessage(Messages.NewsFilterDialog_ENTER_CONDITION);
fSearchConditionList.focusInput();
return;
}
/* Ensure that an Action is specified */
if (fFilterActionList.isEmpty()) {
setErrorMessage(Messages.NewsFilterDialog_CHOOSE_ACTION);
fFilterActionList.focusInput();
return;
}
/* Ensure that Actions are not conflicting */
List<IFilterAction> actions = fFilterActionList.createActions();
if (isConflicting(actions))
return;
/* Create new Filter and save */
if (fEditedFilter == null) {
fAddedFilter = createFilter(actions);
DynamicDAO.save(fAddedFilter);
}
/* Update existing Filter */
else {
updateFilter(actions);
DynamicDAO.save(fEditedFilter);
}
super.okPressed();
}
/**
* @return the {@link ISearchFilter} that was added or updated.
*/
public ISearchFilter getFilter() {
return fEditedFilter != null ? fEditedFilter : fAddedFilter;
}
private ISearchFilter createFilter(List<IFilterAction> actions) {
IModelFactory factory = Owl.getModelFactory();
ISearch search = createSearch();
/* Create Actions */
ISearchFilter filter = factory.createSearchFilter(null, search, fNameInput.getText());
filter.setEnabled(true);
filter.setMatchAllNews(fMatchAllNewsRadio.getSelection());
filter.setOrder(fFilterPosition);
for (IFilterAction action : actions) {
filter.addAction(action);
}
return filter;
}
private ISearch createSearch() {
IModelFactory factory = Owl.getModelFactory();
ISearch search = null;
ISearchCondition locationCondition = fLocationControl.toScopeCondition();
/* Only use Location Condition */
if (locationCondition != null && fMatchAllNewsRadio.getSelection()) {
search = factory.createSearch(null);
search.addSearchCondition(locationCondition);
}
/* Build Conditions from Location and List */
else if (!fMatchAllNewsRadio.getSelection()) {
List<ISearchCondition> conditions = fSearchConditionList.createConditions();
if (locationCondition != null)
conditions.add(locationCondition);
search = factory.createSearch(null);
search.setMatchAllConditions(fMatchAllRadio.getSelection());
for (ISearchCondition condition : conditions) {
search.addSearchCondition(condition);
}
}
return search;
}
private void updateFilter(List<IFilterAction> actions) {
/* Name */
fEditedFilter.setName(fNameInput.getText());
/* Actions */
if (fFilterActionList.isModified()) {
/* Remove Old Actions */
List<IFilterAction> oldActions = fEditedFilter.getActions();
for (IFilterAction oldAction : oldActions) {
fEditedFilter.removeAction(oldAction);
}
/* Add New Actions */
for (IFilterAction action : actions) {
fEditedFilter.addAction(action);
}
}
/* Update Conditioner */
fEditedFilter.setMatchAllNews(fMatchAllNewsRadio.getSelection());
/* Update Search */
ISearch oldSearch = fEditedFilter.getSearch();
fEditedFilter.setSearch(createSearch());
if (oldSearch != null)
DynamicDAO.delete(oldSearch);
}
private boolean isConflicting(List<IFilterAction> actions) {
for (IFilterAction action : actions) {
NewsActionDescriptor newsAction = fNewsActionPresentationManager.getNewsActionDescriptor(action.getActionId());
for (IFilterAction otherAction : actions) {
if (action == otherAction)
continue;
NewsActionDescriptor otherNewsAction = fNewsActionPresentationManager.getNewsActionDescriptor(otherAction.getActionId());
if (otherNewsAction.getNewsAction().conflictsWith(newsAction.getNewsAction())) {
StringBuilder str = new StringBuilder();
str.append(NLS.bind(Messages.NewsFilterDialog_REMOVE_ACTION_N, otherNewsAction.getName(), newsAction.getName()));
setErrorMessage(str.toString());
return true;
}
}
}
return false;
}
/*
* @see org.eclipse.jface.dialogs.TrayDialog#close()
*/
@Override
public boolean close() {
boolean res = super.close();
fResources.dispose();
return res;
}
/*
* @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createDialogArea(Composite parent) {
/* Separator */
new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL).setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
/* Title */
setTitle(Messages.NewsFilterDialog_NEWS_FILTER);
/* Title Image */
setTitleImage(OwlUI.getImage(fResources, "icons/wizban/filter_wiz.png")); //$NON-NLS-1$
/* Title Message */
setMessage(Messages.NewsFilterDialog_DEFINE_SEARCH);
/* Name Input Filed */
Composite container = new Composite(parent, SWT.None);
container.setLayout(LayoutUtils.createGridLayout(2, 10, 5, 0, 5, false));
container.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
Label nameLabel = new Label(container, SWT.NONE);
nameLabel.setText(Messages.NewsFilterDialog_NAME);
Composite nameContainer = new Composite(container, SWT.BORDER);
nameContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
nameContainer.setLayout(LayoutUtils.createGridLayout(2, 0, 0));
nameContainer.setBackground(container.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
fNameInput = new Text(nameContainer, SWT.SINGLE);
OwlUI.makeAccessible(fNameInput, nameLabel);
fNameInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
if (fEditedFilter != null) {
fNameInput.setText(fEditedFilter.getName());
fNameInput.selectAll();
}
fNameInput.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
setErrorMessage(null);
}
});
GC gc = new GC(fNameInput);
gc.setFont(JFaceResources.getDialogFont());
FontMetrics fontMetrics = gc.getFontMetrics();
int entryFieldWidth = Dialog.convertHorizontalDLUsToPixels(fontMetrics, IDialogConstants.ENTRY_FIELD_WIDTH);
gc.dispose();
((GridData) fNameInput.getLayoutData()).widthHint = entryFieldWidth; //Required to avoid large spanning dialog for long Links
ToolBar generateTitleBar = new ToolBar(nameContainer, SWT.FLAT);
OwlUI.makeAccessible(generateTitleBar, Messages.NewsFilterDialog_CREATE_NAME_FROM_CONDITIONS);
generateTitleBar.setBackground(container.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
ToolItem generateTitleItem = new ToolItem(generateTitleBar, SWT.PUSH);
generateTitleItem.setImage(OwlUI.getImage(fResources, "icons/etool16/info.gif")); //$NON-NLS-1$
generateTitleItem.setToolTipText(Messages.NewsFilterDialog_CREATE_NAME_FROM_CONDITIONS);
generateTitleItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onGenerateName();
}
});
/* Sashform dividing search definition from actions */
SashForm sashForm = new SashForm(parent, SWT.VERTICAL | SWT.SMOOTH);
sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
/* Top Sash */
Composite topSash = new Composite(sashForm, SWT.NONE);
topSash.setLayout(LayoutUtils.createGridLayout(2, 0, 0, 0, 0, false));
createConditionControls(topSash);
/* Bottom Sash */
Composite bottomSash = new Composite(sashForm, SWT.NONE);
bottomSash.setLayout(LayoutUtils.createGridLayout(1, 0, 0, 0, 0, false));
/* Label in between */
Composite labelContainer = new Composite(bottomSash, SWT.NONE);
labelContainer.setLayout(LayoutUtils.createGridLayout(1, 10, 3, 0, 0, false));
((GridLayout) labelContainer.getLayout()).marginBottom = 2;
labelContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
Label explanationLabel = new Label(labelContainer, SWT.NONE);
explanationLabel.setText(Messages.NewsFilterDialog_PERFORM_ACTIONS);
/* Action Controls */
createActionControls(bottomSash);
/* Separator */
new Label(bottomSash, SWT.SEPARATOR | SWT.HORIZONTAL).setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
/* Set weights to even */
sashForm.setWeights(new int[] { 50, 50 });
applyDialogFont(parent);
return parent;
}
/*
* @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createButtonBar(Composite parent) {
GridLayout layout = new GridLayout(1, false);
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
Composite buttonBar = new Composite(parent, SWT.NONE);
buttonBar.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
buttonBar.setLayout(layout);
/* Preview Link */
Link previewLink = new Link(buttonBar, SWT.NONE);
previewLink.setText(Messages.NewsFilterDialog_PREVIEW_SEARCH);
applyDialogFont(previewLink);
previewLink.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
previewLink.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onPreview();
}
});
/* Create Buttons */
createButtonsForButtonBar(buttonBar);
return buttonBar;
}
private void onPreview() {
final List<ISearchCondition> conditions = new ArrayList<ISearchCondition>();
/* Create Condition from Scope */
if (fMatchAllNewsRadio.getSelection()) {
ISearchCondition locationCondition = fLocationControl.toScopeCondition();
if (locationCondition != null) {
locationCondition.setSpecifier(SearchSpecifier.IS);
conditions.add(locationCondition);
}
}
/* Create Conditions from List */
else {
conditions.addAll(fSearchConditionList.createConditions());
if (!conditions.isEmpty()) {
ISearchCondition locationCondition = fLocationControl.toScopeCondition();
if (locationCondition != null)
conditions.add(locationCondition);
}
}
/* Show if conditions are present */
if (!conditions.isEmpty()) {
JobRunner.runInUIThread(getShell(), new Runnable() {
public void run() {
SearchNewsDialog dialog = new SearchNewsDialog(getShell(), conditions, fMatchAllRadio.getSelection(), true);
dialog.setBlockOnOpen(false);
dialog.open();
}
});
}
}
void onGenerateName() {
String name;
ISearchCondition locationCondition = fLocationControl.toScopeCondition();
if (fMatchAllNewsRadio.getSelection() && locationCondition == null) {
name = Messages.NewsFilterDialog_ALL_NEWS;
} else {
List<ISearchCondition> conditions = fSearchConditionList.createConditions();
if (locationCondition != null)
conditions.add(locationCondition);
name = CoreUtils.getName(conditions, fMatchAllRadio.getSelection());
}
if (name.length() > 0) {
fNameInput.setText(name);
fNameInput.selectAll();
}
}
private void createConditionControls(Composite container) {
Composite topControlsContainer = new Composite(container, SWT.None);
topControlsContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 2, 1));
topControlsContainer.setLayout(LayoutUtils.createGridLayout(6, 10, 3));
boolean matchAllNews = (fEditedFilter != null) ? fEditedFilter.matchAllNews() : fPresetMatchAll;
boolean matchAllConditions = !matchAllNews && (fEditedFilter != null) ? fEditedFilter.getSearch().matchAllConditions() : true;
if (fPresetSearch != null)
matchAllConditions = fPresetSearch.matchAllConditions();
/* Radio to select Condition Matching */
fMatchAllRadio = new Button(topControlsContainer, SWT.RADIO);
fMatchAllRadio.setText(Messages.NewsFilterDialog_MATCH_ALL_CONDITIONS);
fMatchAllRadio.setSelection(matchAllConditions && !matchAllNews);
fMatchAnyRadio = new Button(topControlsContainer, SWT.RADIO);
fMatchAnyRadio.setText(Messages.NewsFilterDialog_MATCH_ANY_CONDITION);
fMatchAnyRadio.setSelection(!matchAllConditions && !matchAllNews);
fMatchAllNewsRadio = new Button(topControlsContainer, SWT.RADIO);
fMatchAllNewsRadio.setText(Messages.NewsFilterDialog_MATCH_ALL);
fMatchAllNewsRadio.setSelection(matchAllNews);
fMatchAllNewsRadio.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setControlEnabled(fSearchConditionList, !fMatchAllNewsRadio.getSelection());
}
});
/* Separator */
Label sep = new Label(topControlsContainer, SWT.SEPARATOR | SWT.VERTICAL);
sep.setLayoutData(new GridData(SWT.DEFAULT, 20));
/* Scope */
Composite scopeContainer = new Composite(topControlsContainer, SWT.None);
scopeContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
scopeContainer.setLayout(LayoutUtils.createGridLayout(2, 0, 0, 0, 5, false));
Label locationLabel = new Label(scopeContainer, SWT.NONE);
locationLabel.setText(Messages.NewsFilterDialog_IN);
fLocationControl = new LocationControl(scopeContainer, SWT.WRAP) {
@Override
protected String getDefaultLabel() {
return Messages.NewsFilterDialog_ALL_NEWS;
}
};
fLocationControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
((GridData) fLocationControl.getLayoutData()).widthHint = 100;
fLocationControl.setLayout(LayoutUtils.createGridLayout(1, 0, 0, 0, 0, false));
/* ToolBar to add and select existing saved searches */
final ToolBarManager dialogToolBar = new ToolBarManager(SWT.RIGHT | SWT.FLAT);
/* Separator */
dialogToolBar.add(new Separator());
/* Existing Filters */
{
IAction existingFilters = new Action(Messages.NewsFilterDialog_SHOW_NEWS_FILTER, IAction.AS_DROP_DOWN_MENU) {
@Override
public void run() {
OwlUI.positionDropDownMenu(this, dialogToolBar);
}
@Override
public ImageDescriptor getImageDescriptor() {
return OwlUI.FILTER;
}
@Override
public String getId() {
return FILTERS_ACTION;
}
};
existingFilters.setMenuCreator(new ContextMenuCreator() {
@Override
public Menu createMenu(Control parent) {
Collection<ISearchFilter> filters = CoreUtils.loadSortedNewsFilters();
Menu menu = new Menu(parent);
/* Show Something if Collection is Empty */
if (filters.isEmpty()) {
MenuItem item = new MenuItem(menu, SWT.None);
item.setText(Messages.NewsFilterDialog_NO_FILTER);
item.setEnabled(false);
}
/* Show Existing News Filters */
for (final ISearchFilter filter : filters) {
MenuItem item = new MenuItem(menu, SWT.None);
item.setText(filter.getName());
item.setImage(OwlUI.getImage(fResources, OwlUI.FILTER));
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
/* Search */
if (filter.getSearch() != null)
showSearch(filter.getSearch());
/* Match All News */
if (filter.matchAllNews()) {
fMatchAnyRadio.setSelection(false);
fMatchAllRadio.setSelection(false);
fMatchAllNewsRadio.setSelection(true);
setControlEnabled(fSearchConditionList, false);
}
/* Actions */
fFilterActionList.showActions(filter.getActions());
}
});
}
return menu;
}
});
dialogToolBar.add(existingFilters);
}
/* Existing Saved Searches */
{
IAction savedSearches = new Action(Messages.NewsFilterDialog_SHOW_SAVED_SEARCH, IAction.AS_DROP_DOWN_MENU) {
@Override
public void run() {
OwlUI.positionDropDownMenu(this, dialogToolBar);
}
@Override
public ImageDescriptor getImageDescriptor() {
return OwlUI.SEARCHMARK;
}
@Override
public String getId() {
return SEARCHES_ACTION;
}
};
savedSearches.setMenuCreator(new ContextMenuCreator() {
@Override
public Menu createMenu(Control parent) {
Collection<ISearchMark> searchMarks = CoreUtils.loadSortedSearchMarks();
Menu menu = new Menu(parent);
/* Show Something if Collection is Empty */
if (searchMarks.isEmpty()) {
MenuItem item = new MenuItem(menu, SWT.None);
item.setText(Messages.NewsFilterDialog_NO_SAVED_SEARCH);
item.setEnabled(false);
}
/* Show Existing Saved Searches */
for (final ISearchMark searchMark : searchMarks) {
if (isSupported(searchMark)) {
MenuItem item = new MenuItem(menu, SWT.None);
item.setText(searchMark.getName());
item.setImage(OwlUI.getImage(fResources, OwlUI.SEARCHMARK));
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
showSearch(searchMark);
}
});
}
}
return menu;
}
});
dialogToolBar.add(savedSearches);
}
dialogToolBar.createControl(topControlsContainer);
dialogToolBar.getControl().setLayoutData(new GridData(SWT.END, SWT.BEGINNING, true, false));
/* Container for Conditions */
final Composite conditionsContainer = new Composite(container, SWT.NONE);
conditionsContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
conditionsContainer.setLayout(LayoutUtils.createGridLayout(2, 5, 10));
conditionsContainer.setBackground(container.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
conditionsContainer.setBackgroundMode(SWT.INHERIT_FORCE);
conditionsContainer.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
GC gc = e.gc;
Rectangle clArea = conditionsContainer.getClientArea();
gc.setForeground(conditionsContainer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
gc.drawLine(clArea.x, clArea.y, clArea.x + clArea.width, clArea.y);
gc.drawLine(clArea.x, clArea.y + clArea.height - 1, clArea.x + clArea.width, clArea.y + clArea.height - 1);
}
});
/* Search Conditions List */
fSearchConditionList = new SearchConditionList(conditionsContainer, SWT.None, getDefaultConditions(), fExcludedConditions);
fSearchConditionList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
fSearchConditionList.setVisibleItemCount(3);
/* Show Initial Conditions if present */
List<ISearchCondition> initialConditions = null;
if (fEditedFilter != null && fEditedFilter.getSearch() != null)
initialConditions = fEditedFilter.getSearch().getSearchConditions();
else if (fPresetSearch != null)
initialConditions = fPresetSearch.getSearchConditions();
if (initialConditions != null) {
Pair<ISearchCondition, List<ISearchCondition>> conditions = CoreUtils.splitScope(initialConditions);
Long[][] locationValue = null;
if (conditions.getFirst() != null && conditions.getFirst().getValue() instanceof Long[][])
locationValue = (Long[][]) conditions.getFirst().getValue();
fLocationControl.select(locationValue);
if (!conditions.getSecond().isEmpty())
fSearchConditionList.showConditions(conditions.getSecond());
if (CoreUtils.isLocationConflict(initialConditions))
setMessage(Messages.NewsFilterDialog_LOCATION_IN_WARNING, IMessageProvider.WARNING);
}
/* Update Enable-State of Search Condition List */
setControlEnabled(fSearchConditionList, !fMatchAllNewsRadio.getSelection());
/* Generate Name if preset */
if (fPresetSearch != null)
onGenerateName();
}
/* Load a search into the UI */
private void showSearch(ISearch search) {
/* Match Conditions */
fMatchAllRadio.setSelection(search.matchAllConditions());
fMatchAnyRadio.setSelection(!search.matchAllConditions());
fMatchAllNewsRadio.setSelection(false);
setControlEnabled(fSearchConditionList, true);
/* Location */
Pair<ISearchCondition, List<ISearchCondition>> conditions = CoreUtils.splitScope(search.getSearchConditions());
Long[][] location = null;
if (conditions.getFirst() != null && conditions.getFirst().getValue() instanceof Long[][])
location = (Long[][]) conditions.getFirst().getValue();
fLocationControl.select(location);
/* Show Conditions */
fSearchConditionList.showConditions(conditions.getSecond());
/* Layout */
fLocationControl.getParent().getParent().getParent().layout(true, true);
}
private void setControlEnabled(Control control, boolean enabled) {
control.setEnabled(enabled);
if (control instanceof Composite) {
Composite composite = (Composite) control;
Control[] children = composite.getChildren();
for (Control child : children) {
setControlEnabled(child, enabled);
}
}
}
private boolean isSupported(ISearchMark searchmark) {
List<ISearchCondition> conditions = searchmark.getSearchConditions();
for (ISearchCondition condition : conditions) {
if (fExcludedConditions.contains(condition.getField().getId()))
return false;
}
return true;
}
/* We allow all conditions because a filter could also be run on existing news! */
private List<Integer> getExcludedConditions() {
return Collections.emptyList();
}
private List<ISearchCondition> getDefaultConditions() {
List<ISearchCondition> conditions = new ArrayList<ISearchCondition>(1);
IModelFactory factory = Owl.getModelFactory();
ISearchField field = factory.createSearchField(IEntity.ALL_FIELDS, INews.class.getName());
ISearchCondition condition = factory.createSearchCondition(field, SearchSpecifier.CONTAINS_ALL, ""); //$NON-NLS-1$
conditions.add(condition);
return conditions;
}
private void createActionControls(Composite container) {
/* Container for Actions */
final Composite actionsContainer = new Composite(container, SWT.NONE);
actionsContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
actionsContainer.setLayout(LayoutUtils.createGridLayout(2, 5, 10));
actionsContainer.setBackground(container.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
actionsContainer.setBackgroundMode(SWT.INHERIT_FORCE);
actionsContainer.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
GC gc = e.gc;
Rectangle clArea = actionsContainer.getClientArea();
gc.setForeground(actionsContainer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
gc.drawLine(clArea.x, clArea.y, clArea.x + clArea.width, clArea.y);
}
});
/* Action List */
fFilterActionList = new NewsActionList(actionsContainer, SWT.NONE, getDefaultActions());
fFilterActionList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
fFilterActionList.setVisibleItemCount(3);
/* Show initial Actions if present */
if (fEditedFilter != null)
fFilterActionList.showActions(fEditedFilter.getActions());
else if (fPresetActions != null)
fFilterActionList.showActions(fPresetActions);
}
private List<IFilterAction> getDefaultActions() {
List<IFilterAction> defaultActions = new ArrayList<IFilterAction>(1);
IModelFactory factory = Owl.getModelFactory();
defaultActions.add(factory.createFilterAction(MoveNewsAction.ID));
return defaultActions;
}
/*
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
*/
@Override
protected void configureShell(Shell shell) {
super.configureShell(shell);
if (fEditedFilter == null)
shell.setText(Messages.NewsFilterDialog_NEW_FILTER);
else
shell.setText(NLS.bind(Messages.NewsFilterDialog_EDIT_NEWS_FILTER_N, fEditedFilter.getName()));
}
/*
* @see org.eclipse.jface.dialogs.Dialog#isResizable()
*/
@Override
protected boolean isResizable() {
return true;
}
/*
* @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsStrategy()
*/
@Override
protected int getDialogBoundsStrategy() {
return DIALOG_PERSISTSIZE;
}
/*
* @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
*/
@Override
protected IDialogSettings getDialogBoundsSettings() {
IDialogSettings settings = Activator.getDefault().getDialogSettings();
IDialogSettings section = settings.getSection(SETTINGS_SECTION);
if (section != null)
return section;
return settings.addNewSection(SETTINGS_SECTION);
}
}