/* ********************************************************************** **
** 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.views.explorer;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.DecorationOverlayIcon;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Event;
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.INews;
import org.rssowl.core.persist.INewsBin;
import org.rssowl.core.persist.INewsMark;
import org.rssowl.core.persist.ISearchMark;
import org.rssowl.ui.internal.EntityGroup;
import org.rssowl.ui.internal.OwlUI;
import java.util.EnumSet;
import java.util.List;
/**
* @author bpasero
*/
public class BookMarkLabelProvider extends CellLabelProvider {
/* Resource Manager */
private LocalResourceManager fResources;
/* Commonly used Resources */
private Image fFolderIcon;
private Image fFolderNewIcon;
private Image fBookMarkErrorIcon;
private Image fBookMarkIcon;
private Image fSearchMarkIcon;
private Image fSearchMarkNewIcon;
private Image fSearchMarkEmptyIcon;
private Image fGroupIcon;
private Image fBookmarkSetIcon;
private Image fArchiveIcon;
private Image fArchiveNewIcon;
private Image fNewsBinIcon;
private Image fNewsBinNewIcon;
private Image fNewsBinEmptyIcon;
private Color fStickyBgColor;
private Color fGradientFgColor;
private Color fGradientBgColor;
private Color fGradientEndColor;
private Color fGroupFgColor;
private Font fBoldFont;
private Font fDefaultFont;
/* Settings */
private boolean fIndicateState;
private final boolean fUseDialogFont;
private boolean fUseFavicons = true;
/* Helper to compute a Folders Decoration */
private static class FolderDecorationHelper {
int fNewCount;
int fUnreadCount;
boolean fHasSticky;
}
/** Default Constructor */
public BookMarkLabelProvider() {
this(true);
}
/**
* @param indicateState
*/
public BookMarkLabelProvider(boolean indicateState) {
this(indicateState, false);
}
/**
* @param indicateState
* @param useDialogFont
*/
public BookMarkLabelProvider(boolean indicateState, boolean useDialogFont) {
fIndicateState = indicateState;
fUseDialogFont = useDialogFont;
fResources = new LocalResourceManager(JFaceResources.getResources());
createResources();
}
void updateResources() {
/* Sticky Color */
fStickyBgColor = OwlUI.getThemeColor(OwlUI.STICKY_BG_COLOR_ID, fResources, new RGB(255, 255, 180));
}
void setUseFavicons(boolean useFavicons) {
fUseFavicons = useFavicons;
}
private void createResources() {
/* Images */
fBookmarkSetIcon = OwlUI.getImage(fResources, OwlUI.BOOKMARK_SET);
fGroupIcon = OwlUI.getImage(fResources, OwlUI.GROUP);
fFolderIcon = OwlUI.getImage(fResources, OwlUI.FOLDER);
fFolderNewIcon = OwlUI.getImage(fResources, OwlUI.FOLDER_NEW);
fBookMarkErrorIcon = OwlUI.getImage(fResources, OwlUI.BOOKMARK_ERROR);
fBookMarkIcon = OwlUI.getImage(fResources, OwlUI.BOOKMARK);
fSearchMarkIcon = OwlUI.getImage(fResources, OwlUI.SEARCHMARK);
fSearchMarkNewIcon = OwlUI.getImage(fResources, OwlUI.SEARCHMARK_NEW);
fSearchMarkEmptyIcon = OwlUI.getImage(fResources, OwlUI.SEARCHMARK_EMPTY);
fArchiveIcon = OwlUI.getImage(fResources, OwlUI.ARCHIVE);
fArchiveNewIcon = OwlUI.getImage(fResources, OwlUI.ARCHIVE_NEW);
fNewsBinIcon = OwlUI.getImage(fResources, OwlUI.NEWSBIN);
fNewsBinNewIcon = OwlUI.getImage(fResources, OwlUI.NEWSBIN_NEW);
fNewsBinEmptyIcon = OwlUI.getImage(fResources, OwlUI.NEWSBIN_EMPTY);
/* Fonts */
fBoldFont = OwlUI.getThemeFont(fUseDialogFont ? OwlUI.DIALOG_FONT_ID : OwlUI.BKMRK_EXPLORER_FONT_ID, SWT.BOLD);
fDefaultFont = OwlUI.getThemeFont(fUseDialogFont ? OwlUI.DIALOG_FONT_ID : OwlUI.BKMRK_EXPLORER_FONT_ID, SWT.NORMAL);
/* Colors */
fStickyBgColor = OwlUI.getThemeColor(OwlUI.STICKY_BG_COLOR_ID, fResources, new RGB(255, 255, 180));
fGroupFgColor = OwlUI.getColor(fResources, OwlUI.GROUP_FG_COLOR);
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);
}
/*
* @see org.eclipse.jface.viewers.CellLabelProvider#update(org.eclipse.jface.viewers.ViewerCell)
*/
@Override
public void update(ViewerCell cell) {
Object element = cell.getElement();
int unreadNewsCount = 0;
/* Create Label for a Folder */
if (element instanceof IFolder) {
IFolder folder = (IFolder) element;
int newNewsCount = 0;
boolean hasSticky = false;
if (fIndicateState) {
FolderDecorationHelper helper = new FolderDecorationHelper();
computeFolderDecoration(folder, helper);
hasSticky = helper.fHasSticky;
unreadNewsCount = helper.fUnreadCount;
newNewsCount = helper.fNewCount;
}
/* Image */
if (folder.getParent() == null)
cell.setImage(fBookmarkSetIcon);
else if (newNewsCount == 0)
cell.setImage(fFolderIcon);
else
cell.setImage(fFolderNewIcon);
/* Font */
if (unreadNewsCount > 0)
cell.setFont(fBoldFont);
else
cell.setFont(fDefaultFont);
/* Text */
if (unreadNewsCount > 0)
cell.setText(NLS.bind(Messages.BookMarkLabelProvider_NAME_UNREAD, folder.getName(), unreadNewsCount));
else
cell.setText(folder.getName());
/* Reset Foreground */
cell.setForeground(null);
/* Background Color */
if (hasSticky && !OwlUI.isHighContrast())
cell.setBackground(fStickyBgColor);
else
cell.setBackground(null);
}
/* Create generic Label for instances of INewsMark */
else if (element instanceof INewsMark) {
boolean hasNew = false;
int stickyNewsCount = 0;
INewsMark newsmark = (INewsMark) element;
if (fIndicateState) {
unreadNewsCount = newsmark.getNewsCount(EnumSet.of(INews.State.NEW, INews.State.UNREAD, INews.State.UPDATED));
hasNew = newsmark.getNewsCount(EnumSet.of(INews.State.NEW)) != 0;
}
/* Font */
if (unreadNewsCount > 0)
cell.setFont(fBoldFont);
else
cell.setFont(fDefaultFont);
/* Text */
if (unreadNewsCount > 0)
cell.setText(NLS.bind(Messages.BookMarkLabelProvider_NAME_UNREAD, newsmark.getName(), unreadNewsCount));
else
cell.setText(newsmark.getName());
/* Background for IBookMark (TODO Support All News Marks) */
if (newsmark instanceof IBookMark && fIndicateState)
stickyNewsCount = ((IBookMark) newsmark).getStickyNewsCount();
/* Background Color */
if (stickyNewsCount > 0 && !OwlUI.isHighContrast())
cell.setBackground(fStickyBgColor);
else
cell.setBackground(null);
/* Reset Foreground */
cell.setForeground(null);
/* Icon */
if (newsmark instanceof IBookMark)
cell.setImage(getIconForBookMark((IBookMark) newsmark, hasNew));
else if (newsmark instanceof ISearchMark)
cell.setImage(getIconForSearchMark((ISearchMark) newsmark, hasNew, unreadNewsCount));
else if (newsmark instanceof INewsBin)
cell.setImage(getIconForNewsBin((INewsBin) newsmark, hasNew, unreadNewsCount));
}
/* Create Label for EntityGroup */
else if (element instanceof EntityGroup) {
EntityGroup group = (EntityGroup) element;
/* Text */
cell.setText(group.getName());
/* Image */
cell.setImage(fGroupIcon);
/* Foreground */
if (!OwlUI.isHighContrast())
cell.setForeground(fGroupFgColor);
/* Reset Background */
cell.setBackground(null);
/* Font */
cell.setFont(fBoldFont);
}
}
private Image getIconForBookMark(IBookMark bookmark, boolean hasNew) {
/* Load the FavIcon (if enabled) */
ImageDescriptor favicon = fUseFavicons ? OwlUI.getFavicon(bookmark) : null;
/* Indicate Error */
if (bookmark.isErrorLoading()) {
/* Overlay with Error Icon if required */
if (favicon != null) {
Image faviconImg = OwlUI.getImage(fResources, favicon);
DecorationOverlayIcon overlay = new DecorationOverlayIcon(faviconImg, OwlUI.getImageDescriptor("icons/ovr16/error.gif"), IDecoration.BOTTOM_RIGHT); //$NON-NLS-1$
return OwlUI.getImage(fResources, overlay);
}
/* Default Error Icon */
return fBookMarkErrorIcon;
}
/* Use normal Icon */
Image icon = favicon != null ? OwlUI.getImage(fResources, favicon) : fBookMarkIcon;
/* Overlay if News are *new* */
if (hasNew) {
DecorationOverlayIcon overlay = new DecorationOverlayIcon(icon, OwlUI.getImageDescriptor("icons/ovr16/new.gif"), IDecoration.BOTTOM_RIGHT); //$NON-NLS-1$
return OwlUI.getImage(fResources, overlay);
}
/* Don't overlay */
return icon;
}
private Image getIconForSearchMark(ISearchMark searchmark, boolean hasNew, int unreadNewsCount) {
boolean hasMatchingNews = unreadNewsCount > 0 || searchmark.getNewsCount(EnumSet.of(INews.State.NEW, INews.State.UNREAD, INews.State.UPDATED, INews.State.READ)) != 0;
if (hasNew)
return fSearchMarkNewIcon;
else if (hasMatchingNews)
return fSearchMarkIcon;
else
return fSearchMarkEmptyIcon;
}
private Image getIconForNewsBin(INewsBin newsbin, boolean hasNew, int unreadNewsCount) {
boolean hasMatchingNews = unreadNewsCount > 0 || newsbin.getNewsCount(EnumSet.of(INews.State.NEW, INews.State.UNREAD, INews.State.UPDATED, INews.State.READ)) != 0;
boolean isArchive = newsbin.getProperty(DefaultPreferences.ARCHIVE_BIN_MARKER) != null;
if (hasNew)
return isArchive ? fArchiveNewIcon : fNewsBinNewIcon;
else if (isArchive)
return fArchiveIcon;
else if (hasMatchingNews)
return fNewsBinIcon;
else
return fNewsBinEmptyIcon;
}
/*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
*/
@Override
public void dispose() {
fResources.dispose();
}
/*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
* java.lang.String)
*/
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
private void computeFolderDecoration(IFolder folder, FolderDecorationHelper helper) {
List<IFolderChild> children = folder.getChildren();
for (IFolderChild child : children) {
/* News Mark */
if (child instanceof INewsMark) {
INewsMark newsMark = (INewsMark) child;
helper.fUnreadCount += getUnreadNewsCount(newsMark);
helper.fNewCount += newsMark.getNewsCount(EnumSet.of(INews.State.NEW));
if (!helper.fHasSticky && newsMark instanceof IBookMark && ((IBookMark) newsMark).getStickyNewsCount() > 0)
helper.fHasSticky = true;
}
/* Folder */
else if (child instanceof IFolder)
computeFolderDecoration((IFolder) child, helper);
}
}
private int getUnreadNewsCount(INewsMark newsMark) {
return newsMark.getNewsCount(EnumSet.of(INews.State.NEW, INews.State.UNREAD, INews.State.UPDATED));
}
void erase(Event event, Object element) {
if (element instanceof EntityGroup)
OwlUI.codDrawGradient(event, fGradientFgColor, fGradientBgColor, fGradientEndColor);
}
}