PageRenderTime 164ms CodeModel.GetById 42ms app.highlight 87ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/rssowl-2.0.5/org.rssowl.ui/src/org/rssowl/ui/internal/editors/feed/NewsTableLabelProvider.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 747 lines | 463 code | 129 blank | 155 comment | 172 complexity | 1e2251624952e251022daea7cf61be15 MD5 | raw file
  1/*   **********************************************************************  **
  2 **   Copyright notice                                                       **
  3 **                                                                          **
  4 **   (c) 2005-2009 RSSOwl Development Team                                  **
  5 **   http://www.rssowl.org/                                                 **
  6 **                                                                          **
  7 **   All rights reserved                                                    **
  8 **                                                                          **
  9 **   This program and the accompanying materials are made available under   **
 10 **   the terms of the Eclipse Public License v1.0 which accompanies this    **
 11 **   distribution, and is available at:                                     **
 12 **   http://www.rssowl.org/legal/epl-v10.html                               **
 13 **                                                                          **
 14 **   A copy is found in the file epl-v10.html and important notices to the  **
 15 **   license from the team is found in the textfile LICENSE.txt distributed **
 16 **   in this package.                                                       **
 17 **                                                                          **
 18 **   This copyright notice MUST APPEAR in all copies of the file!           **
 19 **                                                                          **
 20 **   Contributors:                                                          **
 21 **     RSSOwl Development Team - initial API and implementation             **
 22 **                                                                          **
 23 **  **********************************************************************  */
 24
 25package org.rssowl.ui.internal.editors.feed;
 26
 27import org.eclipse.jface.resource.ImageDescriptor;
 28import org.eclipse.jface.resource.JFaceResources;
 29import org.eclipse.jface.resource.LocalResourceManager;
 30import org.eclipse.jface.viewers.ColumnViewer;
 31import org.eclipse.jface.viewers.OwnerDrawLabelProvider;
 32import org.eclipse.jface.viewers.ViewerCell;
 33import org.eclipse.jface.viewers.ViewerColumn;
 34import org.eclipse.osgi.util.NLS;
 35import org.eclipse.swt.SWT;
 36import org.eclipse.swt.graphics.Color;
 37import org.eclipse.swt.graphics.Font;
 38import org.eclipse.swt.graphics.GC;
 39import org.eclipse.swt.graphics.Image;
 40import org.eclipse.swt.graphics.Point;
 41import org.eclipse.swt.graphics.RGB;
 42import org.eclipse.swt.graphics.Rectangle;
 43import org.eclipse.swt.widgets.Display;
 44import org.eclipse.swt.widgets.Event;
 45import org.eclipse.swt.widgets.Item;
 46import org.eclipse.swt.widgets.Scrollable;
 47import org.eclipse.swt.widgets.TableItem;
 48import org.eclipse.swt.widgets.TreeItem;
 49import org.rssowl.core.persist.IAttachment;
 50import org.rssowl.core.persist.IBookMark;
 51import org.rssowl.core.persist.ICategory;
 52import org.rssowl.core.persist.ILabel;
 53import org.rssowl.core.persist.INews;
 54import org.rssowl.core.persist.INewsBin;
 55import org.rssowl.core.persist.IPerson;
 56import org.rssowl.core.persist.INews.State;
 57import org.rssowl.core.persist.dao.DynamicDAO;
 58import org.rssowl.core.persist.reference.NewsBinReference;
 59import org.rssowl.core.util.CoreUtils;
 60import org.rssowl.core.util.DateUtils;
 61import org.rssowl.core.util.StringUtils;
 62import org.rssowl.core.util.URIUtils;
 63import org.rssowl.ui.internal.Application;
 64import org.rssowl.ui.internal.EntityGroup;
 65import org.rssowl.ui.internal.OwlUI;
 66
 67import java.text.DateFormat;
 68import java.util.Date;
 69import java.util.HashMap;
 70import java.util.List;
 71import java.util.Map;
 72import java.util.Set;
 73
 74/**
 75 * @author Ismael Juma (ismael@juma.me.uk)
 76 * @author bpasero
 77 */
 78public class NewsTableLabelProvider extends OwnerDrawLabelProvider {
 79
 80  /** News Column Model to use */
 81  protected NewsColumnViewModel fColumnModel;
 82
 83  /* Some Colors of a Label */
 84  private static final String LABEL_COLOR_BLACK = "0,0,0"; //$NON-NLS-1$
 85  private static final String LABEL_COLOR_WHITE = "255,255,255"; //$NON-NLS-1$
 86
 87  /** Resource Manager to use */
 88  protected LocalResourceManager fResources;
 89
 90  /* Date Formatter for News */
 91  private final DateFormat fDateFormat = OwlUI.getShortDateFormat();
 92
 93  /* Pre-Cache some Colors being used */
 94  private Color fStickyBgColor;
 95  private Color fGradientFgColor;
 96  private Color fGradientBgColor;
 97  private Color fGradientEndColor;
 98  private Color fGroupFgColor;
 99  private Color fGroupBgColor;
100  private Color fNewsBgGradientStartColor;
101  private Color fNewsBgGradientEndColor;
102  private RGB fListBackground;
103  private RGB fListSelectionBackground;
104
105  /* Pre-Cache some Images being used */
106  private Image fNewsUnreadIcon;
107  private Image fNewsNewIcon;
108  private Image fNewsUpdatedIcon;
109  private Image fNewsReadIcon;
110  private Image fNewsStickyIcon;
111  private Image fNewsNonStickyIcon;
112  private Image fGroupIcon;
113
114  /* Pre-Cache some Fonts being used */
115  private Font fBoldFont;
116
117  /* A cache for the Feed and Location Column */
118  private Map<Long, String> fMapBinIdToLocation = new HashMap<Long, String>();
119  private Map<String, String> fMapFeedLinkToLocation = new HashMap<String, String>();
120  private Map<String, ImageDescriptor> fMapFeedLinkToFeedIcon = new HashMap<String, ImageDescriptor>();
121
122  /**
123   * Creates a new instance of this LabelProvider
124   *
125   * @param model the column model.
126   */
127  public NewsTableLabelProvider(NewsColumnViewModel model) {
128    fColumnModel = model;
129    fResources = new LocalResourceManager(JFaceResources.getResources());
130    createResources();
131  }
132
133  /*
134   * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#initialize(org.eclipse.jface.viewers.ColumnViewer, org.eclipse.jface.viewers.ViewerColumn)
135   */
136  @Override
137  protected void initialize(ColumnViewer viewer, ViewerColumn column) {
138    super.initialize(viewer, column, false); //Disable Custom Ownerdrawn
139  }
140
141  /**
142   * @param model
143   */
144  public void init(NewsColumnViewModel model) {
145    fColumnModel = model;
146  }
147
148  void updateResources() {
149
150    /* Sticky Color */
151    fStickyBgColor = OwlUI.getThemeColor(OwlUI.STICKY_BG_COLOR_ID, fResources, new RGB(255, 255, 180));
152
153    /* News Background Color */
154    createNewsListBackgroundResources();
155  }
156
157  private void createResources() {
158
159    /* Colors */
160    fStickyBgColor = OwlUI.getThemeColor(OwlUI.STICKY_BG_COLOR_ID, fResources, new RGB(255, 255, 180));
161    fGradientFgColor = OwlUI.getColor(fResources, OwlUI.GROUP_GRADIENT_FG_COLOR);
162    fGradientBgColor = OwlUI.getColor(fResources, OwlUI.GROUP_GRADIENT_BG_COLOR);
163    fGradientEndColor = OwlUI.getColor(fResources, OwlUI.GROUP_GRADIENT_END_COLOR);
164    fGroupFgColor = OwlUI.getColor(fResources, OwlUI.GROUP_FG_COLOR);
165    fGroupBgColor = OwlUI.getColor(fResources, OwlUI.GROUP_BG_COLOR);
166
167    fListBackground = fResources.getDevice().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB();
168    fListSelectionBackground = fResources.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB();
169
170    createNewsListBackgroundResources();
171
172    /* Icons */
173    fNewsUnreadIcon = OwlUI.getImage(fResources, OwlUI.NEWS_STATE_UNREAD);
174    fNewsNewIcon = OwlUI.getImage(fResources, OwlUI.NEWS_STATE_NEW);
175    fNewsUpdatedIcon = OwlUI.getImage(fResources, OwlUI.NEWS_STATE_UPDATED);
176    fNewsReadIcon = OwlUI.getImage(fResources, OwlUI.NEWS_STATE_READ);
177    fNewsStickyIcon = OwlUI.getImage(fResources, OwlUI.NEWS_PINNED);
178    fNewsNonStickyIcon = OwlUI.getImage(fResources, OwlUI.NEWS_PIN);
179    fGroupIcon = OwlUI.getImage(fResources, OwlUI.GROUP);
180
181    /* Fonts */
182    fBoldFont = OwlUI.getThemeFont(OwlUI.HEADLINES_FONT_ID, SWT.BOLD);
183  }
184
185  private void createNewsListBackgroundResources() {
186    fNewsBgGradientStartColor = null;
187    fNewsBgGradientEndColor = null;
188
189    RGB listBackgroundRGB = Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB();
190    RGB newsBgColorRGB = OwlUI.getThemeRGB(OwlUI.NEWS_LIST_BG_COLOR_ID, listBackgroundRGB);
191    if (newsBgColorRGB != null && !listBackgroundRGB.equals(newsBgColorRGB) && !isInvalidColor(newsBgColorRGB)) {
192      fNewsBgGradientEndColor = OwlUI.getColor(fResources, newsBgColorRGB);
193
194      RGB newsBgColorRGBLighter = new RGB(0, 0, 0);
195      newsBgColorRGBLighter.red = Math.min(newsBgColorRGB.red + 5, 255);
196      newsBgColorRGBLighter.green = Math.min(newsBgColorRGB.green + 5, 255);
197      newsBgColorRGBLighter.blue = Math.min(newsBgColorRGB.blue + 5, 255);
198      fNewsBgGradientStartColor = OwlUI.getColor(fResources, newsBgColorRGBLighter);
199    }
200  }
201
202  /*
203   * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#update(org.eclipse.jface.viewers.ViewerCell)
204   */
205  @Override
206  public void update(ViewerCell cell) {
207    NewsColumn column = fColumnModel.getColumn(cell.getColumnIndex());
208
209    /* Text */
210    cell.setText(getColumnText(cell.getElement(), column, cell.getColumnIndex()));
211
212    /* Image */
213    cell.setImage(getColumnImage(cell.getElement(), column, cell.getColumnIndex()));
214
215    /* Font */
216    cell.setFont(getFont(cell.getElement(), cell.getColumnIndex()));
217
218    /* Foreground */
219    Color foreground = getForeground(cell.getElement(), cell.getColumnIndex());
220
221    /* This is required to invalidate + redraw the entire TableItem! */
222    if (!OwlUI.isHighContrast()) {
223      Item item = (Item) cell.getItem();
224      if (item instanceof TreeItem)
225        ((TreeItem) cell.getItem()).setForeground(foreground);
226      else if (item instanceof TableItem)
227        ((TableItem) cell.getItem()).setForeground(foreground);
228    }
229
230    /* Background */
231    if (!OwlUI.isHighContrast())
232      cell.setBackground(getBackground(cell.getElement(), cell.getColumnIndex()));
233  }
234
235  /*
236   * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipText(java.lang.Object)
237   */
238  @Override
239  public String getToolTipText(Object element) {
240
241    /* News */
242    if (element instanceof INews) {
243      INews news = (INews) element;
244      String feedRef = news.getFeedLinkAsText();
245      IBookMark bookMark = CoreUtils.getBookMark(feedRef);
246
247      String name = null;
248      if (bookMark != null)
249        name = bookMark.getName();
250      else
251        name = feedRef;
252
253      if (news.getParentId() != 0) {
254        INewsBin bin = DynamicDAO.load(INewsBin.class, news.getParentId());
255        if (bin != null) {
256          name = NLS.bind(Messages.NewsTableLabelProvider_BIN_NAME, bin.getName(), name);
257        }
258      }
259
260      return StringUtils.replaceAll(name, "&", "&&"); //$NON-NLS-1$ //$NON-NLS-2$
261    }
262
263    /* Entity Group */
264    else if (element instanceof EntityGroup) {
265      return StringUtils.replaceAll(((EntityGroup) element).getName(), "&", "&&"); //$NON-NLS-1$ //$NON-NLS-2$
266    }
267
268    return super.getToolTipText(element);
269  }
270
271  /*
272   * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipShift(java.lang.Object)
273   */
274  @Override
275  public Point getToolTipShift(Object object) {
276    if (Application.IS_WINDOWS)
277      return new Point(0, 21);
278
279    return super.getToolTipShift(object);
280  }
281
282  /**
283   * @param element
284   * @param column
285   * @param colIndex
286   * @return String
287   */
288  protected String getColumnText(Object element, NewsColumn column, int colIndex) {
289    String text = null;
290
291    /* Handle News */
292    if (element instanceof INews) {
293      INews news = (INews) element;
294
295      switch (column) {
296        case TITLE:
297          text = CoreUtils.getHeadline(news, true);
298          break;
299
300        case DATE:
301          Date date = DateUtils.getRecentDate(news);
302          text = fDateFormat.format(date);
303          break;
304
305        case PUBLISHED:
306          Date published = news.getPublishDate();
307          if (published != null)
308            text = fDateFormat.format(published);
309          break;
310
311        case MODIFIED:
312          Date modified = news.getModifiedDate();
313          if (modified != null)
314            text = fDateFormat.format(modified);
315          break;
316
317        case RECEIVED:
318          Date received = news.getReceiveDate();
319          if (received != null)
320            text = fDateFormat.format(received);
321          break;
322
323        case AUTHOR:
324          IPerson author = news.getAuthor();
325          if (author != null) {
326            if (author.getName() != null)
327              text = author.getName();
328            else if (author.getEmail() != null)
329              text = author.getEmail().toString();
330          }
331          break;
332
333        case CATEGORY:
334          List<ICategory> categories = news.getCategories();
335          if (!categories.isEmpty()) {
336            StringBuilder str = new StringBuilder();
337            for (ICategory category : categories) {
338              if (StringUtils.isSet(category.getName()))
339                str.append(category.getName().trim()).append(", "); //$NON-NLS-1$
340              else if (StringUtils.isSet(category.getDomain()))
341                str.append(category.getDomain().trim()).append(", "); //$NON-NLS-1$
342            }
343
344            if (str.length() > 0)
345              str = str.delete(str.length() - 2, str.length());
346            text = str.toString();
347          }
348          break;
349
350        case LABELS:
351          Set<ILabel> labels = CoreUtils.getSortedLabels(news);
352          if (!labels.isEmpty()) {
353            StringBuilder str = new StringBuilder();
354            for (ILabel label : labels) {
355              str.append(label.getName()).append(", "); //$NON-NLS-1$
356            }
357
358            if (str.length() > 0)
359              str = str.delete(str.length() - 2, str.length());
360            text = str.toString();
361          }
362          break;
363
364        case STATUS:
365          State state = news.getState();
366          if (state == State.NEW)
367            text = Messages.NewsTableLabelProvider_NEW;
368          else if (state == State.UNREAD)
369            text = Messages.NewsTableLabelProvider_UNREAD;
370          else if (state == State.UPDATED)
371            text = Messages.NewsTableLabelProvider_UPDATED;
372          else if (state == State.READ)
373            text = Messages.NewsTableLabelProvider_READ;
374
375          break;
376
377        case LOCATION:
378
379          /* Location: Bin */
380          if (news.getParentId() > 0) {
381            String location = fMapBinIdToLocation.get(news.getParentId());
382            if (location == null) {
383              NewsBinReference ref = new NewsBinReference(news.getParentId());
384              INewsBin bin = ref.resolve();
385              location = bin.getName();
386              fMapBinIdToLocation.put(news.getParentId(), location);
387            }
388
389            text = location;
390          }
391
392          /* Location: Bookmark */
393          else {
394            String location = fMapFeedLinkToLocation.get(news.getFeedLinkAsText());
395            if (location == null) {
396              IBookMark bookmark = CoreUtils.getBookMark(news.getFeedLinkAsText());
397              if (bookmark != null) {
398                location = bookmark.getName();
399                fMapFeedLinkToLocation.put(news.getFeedLinkAsText(), location);
400              }
401            }
402
403            text = location;
404          }
405          break;
406
407        case LINK:
408          text = CoreUtils.getLink(news);
409          if (StringUtils.isSet(text)) {
410            text = StringUtils.replaceAll(text, URIUtils.HTTP, ""); //$NON-NLS-1$
411            text = StringUtils.replaceAll(text, "www.", ""); //$NON-NLS-1$ //$NON-NLS-2$
412          }
413      }
414    }
415
416    /* Handle EntityGroup */
417    else if (element instanceof EntityGroup && column == NewsColumn.TITLE)
418      text = ((EntityGroup) element).getName();
419
420    /* Make sure to normalize the Text for the Table */
421    return text != null ? StringUtils.normalizeString(text) : null;
422  }
423
424  /**
425   * @param element
426   * @param newsColumn
427   * @param colIndex
428   * @return Image
429   */
430  protected Image getColumnImage(Object element, NewsColumn newsColumn, int colIndex) {
431
432    /* News */
433    if (element instanceof INews) {
434      INews news = (INews) element;
435
436      /* News Icon */
437      if (newsColumn == NewsColumn.TITLE) {
438        if (news.getState() == INews.State.UNREAD)
439          return fNewsUnreadIcon;
440        else if (news.getState() == INews.State.NEW)
441          return fNewsNewIcon;
442        else if (news.getState() == INews.State.UPDATED)
443          return fNewsUpdatedIcon;
444        else if (news.getState() == INews.State.READ)
445          return fNewsReadIcon;
446      }
447
448      /* Feed Column */
449      else if (newsColumn == NewsColumn.FEED) {
450        String feedRef = news.getFeedLinkAsText();
451        ImageDescriptor feedIcon = fMapFeedLinkToFeedIcon.get(feedRef);
452        if (feedIcon == null) {
453          IBookMark bookMark = CoreUtils.getBookMark(feedRef);
454          if (bookMark != null)
455            feedIcon = OwlUI.getFavicon(bookMark);
456
457          if (feedIcon == null)
458            feedIcon = OwlUI.BOOKMARK;
459
460          fMapFeedLinkToFeedIcon.put(feedRef, feedIcon);
461        }
462
463        return OwlUI.getImage(fResources, feedIcon);
464      }
465
466      /* Sticky State */
467      else if (newsColumn == NewsColumn.STICKY) {
468        if (news.isFlagged())
469          return fNewsStickyIcon;
470
471        return fNewsNonStickyIcon;
472      }
473
474      /* Attachment */
475      else if (newsColumn == NewsColumn.ATTACHMENTS) {
476        List<IAttachment> attachments = news.getAttachments();
477        if (!attachments.isEmpty())
478          return OwlUI.getImage(fResources, OwlUI.ATTACHMENT);
479      }
480    }
481
482    /* EntityGroup Image */
483    else if (element instanceof EntityGroup && newsColumn == NewsColumn.TITLE) {
484      EntityGroup group = (EntityGroup) element;
485      if (group.getImage() != null)
486        return OwlUI.getImage(fResources, group.getImage());
487
488      return fGroupIcon;
489    }
490
491    return null;
492  }
493
494  /**
495   * @param element
496   * @param columnIndex
497   * @return Font
498   */
499  protected Font getFont(Object element, int columnIndex) {
500
501    /* Use a Bold Font for Unread News */
502    if (element instanceof INews) {
503      INews news = (INews) element;
504      INews.State state = news.getState();
505      if (state == null)
506        return null;
507
508      /* Bold for New, Updated and Unread News */
509      if (state == INews.State.NEW || state == INews.State.UPDATED || state == INews.State.UNREAD)
510        return fBoldFont;
511    }
512
513    /* Use Bold Font for EntityGroup */
514    if (element instanceof EntityGroup)
515      return fBoldFont;
516
517    return null;
518  }
519
520  /**
521   * @param element
522   * @param columnIndex
523   * @return Color
524   */
525  protected Color getBackground(Object element, int columnIndex) {
526
527    /* Handle INews */
528    if (element instanceof INews && ((INews) element).isFlagged())
529      return fStickyBgColor;
530
531    /* Handle EntityGroup */
532    else if (element instanceof EntityGroup)
533      return fGroupBgColor;
534
535    return null;
536  }
537
538  /**
539   * @param element
540   * @param columnIndex
541   * @return Color
542   */
543  protected Color getForeground(Object element, int columnIndex) {
544
545    /* Handle EntityGroup */
546    if (element instanceof EntityGroup) {
547      EntityGroup group = (EntityGroup) element;
548      if (group.getColorHint() != null) {
549        if (!fListBackground.equals(group.getColorHint()) && !fListSelectionBackground.equals(group.getColorHint()))
550          return OwlUI.getColor(fResources, group.getColorHint());
551      }
552
553      return fGroupFgColor;
554    }
555
556    /* Handle INews */
557    else if (element instanceof INews) {
558      Set<ILabel> labels = CoreUtils.getSortedLabels((INews) element);
559      if (!labels.isEmpty()) {
560        RGB labelRGB = OwlUI.getRGB(labels.iterator().next());
561        if (!fListBackground.equals(labelRGB) && !fListSelectionBackground.equals(labelRGB))
562          return OwlUI.getColor(fResources, labelRGB);
563      }
564    }
565
566    return null;
567  }
568
569  /*
570   * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
571   */
572  @Override
573  public void dispose() {
574    fResources.dispose();
575  }
576
577  /*
578   * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
579   * java.lang.String)
580   */
581  @Override
582  public boolean isLabelProperty(Object element, String property) {
583    return false;
584  }
585
586  /*
587   * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#erase(org.eclipse.swt.widgets.Event,
588   * java.lang.Object)
589   */
590  @Override
591  public void erase(Event event, Object element) {
592
593    /* Erase News */
594    if (element instanceof INews)
595      eraseNews(event, (INews) element);
596
597    /* Erase Group */
598    else if (element instanceof EntityGroup)
599      eraseGroup(event, (EntityGroup) element);
600
601  }
602
603  private void eraseGroup(Event event, EntityGroup group) {
604    Scrollable scrollable = (Scrollable) event.widget;
605    GC gc = event.gc;
606
607    /* Draw Color if Selected */
608    if (group.getColorHint() != null && (event.detail & SWT.SELECTED) != 0) {
609
610      /* Some conditions under which we don't override the selection color */
611      if (!scrollable.isFocusControl() || isInvalidColor(group.getColorHint()))
612        return;
613
614      Rectangle clArea = scrollable.getClientArea();
615      Rectangle itemRect = event.getBounds();
616
617      /* Paint the selection beyond the end of last column */
618      OwlUI.codExpandRegion(event, scrollable, gc, clArea);
619
620      /* Draw Rectangle */
621      Color oldBackground = gc.getBackground();
622      gc.setBackground(OwlUI.getColor(fResources, group.getColorHint()));
623      gc.fillRectangle(0, itemRect.y, clArea.width, itemRect.height);
624      gc.setBackground(oldBackground);
625      gc.setForeground(scrollable.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
626
627      /* Mark as Selected being handled */
628      event.detail &= ~SWT.SELECTED;
629    }
630
631    /* Draw Gradient */
632    else
633      OwlUI.codDrawGradient(event, fGradientFgColor, fGradientBgColor, fGradientEndColor);
634  }
635
636  private void eraseNews(Event event, INews news) {
637    Scrollable scrollable = (Scrollable) event.widget;
638    GC gc = event.gc;
639
640    /* Handle selected News (Linux: Note Bug 444) */
641    if ((event.detail & SWT.SELECTED) != 0 && (Application.IS_WINDOWS || !news.isFlagged())) {
642
643      /* Do not override selection color if not focus control */
644      if (!scrollable.isFocusControl())
645        return;
646
647      /* Load Labels */
648      Set<ILabel> labels = CoreUtils.getSortedLabels(news);
649      if (labels.isEmpty())
650        return;
651
652      ILabel label = labels.iterator().next();
653      if (isInvalidColor(label))
654        return;
655
656      Rectangle clArea = scrollable.getClientArea();
657      Rectangle itemRect = event.getBounds();
658
659      /* Paint the selection beyond the end of last column */
660      OwlUI.codExpandRegion(event, scrollable, gc, clArea);
661
662      /* Draw Rectangle */
663      Color oldBackground = gc.getBackground();
664      gc.setBackground(OwlUI.getColor(fResources, label));
665      gc.fillRectangle(0, itemRect.y, clArea.width, itemRect.height);
666      gc.setBackground(oldBackground);
667      gc.setForeground(scrollable.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
668
669      /* Mark as Selected being handled */
670      event.detail &= ~SWT.SELECTED;
671    }
672
673    /* Handle Non-Selected flagged News */
674    else if (news.isFlagged()) {
675      Rectangle clArea = scrollable.getClientArea();
676      Rectangle itemRect = event.getBounds();
677
678      /* Paint the selection beyond the end of last column */
679      OwlUI.codExpandRegion(event, scrollable, gc, clArea);
680
681      /* Draw Rectangle */
682      Color oldBackground = gc.getBackground();
683      gc.setBackground(fStickyBgColor);
684      gc.fillRectangle(0, itemRect.y, clArea.width, itemRect.height);
685      gc.setBackground(oldBackground);
686
687      /* Mark as Background being handled */
688      event.detail &= ~SWT.BACKGROUND;
689    }
690
691    /* Handle News List Background Color if set */
692    else if (fNewsBgGradientStartColor != null && fNewsBgGradientEndColor != null) {
693      int index = 0;
694
695      /* Tree */
696      if (event.item instanceof TreeItem) {
697        TreeItem item = (TreeItem) event.item;
698        TreeItem parentItem = item.getParentItem();
699        if (parentItem != null)
700          index = parentItem.indexOf(item);
701        else
702          index = item.getParent().indexOf(item);
703      }
704
705      /* Table */
706      else if (event.item instanceof TableItem) {
707        TableItem item = (TableItem) event.item;
708        index = item.getParent().indexOf(item);
709      }
710
711      if (index % 2 != 0)
712        OwlUI.codDrawGradient(event, fNewsBgGradientStartColor, fNewsBgGradientEndColor, fNewsBgGradientEndColor);
713    }
714  }
715
716  private boolean isInvalidColor(ILabel label) {
717    return label.getColor().equals(LABEL_COLOR_BLACK) || label.getColor().equals(LABEL_COLOR_WHITE);
718  }
719
720  private boolean isInvalidColor(RGB color) {
721    if (color.blue == 0 && color.red == 0 && color.green == 0)
722      return true;
723
724    if (color.blue == 255 && color.red == 255 && color.green == 255)
725      return true;
726
727    return false;
728  }
729
730  /*
731   * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#measure(org.eclipse.swt.widgets.Event,
732   * java.lang.Object)
733   */
734  @Override
735  protected void measure(Event event, Object element) {
736  /* Ignore */
737  }
738
739  /*
740   * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#paint(org.eclipse.swt.widgets.Event,
741   * java.lang.Object)
742   */
743  @Override
744  protected void paint(Event event, Object element) {
745  /* Ignore */
746  }
747}