/* ********************************************************************** ** ** 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.cleanup; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IFontProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeViewerListener; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; 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.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Scrollable; import org.eclipse.swt.widgets.TreeItem; import org.rssowl.core.persist.IBookMark; import org.rssowl.ui.internal.Activator; import org.rssowl.ui.internal.Application; import org.rssowl.ui.internal.ApplicationWorkbenchWindowAdvisor; import org.rssowl.ui.internal.OwlUI; import org.rssowl.ui.internal.dialogs.PreviewFeedDialog; import org.rssowl.ui.internal.util.JobRunner; import org.rssowl.ui.internal.util.LayoutUtils; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * @author bpasero */ public class CleanUpSummaryPage extends WizardPage { private CheckboxTreeViewer fViewer; private ResourceManager fResources; private Button fSelectAll; private Button fDeselectAll; private Button fDisplayFeedButton; /* Summary Label Provider */ class SummaryLabelProvider extends LabelProvider implements IFontProvider, IColorProvider { private Color fGradientFgColor; private Color fGradientBgColor; private Color fGradientEndColor; private Color fGroupFgColor; SummaryLabelProvider() { fGradientFgColor = OwlUI.getColor(fResources, OwlUI.GROUP_GRADIENT_FG_COLOR); fGradientBgColor = OwlUI.getColor(fResources, OwlUI.GROUP_GRADIENT_BG_COLOR); fGradientEndColor = OwlUI.getColor(fResources, OwlUI.GROUP_GRADIENT_END_COLOR); fGroupFgColor = OwlUI.getColor(fResources, OwlUI.GROUP_FG_COLOR); } @Override public String getText(Object element) { if (element instanceof CleanUpGroup) return ((CleanUpGroup) element).getLabel(); return ((CleanUpTask) element).getLabel(); } @Override public Image getImage(Object element) { if (element instanceof CleanUpGroup) return OwlUI.getImage(fResources, OwlUI.GROUP); return OwlUI.getImage(fResources, ((CleanUpTask) element).getImage()); } public Font getFont(Object element) { if (element instanceof CleanUpGroup) return OwlUI.getBold(JFaceResources.DEFAULT_FONT); return null; } public Color getBackground(Object element) { return null; } public Color getForeground(Object element) { if (element instanceof CleanUpGroup && !OwlUI.isHighContrast()) return fGroupFgColor; return null; } void eraseGroup(Event event) { Scrollable scrollable = (Scrollable) event.widget; GC gc = event.gc; Rectangle area = scrollable.getClientArea(); Rectangle rect = event.getBounds(); /* Paint the selection beyond the end of last column */ OwlUI.codExpandRegion(event, scrollable, gc, area); /* Draw Gradient Rectangle */ Color oldForeground = gc.getForeground(); Color oldBackground = gc.getBackground(); /* Gradient */ gc.setForeground(fGradientFgColor); gc.setBackground(fGradientBgColor); gc.fillGradientRectangle(0, rect.y, area.width, rect.height, true); /* Bottom Line */ gc.setForeground(fGradientEndColor); gc.drawLine(0, rect.y + rect.height - 1, area.width, rect.y + rect.height - 1); gc.setForeground(oldForeground); gc.setBackground(oldBackground); /* Mark as Background being handled */ event.detail &= ~SWT.BACKGROUND; } } /** * @param pageName */ protected CleanUpSummaryPage(String pageName) { super(pageName, pageName, OwlUI.getImageDescriptor("icons/wizban/cleanup_wiz.gif")); //$NON-NLS-1$ setMessage(Messages.CleanUpSummaryPage_REVIEW_OPS); fResources = new LocalResourceManager(JFaceResources.getResources()); } List<CleanUpTask> getTasks() { Object[] checkedElements = fViewer.getCheckedElements(); List<CleanUpTask> tasks = new ArrayList<CleanUpTask>(checkedElements.length); for (Object checkedElement : checkedElements) if (checkedElement instanceof CleanUpTask) tasks.add((CleanUpTask) checkedElement); return tasks; } /* * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { Composite container = new Composite(parent, SWT.NONE); container.setLayout(new GridLayout(1, false)); /* Viewer to select particular Tasks */ fViewer = new CheckboxTreeViewer(container, SWT.BORDER | SWT.FULL_SELECTION); fViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); fViewer.getTree().setData(ApplicationWorkbenchWindowAdvisor.FOCUSLESS_SCROLL_HOOK, new Object()); /* ContentProvider */ fViewer.setContentProvider(new ITreeContentProvider() { public Object[] getElements(Object inputElement) { if (inputElement instanceof List<?>) return ((List<?>) inputElement).toArray(); return new Object[0]; } public Object[] getChildren(Object parentElement) { if (parentElement instanceof CleanUpGroup) { CleanUpGroup group = (CleanUpGroup) parentElement; return group.getTasks().toArray(); } return new Object[0]; } public Object getParent(Object element) { if (element instanceof CleanUpTask) return ((CleanUpTask) element).getGroup(); return null; } public boolean hasChildren(Object element) { return element instanceof CleanUpGroup; } public void dispose() {} public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} }); /* LabelProvider */ final SummaryLabelProvider summaryLabelProvider = new SummaryLabelProvider(); fViewer.setLabelProvider(summaryLabelProvider); /* Custom Owner Drawn Category */ if (!OwlUI.isHighContrast()) { fViewer.getControl().addListener(SWT.EraseItem, new Listener() { public void handleEvent(Event event) { Object element = event.item.getData(); if (element instanceof CleanUpGroup) summaryLabelProvider.eraseGroup(event); } }); } /* Listen on Doubleclick */ fViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { onDoubleClick(event); } }); /* Update Checks on Selection */ fViewer.getTree().addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onSelect(e); } }); /* Update Display Button on Selection */ fViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { fDisplayFeedButton.setEnabled(((IStructuredSelection) event.getSelection()).getFirstElement() instanceof BookMarkTask); } }); /* Update Checks on Expand */ fViewer.addTreeListener(new ITreeViewerListener() { public void treeExpanded(TreeExpansionEvent event) { onExpand(event); } public void treeCollapsed(TreeExpansionEvent event) {} }); /* Select All / Deselect All */ Composite buttonContainer = new Composite(container, SWT.NONE); buttonContainer.setLayout(LayoutUtils.createGridLayout(4, 0, 0)); buttonContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); fSelectAll = new Button(buttonContainer, SWT.PUSH); fSelectAll.setText(Messages.CleanUpSummaryPage_SELECT_ALL); Dialog.applyDialogFont(fSelectAll); setButtonLayoutData(fSelectAll); fSelectAll.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { OwlUI.setAllChecked(fViewer.getTree(), true); } }); fDeselectAll = new Button(buttonContainer, SWT.PUSH); fDeselectAll.setText(Messages.CleanUpSummaryPage_DESELECT_ALL); Dialog.applyDialogFont(fDeselectAll); setButtonLayoutData(fDeselectAll); fDeselectAll.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { OwlUI.setAllChecked(fViewer.getTree(), false); } }); if (!Application.IS_MAC) { Label sep = new Label(buttonContainer, SWT.SEPARATOR | SWT.VERTICAL); sep.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false)); ((GridData) sep.getLayoutData()).heightHint = 20; } fDisplayFeedButton = new Button(buttonContainer, SWT.PUSH); fDisplayFeedButton.setText(Messages.CleanUpSummaryPage_DISPLAY); fDisplayFeedButton.setEnabled(false); fDisplayFeedButton.setToolTipText(Messages.CleanUpSummaryPage_DISPLAY_FEED); Dialog.applyDialogFont(fDisplayFeedButton); setButtonLayoutData(fDisplayFeedButton); fDisplayFeedButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { showFeeds((IStructuredSelection) fViewer.getSelection()); } }); Dialog.applyDialogFont(container); setControl(container); } /* * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean) */ @Override public void setVisible(boolean visible) { super.setVisible(visible); /* Generate the Summary */ if (visible) { CleanUpOptionsPage cleanUpOptionsPage = (CleanUpOptionsPage) getPreviousPage(); FeedSelectionPage feedSelectionPage = (FeedSelectionPage) cleanUpOptionsPage.getPreviousPage(); final Set<IBookMark> selection = feedSelectionPage.getSelection(); final CleanUpOperations operations = cleanUpOptionsPage.getOperations(); IRunnableWithProgress runnable = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { monitor.beginTask(Messages.CleanUpSummaryPage_WAIT_GENERATE_PREVIEW, IProgressMonitor.UNKNOWN); onGenerateSummary(operations, selection, monitor); } }; try { getContainer().run(true, true, runnable); } catch (InvocationTargetException e) { Activator.getDefault().logError(e.getMessage(), e); } catch (InterruptedException e) { Activator.getDefault().logError(e.getMessage(), e); } } } private void onGenerateSummary(CleanUpOperations operations, Set<IBookMark> selection, IProgressMonitor monitor) { final CleanUpModel model = new CleanUpModel(operations, selection); model.generate(monitor); /* Show in Viewer */ JobRunner.runInUIThread(fViewer.getTree(), new Runnable() { public void run() { fViewer.setInput(model.getTasks()); fViewer.expandAll(); OwlUI.setAllChecked(fViewer.getTree(), true); } }); } /* * @see org.eclipse.jface.wizard.WizardPage#isPageComplete() */ @Override public boolean isPageComplete() { return isCurrentPage(); } /* * @see org.eclipse.jface.dialogs.DialogPage#dispose() */ @Override public void dispose() { super.dispose(); fResources.dispose(); } private void onDoubleClick(DoubleClickEvent event) { IStructuredSelection selection = (IStructuredSelection) event.getSelection(); CleanUpGroup group = selection.getFirstElement() instanceof CleanUpGroup ? (CleanUpGroup) selection.getFirstElement() : null; /* Expand / Collapse Folder */ if (group != null) { boolean expandedState = !fViewer.getExpandedState(group); fViewer.setExpandedState(group, expandedState); if (expandedState && fViewer.getChecked(group)) setChildsChecked(group, true); } /* Display Bookmark */ else if (selection.getFirstElement() instanceof BookMarkTask) { showFeeds(selection); } } private void showFeeds(IStructuredSelection selection) { if (!selection.isEmpty()) { Object firstElement = selection.getFirstElement(); if (firstElement instanceof BookMarkTask) { IBookMark bookmark = ((BookMarkTask) firstElement).getMark(); PreviewFeedDialog dialog = new PreviewFeedDialog(getShell(), bookmark, bookmark.getFeedLinkReference()); dialog.setBlockOnOpen(false); dialog.open(); } } } private void onSelect(SelectionEvent e) { if (e.detail == SWT.CHECK) { TreeItem item = (TreeItem) e.item; if (item.getData() instanceof CleanUpGroup) setChildsChecked((CleanUpGroup) item.getData(), item.getChecked()); if (!item.getChecked() && item.getData() instanceof CleanUpTask) setParentsChecked((CleanUpTask) item.getData(), false); } } private void onExpand(TreeExpansionEvent event) { boolean isChecked = fViewer.getChecked(event.getElement()); if (isChecked) setChildsChecked((CleanUpGroup) event.getElement(), isChecked); } private void setChildsChecked(CleanUpGroup cleanUpGroup, boolean checked) { List<CleanUpTask> children = cleanUpGroup.getTasks(); for (CleanUpTask child : children) fViewer.setChecked(child, checked); } private void setParentsChecked(CleanUpTask cleanUpTask, boolean checked) { CleanUpGroup parent = cleanUpTask.getGroup(); if (parent != null) fViewer.setChecked(parent, checked); } }