/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2003-2006 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 1.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 - initial API and implementation (bpasero@rssowl.org)         **
 **                                                                          **
 **  **********************************************************************  */

package net.sourceforge.rssowl.controller;

import net.sourceforge.rssowl.controller.dialog.ToolBarDialog;
import net.sourceforge.rssowl.controller.thread.ExtendedThread;
import net.sourceforge.rssowl.controller.thread.SettingsManager;
import net.sourceforge.rssowl.model.Category;
import net.sourceforge.rssowl.util.GlobalSettings;
import net.sourceforge.rssowl.util.i18n.ITranslatable;
import net.sourceforge.rssowl.util.search.SearchDefinition;
import net.sourceforge.rssowl.util.search.SearchPatternParser;
import net.sourceforge.rssowl.util.shop.FontShop;
import net.sourceforge.rssowl.util.shop.HotkeyShop;
import net.sourceforge.rssowl.util.shop.LayoutShop;
import net.sourceforge.rssowl.util.shop.PaintShop;
import net.sourceforge.rssowl.util.shop.RegExShop;
import net.sourceforge.rssowl.util.shop.StringShop;
import net.sourceforge.rssowl.util.shop.WidgetShop;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
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 java.util.Vector;

/**
 * This is the RSS Quickview controll that is displayed directly under the
 * menue. It includes the ToolBar as well.
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class Quickview implements ITranslatable, IFontChangeable {

  /** ToolBar Mode: Show only Icons */
  public static final int TOOLBAR_MODE_ICONS = 1;

  /** ToolBar Mode: Show Icons and Text */
  public static final int TOOLBAR_MODE_ICONS_TEXT = 0;

  /** ToolBar Mode: Show only Text */
  public static final int TOOLBAR_MODE_TEXT = 2;

  /** Delay before the Search is beginning */
  private static final int SEARCH_DELAY = 400;

  private MenuItem aggregateFavorites;
  private Composite bottomContainer;
  private Composite centerContainer;
  private ToolItem closeAllItem;
  private ToolItem closeOtherItem;
  private MenuItem customizeBar;
  private MenuItem discoverFeedItem;
  private MenuItem exportOPML;
  private MenuItem importBlogroll;
  private MenuItem importOPML;
  private CLabel liveSearchLabel;
  private MenuItem markAllRead;
  private MenuItem markFeedRead;
  private MenuItem markNewsUnread;
  private MenuItem newCategory;
  private MenuItem newFavorite;
  private MenuItem newSubCategory;
  private MenuItem nextMessageItem;
  private MenuItem nextUnreadItem;
  private MenuItem preferencesItem;
  private Menu quickviewMenu;
  private MenuItem reloadFavorites;
  private ExtendedThread searchDelayThread;
  private MenuItem searchFavorites;
  private MenuItem searchFeedItem;
  private Label sep;
  private Composite topContainer;
  private Label urlLabelQuickView;
  private MenuItem validateFeedItem;
  private Menu wildCardMenu;
  ToolBar centerToolBar;
  ToolItem closeItem;
  DropTarget comboDNDTarget;
  EventManager eventManager;
  ToolItem exportItem;
  Menu exportMenu;
  ToolItem favoritesItem;
  Menu favoritesMenu;
  ToolItem historyItem;
  Menu historyMenu;
  ToolItem importItem;
  Menu importMenu;
  ToolBar leftToolBar;
  Text liveSearch;
  ToolItem mailNewsTip;
  ToolItem markReadItem;
  ToolItem newItem;
  Menu newMenu;
  ToolItem nextNewsItem;
  ToolItem nextTab;
  ToolItem previousTab;
  MenuItem quickviewState;
  ToolItem reloadItem;
  GUI rssOwlGui;
  MenuItem searchAndItem;
  ToolItem searchItem;
  MenuItem searchNotItem;
  MenuItem searchOrItem;
  Shell shell;
  boolean stopLiveSearch;
  MenuItem toolBarState;
  ViewForm toolbarViewForm;
  ToolItem toolsItem;
  Combo urlTestCombo;

  /**
   * Instantiate a new Quickview
   * 
   * @param rssOwlGui Access some methods of the main controller
   * @param shell The shell
   * @param eventManager The event manager
   */
  public Quickview(GUI rssOwlGui, Shell shell, EventManager eventManager) {
    this.rssOwlGui = rssOwlGui;
    this.shell = shell;
    this.eventManager = eventManager;
    initComponents();
  }

  /**
   * Clear the live search input field
   */
  public void clearLiveSearch() {
    stopLiveSearch = true;
    liveSearch.setText("");
    stopLiveSearch = false;
  }

  /**
   * Create the ToolBar. The ToolBar is created using the user-defined setting.
   */
  public void createToolBar() {
    String items[] = GlobalSettings.toolBarItems.split(",");
    int pivot = getPivot(items);
    boolean useIcons = GlobalSettings.toolBarMode != TOOLBAR_MODE_TEXT;

    /** First dispose the old Toolbars */
    if (leftToolBar != null)
      leftToolBar.dispose();

    if (centerToolBar != null)
      centerToolBar.dispose();

    /** Re-Create the Context Menu since it might has been disposed as well */
    if (!WidgetShop.isset(quickviewMenu))
      initContextMenu(toolbarViewForm);

    /** Left ToolBar */
    leftToolBar = new ToolBar(topContainer, SWT.FLAT);
    leftToolBar.setBackground(PaintShop.grayViewFormColor);
    leftToolBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
    leftToolBar.setMenu(quickviewMenu);

    /** Center ToolBar if required */
    if (items.length > 1) {
      centerToolBar = new ToolBar(centerContainer, SWT.FLAT);
      centerToolBar.setBackground(PaintShop.grayViewFormColor);
      centerToolBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
      centerToolBar.setMenu(quickviewMenu);
    }

    /** The Image Path is dependant on usage of Big or Small Icons */
    String toolImgPath = GlobalSettings.useSmallIcons ? "/img/icons/" : "/img/icons/24x24/";

    /** Foreach ToolItem */
    for (int i = 0; i < items.length; i++) {
      String itemValue = items[i];

      /**
       * Decide which ToolBar to use. In case we are still left from the Pivot,
       * use the left ToolBar. Otherwise proceed with the center ToolBar.
       */
      final ToolBar toolBar = i < pivot ? leftToolBar : centerToolBar;

      /** Drop Down: New Favorite and New Category */
      if (itemValue.equals(ToolBarDialog.TOOLITEM_NEW)) {
        newItem = new ToolItem(toolBar, SWT.DROP_DOWN);

        if (useIcons) {
          newItem.setImage(GlobalSettings.useSmallIcons ? PaintShop.iconNew : PaintShop.loadImage(toolImgPath + "add_category_small.gif"));
          newItem.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
              if (newItem.getImage() != PaintShop.iconNew)
                newItem.getImage().dispose();
            }
          });
        }

        /** Create New Menu */
        newMenu = new Menu(toolBar);

        /** Handle Drop Down Selection */
        newItem.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event event) {

            /** Make popupmenue visible */
            if (event.detail == SWT.ARROW) {
              Rectangle rect = newItem.getBounds();
              Point pt = new Point(rect.x, rect.y + rect.height);
              pt = newItem.getParent().toDisplay(pt);
              newMenu.setLocation(pt.x, pt.y);
              newMenu.setVisible(true);
            }

            /** Perform default operation: New Favorite */
            else {
              eventManager.actionNewFavorite();
            }
          }
        });

        /** New Favorite Item */
        newFavorite = new MenuItem(newMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          newFavorite.setImage(PaintShop.iconAddToFavorites);
        newFavorite.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionNewFavorite();
          }
        });

        /** Separator */
        new MenuItem(newMenu, SWT.SEPARATOR);

        /** New Category Item */
        newCategory = new MenuItem(newMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          newCategory.setImage(PaintShop.iconAddCategory);
        newCategory.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionNewCategory();
          }
        });

        /** New Sub-Category Item */
        newSubCategory = new MenuItem(newMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          newSubCategory.setImage(PaintShop.iconSubCategory);
        newSubCategory.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionNewCategory(true);
          }
        });

        /** Register to MenuManager */
        MenuManager.registerNewSubMenuItems(newCategory, newSubCategory);
      }

      /** Drop Down: Import OPML, Import Synchronized Blogroll */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_IMPORT)) {
        importItem = new ToolItem(toolBar, SWT.DROP_DOWN);

        if (useIcons) {
          importItem.setImage(GlobalSettings.useSmallIcons ? PaintShop.iconImport : PaintShop.loadImage(toolImgPath + "import.gif"));
          importItem.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
              if (importItem.getImage() != PaintShop.iconImport)
                importItem.getImage().dispose();
            }
          });
        }

        /** Import Menu */
        importMenu = new Menu(toolBar);

        /** Handle Drop Down Selection */
        importItem.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event event) {

            /** Make popupmenue visible */
            if (event.detail == SWT.ARROW) {
              Rectangle rect = importItem.getBounds();
              Point pt = new Point(rect.x, rect.y + rect.height);
              pt = importItem.getParent().toDisplay(pt);
              importMenu.setLocation(pt.x, pt.y);
              importMenu.setVisible(true);
            }

            /** Perform default operation */
            else {
              eventManager.actionImportOPML();
            }
          }
        });

        /** Import OPML */
        importOPML = new MenuItem(importMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          importOPML.setImage(PaintShop.iconImportOpml);
        importOPML.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionImportOPML();
          }
        });

        /** Import Synchronized Blogroll */
        importBlogroll = new MenuItem(importMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          importBlogroll.setImage(PaintShop.iconAddBlogroll);
        importBlogroll.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionImportBlogroll();
          }
        });
      }

      /** Drop Down: Export To OPML */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_EXPORT)) {
        exportItem = new ToolItem(toolBar, SWT.DROP_DOWN);

        if (useIcons) {
          exportItem.setImage(GlobalSettings.useSmallIcons ? PaintShop.iconExport : PaintShop.loadImage(toolImgPath + "export.gif"));
          exportItem.setDisabledImage(PaintShop.loadImage(toolImgPath + "export_disabled.gif"));
          exportItem.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
              if (exportItem.getImage() != PaintShop.iconExport)
                exportItem.getImage().dispose();

              exportItem.getDisabledImage().dispose();
            }
          });
        }

        /** Export Menu */
        exportMenu = new Menu(toolBar);

        /** Handle Drop Down Selection */
        exportItem.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event event) {

            /** Make popupmenue visible */
            if (event.detail == SWT.ARROW) {
              Rectangle rect = exportItem.getBounds();
              Point pt = new Point(rect.x, rect.y + rect.height);
              pt = exportItem.getParent().toDisplay(pt);
              exportMenu.setLocation(pt.x, pt.y);
              exportMenu.setVisible(true);
            }

            /** Perform default operation */
            else {
              eventManager.actionCategoryToOPML(Category.getRootCategory(), "rssowl.opml");
            }
          }
        });

        /** Export To OPML */
        exportOPML = new MenuItem(exportMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          exportOPML.setImage(PaintShop.iconExportOpml);
        exportOPML.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionCategoryToOPML(Category.getRootCategory(), "rssowl.opml");
          }
        });

        /** Register to MenuManager */
        MenuManager.registerExportToolItem(exportItem);
      }

      /** Reload Feed */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_RELOAD)) {
        reloadItem = new ToolItem(toolBar, SWT.PUSH);

        if (useIcons) {
          reloadItem.setImage(GlobalSettings.useSmallIcons ? PaintShop.iconReload : PaintShop.loadImage(toolImgPath + "reload.gif"));
          reloadItem.setDisabledImage(PaintShop.loadImage(toolImgPath + "reload_disabled.gif"));
          reloadItem.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
              if (reloadItem.getImage() != PaintShop.iconReload)
                reloadItem.getImage().dispose();
              reloadItem.getDisabledImage().dispose();
            }
          });
        }

        reloadItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionReload();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerReloadToolItem(reloadItem);
      }

      /** Search Feed */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_SEARCH)) {
        searchItem = new ToolItem(toolBar, SWT.PUSH);

        if (useIcons) {
          searchItem.setImage(GlobalSettings.useSmallIcons ? PaintShop.iconFind : PaintShop.loadImage(toolImgPath + "search.gif"));
          searchItem.setDisabledImage(PaintShop.loadImage(toolImgPath + "search_disabled.gif"));
          searchItem.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
              if (searchItem.getImage() != PaintShop.iconFind)
                searchItem.getImage().dispose();
              searchItem.getDisabledImage().dispose();
            }
          });
        }

        searchItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionSearch();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerSearchToolItem(searchItem);
      }

      /** Drop Down: Mark Read */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_MARK)) {
        markReadItem = new ToolItem(toolBar, SWT.DROP_DOWN);

        if (useIcons) {
          markReadItem.setImage(PaintShop.loadImage(toolImgPath + "mark_feed_read.gif"));
          markReadItem.setDisabledImage(PaintShop.loadImage(toolImgPath + "mark_feed_read_disabled.gif"));
          markReadItem.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        /** Mark Read Menu */
        final Menu markReadMenu = new Menu(toolBar);

        /** Handle Drop Down Selection */
        markReadItem.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event event) {

            /** Make popupmenue visible */
            if (event.detail == SWT.ARROW) {
              Rectangle rect = markReadItem.getBounds();
              Point pt = new Point(rect.x, rect.y + rect.height);
              pt = markReadItem.getParent().toDisplay(pt);
              markReadMenu.setLocation(pt.x, pt.y);
              markReadMenu.setVisible(true);
            }

            /** Perform default operation */
            else {
              eventManager.actionMarkAllNewsRead();
            }
          }
        });

        /** Mark Feed Read */
        markFeedRead = new MenuItem(markReadMenu, SWT.PUSH);
        markFeedRead.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionMarkAllNewsRead();
          }
        });

        /** Separator */
        new MenuItem(markReadMenu, SWT.SEPARATOR);

        /** Mark News Unread */
        markNewsUnread = new MenuItem(markReadMenu, SWT.PUSH);
        markNewsUnread.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionMarkNewsUnread();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerMarkAllReadToolItem(markReadItem);
      }

      /** Dropdown: Next unread News and next News */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_NEXT)) {
        nextNewsItem = new ToolItem(toolBar, SWT.DROP_DOWN);

        if (useIcons) {
          nextNewsItem.setImage(PaintShop.loadImage(toolImgPath + "next_unread.gif"));
          nextNewsItem.setDisabledImage(PaintShop.loadImage(toolImgPath + "next_unread_disabled.gif"));
          nextNewsItem.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        /** Next News Menu */
        final Menu nextNewsMenu = new Menu(toolBar);

        /** Handle Drop Down Selection */
        nextNewsItem.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event event) {

            /** Make popupmenue visible */
            if (event.detail == SWT.ARROW) {
              Rectangle rect = nextNewsItem.getBounds();
              Point pt = new Point(rect.x, rect.y + rect.height);
              pt = nextNewsItem.getParent().toDisplay(pt);
              nextNewsMenu.setLocation(pt.x, pt.y);
              nextNewsMenu.setVisible(true);
            }

            /** Perform default operation */
            else {
              eventManager.actionGotoNextUnreadNews();
            }
          }
        });

        /** Next Unread Message */
        nextUnreadItem = new MenuItem(nextNewsMenu, SWT.PUSH);
        nextUnreadItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionGotoNextUnreadNews();
          }
        });

        /** Separator */
        new MenuItem(nextNewsMenu, SWT.SEPARATOR);

        /** Next Message */
        nextMessageItem = new MenuItem(nextNewsMenu, SWT.PUSH);
        nextMessageItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionGotoNextNews();
          }
        });
      }

      /** Drop Down: Mark All Read, Aggregate Favs, Reload Favs, Search Favs */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_FAVORITES)) {
        favoritesItem = new ToolItem(toolBar, SWT.DROP_DOWN);

        if (useIcons) {
          favoritesItem.setImage(PaintShop.loadImage(toolImgPath + "favorites.gif"));
          favoritesItem.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        /** Favorites Menu */
        favoritesMenu = new Menu(toolBar);

        /** Handle Drop Down Selection */
        favoritesItem.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event event) {

            /** Make popupmenue visible */
            Rectangle rect = favoritesItem.getBounds();
            Point pt = new Point(rect.x, rect.y + rect.height);
            pt = favoritesItem.getParent().toDisplay(pt);
            favoritesMenu.setLocation(pt.x, pt.y);
            favoritesMenu.setVisible(true);
          }
        });

        /** Aggregate all Favorites */
        aggregateFavorites = new MenuItem(favoritesMenu, SWT.PUSH);
        aggregateFavorites.setImage(PaintShop.loadImage("/img/icons/aggregate_all.gif", true));
        aggregateFavorites.addDisposeListener(DisposeListenerImpl.getInstance());
        aggregateFavorites.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionAggregateAllCategories();
          }
        });

        /** Reload all Favorites */
        reloadFavorites = new MenuItem(favoritesMenu, SWT.PUSH);
        reloadFavorites.setImage(PaintShop.loadImage("/img/icons/reload_all.gif", true));
        reloadFavorites.addDisposeListener(DisposeListenerImpl.getInstance());
        reloadFavorites.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionReloadAllCategories();
          }
        });

        /** Search all Favorites */
        searchFavorites = new MenuItem(favoritesMenu, SWT.PUSH);
        searchFavorites.setImage(PaintShop.loadImage("/img/icons/search_all.gif", true));
        searchFavorites.addDisposeListener(DisposeListenerImpl.getInstance());
        searchFavorites.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionSearchInAllCategories();
          }
        });

        /** Separator */
        new MenuItem(favoritesMenu, SWT.SEPARATOR);

        /** Mark All Read */
        markAllRead = new MenuItem(favoritesMenu, SWT.PUSH);
        markAllRead.setImage(PaintShop.loadImage("/img/icons/mark_read.gif", true));
        markAllRead.addDisposeListener(DisposeListenerImpl.getInstance());
        markAllRead.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionMarkAllCategoriesRead();
          }
        });
      }

      /** Drop Down: Search, Discover and validate Feeds, Preferences */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_TOOLS)) {
        toolsItem = new ToolItem(toolBar, SWT.DROP_DOWN);

        if (useIcons) {
          toolsItem.setImage(PaintShop.loadImage(toolImgPath + "tools.gif"));
          toolsItem.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        /** Favorites Menu */
        final Menu toolsMenu = new Menu(toolBar);

        /** Handle Drop Down Selection */
        toolsItem.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event event) {

            /** Make popupmenue visible */
            Rectangle rect = toolsItem.getBounds();
            Point pt = new Point(rect.x, rect.y + rect.height);
            pt = toolsItem.getParent().toDisplay(pt);
            toolsMenu.setLocation(pt.x, pt.y);
            toolsMenu.setVisible(true);
          }
        });

        /** Search Newsfeeds */
        searchFeedItem = new MenuItem(toolsMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          searchFeedItem.setImage(PaintShop.iconSearch);
        searchFeedItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionSearchFeeds();
          }
        });

        /** Discover Newsfeeds on Website */
        discoverFeedItem = new MenuItem(toolsMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          discoverFeedItem.setImage(PaintShop.iconFeedDiscovery);
        discoverFeedItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionDiscoverFeeds();
          }
        });

        /** Validate Newsfeed */
        validateFeedItem = new MenuItem(toolsMenu, SWT.PUSH);
        if (!GlobalSettings.isMac())
          validateFeedItem.setImage(PaintShop.iconValidate);
        validateFeedItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionValidateFeeds(false);
          }
        });

        /** Separator */
        new MenuItem(toolsMenu, SWT.SEPARATOR);

        /** Preferences */
        preferencesItem = new MenuItem(toolsMenu, SWT.PUSH);
        preferencesItem.setImage(PaintShop.loadImage("/img/icons/preferences.gif", true));
        preferencesItem.addDisposeListener(DisposeListenerImpl.getInstance());
        preferencesItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionOpenPreferences();
          }
        });
      }

      /** Mail NewsTip */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_NEWSTIP)) {
        mailNewsTip = new ToolItem(toolBar, SWT.PUSH);

        if (useIcons) {
          mailNewsTip.setImage(GlobalSettings.useSmallIcons ? PaintShop.iconMail : PaintShop.loadImage(toolImgPath + "mail.gif"));
          mailNewsTip.setDisabledImage(PaintShop.loadImage(toolImgPath + "mail_disabled.gif"));
          mailNewsTip.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
              if (mailNewsTip.getImage() != PaintShop.iconMail)
                mailNewsTip.getImage().dispose();

              mailNewsTip.getDisabledImage().dispose();
            }
          });
        }

        mailNewsTip.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionMailNewsTip();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerNewsTipToolItem(mailNewsTip);
      }

      /** Drop Down: History */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_HISTORY)) {
        historyItem = new ToolItem(toolBar, SWT.DROP_DOWN);

        if (useIcons) {
          historyItem.setImage(PaintShop.loadImage(toolImgPath + "history.gif"));
          historyItem.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        /** Handle Drop Down Selection */
        historyItem.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event event) {
            Rectangle rect = historyItem.getBounds();
            Point pt = new Point(rect.x, rect.y + rect.height);
            pt = historyItem.getParent().toDisplay(pt);

            /** Dispose Old */
            if (historyMenu != null)
              historyMenu.dispose();

            /** Create New */
            historyMenu = new Menu(historyItem.getParent());

            /** Fill in History */
            rssOwlGui.getRSSOwlNewsTabFolder().fillHistory(historyMenu);

            /** Show Menu */
            historyMenu.setLocation(pt.x, pt.y);
            historyMenu.setVisible(true);
          }
        });
      }

      /** Close Tab */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_CLOSE)) {
        closeItem = new ToolItem(toolBar, SWT.PUSH);

        if (useIcons) {
          closeItem.setImage(PaintShop.loadImage(toolImgPath + "close_tab.gif"));
          closeItem.setDisabledImage(PaintShop.loadImage(toolImgPath + "close_tab_disabled.gif"));
          closeItem.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        closeItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionCloseCurrent();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerCloseTabToolItem(closeItem);
      }

      /** Close Other Tabs */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_CLOSE_OTHERS)) {
        closeOtherItem = new ToolItem(toolBar, SWT.PUSH);

        if (useIcons) {
          closeOtherItem.setImage(PaintShop.loadImage(toolImgPath + "close_others.gif"));
          closeOtherItem.setDisabledImage(PaintShop.loadImage(toolImgPath + "close_others_disabled.gif"));
          closeOtherItem.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        closeOtherItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionCloseOthers();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerCloseOtherTabsToolItem(closeOtherItem);
      }

      /** Close All Tabs */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_CLOSE_ALL)) {
        closeAllItem = new ToolItem(toolBar, SWT.PUSH);

        if (useIcons) {
          closeAllItem.setImage(PaintShop.loadImage(toolImgPath + "close_all_tabs.gif"));
          closeAllItem.setDisabledImage(PaintShop.loadImage(toolImgPath + "close_all_tabs_disabled.gif"));
          closeAllItem.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        closeAllItem.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionCloseAll();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerCloseAllTabsToolItem(closeAllItem);
      }

      /** Previous Tab */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_PREVIOUS_TAB)) {
        previousTab = new ToolItem(toolBar, SWT.PUSH);

        if (useIcons) {
          previousTab.setImage(PaintShop.loadImage(toolImgPath + "backward_small.gif"));
          previousTab.setDisabledImage(PaintShop.loadImage(toolImgPath + "backward_small_disabled.gif"));
          previousTab.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        previousTab.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionGotoPreviousTab();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerGotoPreviousTabToolItem(previousTab);
      }

      /** Next Tab */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_NEXT_TAB)) {
        nextTab = new ToolItem(toolBar, SWT.PUSH);

        if (useIcons) {
          nextTab.setImage(PaintShop.loadImage(toolImgPath + "forward_small.gif"));
          nextTab.setDisabledImage(PaintShop.loadImage(toolImgPath + "forward_small_disabled.gif"));
          nextTab.addDisposeListener(DisposeListenerImpl.getInstance());
        }

        nextTab.addSelectionListener(new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            eventManager.actionGotoNextTab();
          }
        });

        /** Register to MenuManager */
        MenuManager.registerGotoNextTabToolItem(nextTab);
      }

      /** Separator */
      else if (itemValue.equals(ToolBarDialog.TOOLITEM_SEPARATOR)) {
        new ToolItem(toolBar, SWT.SEPARATOR);
      }
    }

    /** Pack the Left ToolBar */
    leftToolBar.pack();

    /** Pack the Center ToolBar */
    if (WidgetShop.isset(centerToolBar))
      centerToolBar.pack();

    /** Re-Set the Context Menu to all Controls */
    topContainer.setMenu(quickviewMenu);
    centerContainer.setMenu(quickviewMenu);
    bottomContainer.setMenu(quickviewMenu);
    urlLabelQuickView.setMenu(quickviewMenu);
    sep.setMenu(quickviewMenu);
    liveSearchLabel.setMenu(quickviewMenu);

    /** Update I18N to fill the ToolItems */
    updateI18N();

    /** Layout Bar Container */
    topContainer.layout();
    centerContainer.layout();

    /** Layout and Redraw the ViewForm */
    toolbarViewForm.layout();
    toolbarViewForm.redraw();
    toolbarViewForm.update();

    /** Finally Layout the Shell */
    shell.layout();
  }

  /**
   * Show / Hide the quickview control
   * 
   * @param show TRUE if visible
   * @param save If TRUE save state to GlobalSettings
   */
  public void setShowQuickview(boolean show, boolean save) {

    /** Update */
    rssOwlGui.getRSSOwlMenu().setQuickviewMenuEnabled(show);

    /** Set ViewForm Content */
    toolbarViewForm.setContent((show == true) ? bottomContainer : null, true);

    /** Update visibility */
    bottomContainer.setVisible(show);

    /** Completly hide the ViewForm since it contains no controls now */
    if (!show && !topContainer.getVisible())
      setShowViewForm(false);

    /** Restore the ViewForm since it is now containing a control */
    else if (show && !topContainer.getVisible())
      setShowViewForm(true);

    /** This might be called from a closing RSSOwl, so be carefull */
    if (WidgetShop.isset(shell) && GUI.isAlive())
      shell.layout();

    /** Update Global Settings */
    if (save) {
      GlobalSettings.isQuickviewShown = show;
      SettingsManager.getInstance().requestSave();
    }

    /** Update Context Menu */
    quickviewState.setSelection(show);
  }

  /**
   * Show / Hide the ToolBar control
   * 
   * @param show TRUE if visible
   * @param save If TRUE save state to GlobalSettings
   */
  public void setShowToolBar(boolean show, boolean save) {

    /** Update */
    rssOwlGui.getRSSOwlMenu().setToolBarMenuEnabled(show);

    /** Set ViewForm TopLeft */
    toolbarViewForm.setTopLeft((show == true) ? topContainer : null, true);

    /** Set ViewForm TopCenter */
    toolbarViewForm.setTopCenter((show == true) ? centerContainer : null, true);

    /** Update visibility */
    topContainer.setVisible(show);
    centerContainer.setVisible(show);

    /** Completly hide the ViewForm since it contains no controls now */
    if (!show && !bottomContainer.getVisible())
      setShowViewForm(false);

    /** Restore the ViewForm since it is now containing a control */
    else if (show && !bottomContainer.getVisible())
      setShowViewForm(true);

    /** This might be called from a closing RSSOwl, so be carefull */
    if (WidgetShop.isset(shell) && GUI.isAlive())
      shell.layout();

    /** Update Global Settings */
    if (save) {
      GlobalSettings.isToolBarShown = show;
      SettingsManager.getInstance().requestSave();
    }

    /** Update Context Menu */
    toolBarState.setSelection(show);
  }

  /**
   * Show / Hide the ViewForm containing ToolBar and Quickview
   * 
   * @param show TRUE if visible
   */
  public void setShowViewForm(boolean show) {

    /** Set Visibility */
    toolbarViewForm.setVisible(show);

    /** Set state of Exclude in GridData */
    ((GridData) toolbarViewForm.getLayoutData()).exclude = !show;
  }

  /**
   * @see net.sourceforge.rssowl.controller.IFontChangeable#updateFonts()
   */
  public void updateFonts() {
    urlLabelQuickView.setFont(FontShop.dialogFont);
    urlTestCombo.setFont(FontShop.dialogFont);
    liveSearch.setFont(FontShop.dialogFont);
  }

  /** Update all controlls text with i18n */
  public void updateI18N() {
    urlLabelQuickView.setText(GUI.i18n.getTranslation("LABEL_ADDRESS"));
    liveSearchLabel.setToolTipText(GUI.i18n.getTranslation("TOOLTIP_QUICKSEARCH"));
    toolBarState.setText(GUI.i18n.getTranslation("MENU_TOOLBAR"));
    quickviewState.setText(GUI.i18n.getTranslation("MENU_QUICKVIEW"));
    customizeBar.setText(GUI.i18n.getTranslation("POP_CUSTOMIZE_TOOLBAR") + "...");

    /** Quicksearch Wildcards */
    searchAndItem.setText(SearchPatternParser.getTranslation(SearchPatternParser.AND));
    searchOrItem.setText(SearchPatternParser.getTranslation(SearchPatternParser.OR));
    searchNotItem.setText(SearchPatternParser.getTranslation(SearchPatternParser.NOT));

    /** Init Mnemonics for Wildcard Menu */
    MenuManager.initMnemonics(wildCardMenu);

    /** Drop Down Menu: "New" */
    if (WidgetShop.isset(newFavorite) && HotkeyShop.isHotkeySet("MENU_NEW_FAVORITE") && !GlobalSettings.isMac())
      newFavorite.setText(GUI.i18n.getTranslation("LABEL_FAVORITE") + "..." + "\t" + HotkeyShop.getHotkeyName("MENU_NEW_FAVORITE"));
    else if (WidgetShop.isset(newFavorite))
      newFavorite.setText(GUI.i18n.getTranslation("LABEL_FAVORITE") + "...");

    if (WidgetShop.isset(newCategory))
      newCategory.setText(GUI.i18n.getTranslation("LABEL_CATEGORY") + "...");

    if (WidgetShop.isset(newSubCategory))
      newSubCategory.setText(GUI.i18n.getTranslation("POP_SUB_CATEGORY") + "...");

    /** Drop Down Menu: "Import" */
    if (WidgetShop.isset(importOPML))
      importOPML.setText(GUI.i18n.getTranslation("POP_FROM_OPML") + "...");

    if (WidgetShop.isset(importBlogroll))
      importBlogroll.setText(GUI.i18n.getTranslation("POP_IMPORT_BLOGROLL") + "...");

    /** Drop Down Menu: "Export" */
    if (WidgetShop.isset(exportOPML))
      exportOPML.setText(GUI.i18n.getTranslation("POP_EXPORT_OPML") + "...");

    /** Drop Down Menu: "Mark" */
    if (WidgetShop.isset(markFeedRead) && HotkeyShop.isHotkeySet("POP_MARK_ALL_READ") && !GlobalSettings.isMac())
      markFeedRead.setText(GUI.i18n.getTranslation("POP_MARK_ALL_READ") + "\t" + HotkeyShop.getHotkeyName("POP_MARK_ALL_READ"));
    else if (WidgetShop.isset(markFeedRead))
      markFeedRead.setText(GUI.i18n.getTranslation("POP_MARK_ALL_READ"));

    if (WidgetShop.isset(markNewsUnread) && HotkeyShop.isHotkeySet("POP_MARK_UNREAD") && !GlobalSettings.isMac())
      markNewsUnread.setText(GUI.i18n.getTranslation("POP_MARK_UNREAD") + "\t" + HotkeyShop.getHotkeyName("POP_MARK_UNREAD"));
    else if (WidgetShop.isset(markNewsUnread))
      markNewsUnread.setText(GUI.i18n.getTranslation("POP_MARK_UNREAD"));

    /** Drop Down Menu: "Next" */
    if (WidgetShop.isset(nextUnreadItem) && HotkeyShop.isHotkeySet("MENU_NEXT_UNREAD_NEWS") && !GlobalSettings.isMac())
      nextUnreadItem.setText(GUI.i18n.getTranslation("MENU_NEXT_UNREAD_NEWS") + "\t" + HotkeyShop.getHotkeyName("MENU_NEXT_UNREAD_NEWS"));
    else if (WidgetShop.isset(nextUnreadItem))
      nextUnreadItem.setText(GUI.i18n.getTranslation("MENU_NEXT_UNREAD_NEWS"));

    if (WidgetShop.isset(nextMessageItem) && HotkeyShop.isHotkeySet("MENU_NEXT_NEWS") && !GlobalSettings.isMac())
      nextMessageItem.setText(GUI.i18n.getTranslation("MENU_NEXT_NEWS") + "\t" + HotkeyShop.getHotkeyName("MENU_NEXT_NEWS"));
    else if (WidgetShop.isset(nextMessageItem))
      nextMessageItem.setText(GUI.i18n.getTranslation("MENU_NEXT_NEWS"));

    /** Drop Down Menu: "Favorites" */
    if (WidgetShop.isset(aggregateFavorites) && HotkeyShop.isHotkeySet("BUTTON_AGGREGATE_ALL") && !GlobalSettings.isMac())
      aggregateFavorites.setText(GUI.i18n.getTranslation("BUTTON_AGGREGATE_ALL") + "\t" + HotkeyShop.getHotkeyName("BUTTON_AGGREGATE_ALL"));
    else if (WidgetShop.isset(aggregateFavorites))
      aggregateFavorites.setText(GUI.i18n.getTranslation("BUTTON_AGGREGATE_ALL"));

    if (WidgetShop.isset(reloadFavorites) && HotkeyShop.isHotkeySet("BUTTON_RELOAD_ALL") && !GlobalSettings.isMac())
      reloadFavorites.setText(GUI.i18n.getTranslation("BUTTON_RELOAD_ALL") + "\t" + HotkeyShop.getHotkeyName("BUTTON_RELOAD_ALL"));
    else if (WidgetShop.isset(reloadFavorites))
      reloadFavorites.setText(GUI.i18n.getTranslation("BUTTON_RELOAD_ALL"));

    if (WidgetShop.isset(searchFavorites) && HotkeyShop.isHotkeySet("BUTTON_SEARCH_ALL") && !GlobalSettings.isMac())
      searchFavorites.setText(GUI.i18n.getTranslation("BUTTON_SEARCH_ALL") + "..." + "\t" + HotkeyShop.getHotkeyName("BUTTON_SEARCH_ALL"));
    else if (WidgetShop.isset(searchFavorites))
      searchFavorites.setText(GUI.i18n.getTranslation("BUTTON_SEARCH_ALL") + "...");

    if (WidgetShop.isset(markAllRead) && HotkeyShop.isHotkeySet("BUTTON_MARK_ALL_READ") && !GlobalSettings.isMac())
      markAllRead.setText(GUI.i18n.getTranslation("BUTTON_MARK_ALL_READ") + "\t" + HotkeyShop.getHotkeyName("BUTTON_MARK_ALL_READ"));
    else if (WidgetShop.isset(markAllRead))
      markAllRead.setText(GUI.i18n.getTranslation("BUTTON_MARK_ALL_READ"));

    /** Drop Down Menu: "Tools" */
    if (WidgetShop.isset(searchFeedItem) && HotkeyShop.isHotkeySet("MENU_FEEDSEARCH") && !GlobalSettings.isMac())
      searchFeedItem.setText(GUI.i18n.getTranslation("MENU_FEEDSEARCH") + "..." + "\t" + HotkeyShop.getHotkeyName("MENU_FEEDSEARCH"));
    else if (WidgetShop.isset(searchFeedItem))
      searchFeedItem.setText(GUI.i18n.getTranslation("MENU_FEEDSEARCH") + "...");

    if (WidgetShop.isset(discoverFeedItem) && HotkeyShop.isHotkeySet("MENU_FEED_DISCOVERY") && !GlobalSettings.isMac())
      discoverFeedItem.setText(GUI.i18n.getTranslation("MENU_FEED_DISCOVERY") + "..." + "\t" + HotkeyShop.getHotkeyName("MENU_FEED_DISCOVERY"));
    else if (WidgetShop.isset(discoverFeedItem))
      discoverFeedItem.setText(GUI.i18n.getTranslation("MENU_FEED_DISCOVERY") + "...");

    if (WidgetShop.isset(validateFeedItem) && HotkeyShop.isHotkeySet("MENU_VALIDATE") && !GlobalSettings.isMac())
      validateFeedItem.setText(GUI.i18n.getTranslation("MENU_VALIDATE") + "..." + "\t" + HotkeyShop.getHotkeyName("MENU_VALIDATE"));
    else if (WidgetShop.isset(validateFeedItem))
      validateFeedItem.setText(GUI.i18n.getTranslation("MENU_VALIDATE") + "...");

    if (WidgetShop.isset(preferencesItem) && HotkeyShop.isHotkeySet("MENU_PREFERENCES") && !GlobalSettings.isMac())
      preferencesItem.setText(GUI.i18n.getTranslation("MENU_PREFERENCES") + "..." + "\t" + HotkeyShop.getHotkeyName("MENU_PREFERENCES"));
    else if (WidgetShop.isset(preferencesItem))
      preferencesItem.setText(GUI.i18n.getTranslation("MENU_PREFERENCES") + "...");

    /** Show Text for ToolItems - Remove some ToolTips */
    if (GlobalSettings.toolBarMode != TOOLBAR_MODE_ICONS) {
      if (WidgetShop.isset(newItem)) {
        newItem.setText(GUI.i18n.getTranslation("POP_NEW"));
        newItem.setToolTipText(null);
      }

      if (WidgetShop.isset(importItem)) {
        importItem.setText(GUI.i18n.getTranslation("POP_IMPORT"));
        importItem.setToolTipText(null);
      }

      if (WidgetShop.isset(exportItem)) {
        exportItem.setText(GUI.i18n.getTranslation("BUTTON_EXPORT"));
        exportItem.setToolTipText(null);
      }

      if (WidgetShop.isset(reloadItem)) {
        reloadItem.setText(GUI.i18n.getTranslation("MENU_RELOAD"));
        reloadItem.setToolTipText(null);
      }

      if (WidgetShop.isset(searchItem)) {
        searchItem.setText(GUI.i18n.getTranslation("BUTTON_SEARCH"));
        searchItem.setToolTipText(null);
      }

      if (WidgetShop.isset(markReadItem)) {
        markReadItem.setText(GUI.i18n.getTranslation("TOOL_MARK"));
        markReadItem.setToolTipText(GUI.i18n.getTranslation("POP_MARK_ALL_READ"));
      }

      if (WidgetShop.isset(favoritesItem)) {
        favoritesItem.setText(GUI.i18n.getTranslation("HEADER_RSS_FAVORITES"));
        favoritesItem.setToolTipText(null);
      }

      if (WidgetShop.isset(nextNewsItem)) {
        nextNewsItem.setText(GUI.i18n.getTranslation("TOOL_NEXT"));
        nextNewsItem.setToolTipText(GUI.i18n.getTranslation("MENU_NEXT_UNREAD_NEWS"));
      }

      if (WidgetShop.isset(historyItem)) {
        historyItem.setText(GUI.i18n.getTranslation("TOOL_HISTORY"));
        historyItem.setToolTipText(null);
      }

      if (WidgetShop.isset(toolsItem)) {
        toolsItem.setText(GUI.i18n.getTranslation("MENU_TOOLS"));
        toolsItem.setToolTipText(null);
      }

      if (WidgetShop.isset(mailNewsTip)) {
        mailNewsTip.setText(GUI.i18n.getTranslation("TOOL_NEWSTIP"));
        mailNewsTip.setToolTipText(GUI.i18n.getTranslation("POP_MAIL_LINK"));
      }

      if (WidgetShop.isset(previousTab)) {
        previousTab.setText(GUI.i18n.getTranslation("MENU_PREVIOUS_TAB"));
        previousTab.setToolTipText(null);
      }

      if (WidgetShop.isset(nextTab)) {
        nextTab.setText(GUI.i18n.getTranslation("MENU_NEXT_TAB"));
        nextTab.setToolTipText(null);
      }

      if (WidgetShop.isset(closeItem)) {
        closeItem.setText(GUI.i18n.getTranslation("MENU_CLOSE"));
        closeItem.setToolTipText(null);
      }

      if (WidgetShop.isset(closeOtherItem)) {
        closeOtherItem.setText(GUI.i18n.getTranslation("POP_KEEP_CURRENT"));
        closeOtherItem.setToolTipText(null);
      }

      if (WidgetShop.isset(closeAllItem)) {
        closeAllItem.setText(GUI.i18n.getTranslation("MENU_CLOSE_ALL"));
        closeAllItem.setToolTipText(null);
      }
    }

    /** Show only ToolTips for ToolItems */
    else {
      if (WidgetShop.isset(newItem))
        newItem.setToolTipText(GUI.i18n.getTranslation("POP_NEW"));

      if (WidgetShop.isset(importItem))
        importItem.setToolTipText(GUI.i18n.getTranslation("POP_IMPORT"));

      if (WidgetShop.isset(exportItem))
        exportItem.setToolTipText(GUI.i18n.getTranslation("BUTTON_EXPORT"));

      if (WidgetShop.isset(reloadItem))
        reloadItem.setToolTipText(GUI.i18n.getTranslation("MENU_RELOAD"));

      if (WidgetShop.isset(searchItem))
        searchItem.setToolTipText(GUI.i18n.getTranslation("BUTTON_SEARCH"));

      if (WidgetShop.isset(markReadItem))
        markReadItem.setToolTipText(GUI.i18n.getTranslation("POP_MARK_ALL_READ"));

      if (WidgetShop.isset(favoritesItem))
        favoritesItem.setToolTipText(GUI.i18n.getTranslation("HEADER_RSS_FAVORITES"));

      if (WidgetShop.isset(nextNewsItem))
        nextNewsItem.setToolTipText(GUI.i18n.getTranslation("MENU_NEXT_UNREAD_NEWS"));

      if (WidgetShop.isset(historyItem))
        historyItem.setToolTipText(GUI.i18n.getTranslation("TOOL_HISTORY"));

      if (WidgetShop.isset(toolsItem))
        toolsItem.setToolTipText(GUI.i18n.getTranslation("MENU_TOOLS"));

      if (WidgetShop.isset(mailNewsTip))
        mailNewsTip.setToolTipText(GUI.i18n.getTranslation("POP_MAIL_LINK"));

      if (WidgetShop.isset(previousTab))
        previousTab.setToolTipText(GUI.i18n.getTranslation("MENU_PREVIOUS_TAB"));

      if (WidgetShop.isset(nextTab))
        nextTab.setToolTipText(GUI.i18n.getTranslation("MENU_NEXT_TAB"));

      if (WidgetShop.isset(closeItem))
        closeItem.setToolTipText(GUI.i18n.getTranslation("MENU_CLOSE"));

      if (WidgetShop.isset(closeOtherItem))
        closeOtherItem.setToolTipText(GUI.i18n.getTranslation("POP_KEEP_CURRENT"));

      if (WidgetShop.isset(closeAllItem))
        closeAllItem.setToolTipText(GUI.i18n.getTranslation("MENU_CLOSE_ALL"));
    }
  }

  /**
   * Apply a wildcard popup menu to the text. These allow to specify the Search.
   */
  private void createWildCardMenu() {

    /** Create Menu */
    wildCardMenu = new Menu(liveSearch);

    /** AND Item */
    searchAndItem = new MenuItem(wildCardMenu, SWT.POP_UP);
    if (!GlobalSettings.isMac())
      searchAndItem.setImage(PaintShop.iconBackward);
    searchAndItem.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        stopLiveSearch = true;
        liveSearch.insert(SearchPatternParser.getTranslation(SearchPatternParser.AND));
        stopLiveSearch = false;
      }
    });

    /** OR Item */
    searchOrItem = new MenuItem(wildCardMenu, SWT.POP_UP);
    if (!GlobalSettings.isMac())
      searchOrItem.setImage(PaintShop.iconBackward);
    searchOrItem.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        stopLiveSearch = true;
        liveSearch.insert(SearchPatternParser.getTranslation(SearchPatternParser.OR));
        stopLiveSearch = false;
      }
    });

    /** NOT Item */
    searchNotItem = new MenuItem(wildCardMenu, SWT.POP_UP);
    if (!GlobalSettings.isMac())
      searchNotItem.setImage(PaintShop.iconBackward);
    searchNotItem.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        stopLiveSearch = true;
        liveSearch.insert(SearchPatternParser.getTranslation(SearchPatternParser.NOT));
        stopLiveSearch = false;
      }
    });

    /** Apply */
    liveSearch.setMenu(wildCardMenu);
  }

  /**
   * Get the index from the combo where the given URL is located or -1 if the
   * URL is not part of the combo
   * 
   * @param url Any URL to search for
   * @return int The index or -1
   */
  private int getIndex(String url) {
    int itemCount = urlTestCombo.getItemCount();
    for (int a = 0; a < itemCount; a++) {
      if (urlTestCombo.getItem(a).equals(url))
        return a;
    }
    return -1;
  }

  /**
   * Calculate the Pivot to be used as divider between the two ToolBars.
   * 
   * @param items The ToolItems as I18N Keys.
   * @return int The smart Pivot Element as divider between the two ToolBars.
   */
  private int getPivot(String items[]) {

    /** Ignore in case Lenght is below or equal 1 */
    if (items.length <= 1)
      return items.length;

    /** Math Pivot is length / 2 rounded up */
    int mathPivot = (items.length % 2 == 0) ? items.length / 2 : items.length / 2 + 1;

    /** Real Pivot recognizes Seperatarors */
    float realPivot = mathPivot;

    /** For each Separator to the left, move Pivot to right by 0.5 */
    for (int i = 0; i < mathPivot; i++)
      if (ToolBarDialog.TOOLITEM_SEPARATOR.equals(items[i]))
        realPivot += 0.5f;

    /** For each Separator to the right, move Pivot to left by 0.5 */
    for (int i = mathPivot; i < items.length; i++)
      if (ToolBarDialog.TOOLITEM_SEPARATOR.equals(items[i]))
        realPivot -= 0.5f;

    return (int) realPivot;
  }

  /** Init all components */
  private void initComponents() {

    /** ViewForm for the ToolBar controls */
    toolbarViewForm = new ViewForm(shell, SWT.BORDER | SWT.FLAT);
    toolbarViewForm.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
    toolbarViewForm.setBackground(PaintShop.grayViewFormColor);
    toolbarViewForm.setToolBarMode(true);

    if (GlobalSettings.isMac())
      toolbarViewForm.setOnlyBorderBottom(true);
    else
      toolbarViewForm.setOnlyBorderTopBottom(true);

    /** Initialize the Context Menu */
    initContextMenu(toolbarViewForm);

    /** Top Container */
    topContainer = new Composite(toolbarViewForm, SWT.NONE);
    topContainer.setBackground(PaintShop.grayViewFormColor);
    topContainer.setLayout(LayoutShop.createGridLayout(1, 0, 0));
    topContainer.setMenu(quickviewMenu);

    /** Apply to ViewForm */
    toolbarViewForm.setTopLeft(topContainer, false);

    /** Center Container */
    centerContainer = new Composite(toolbarViewForm, SWT.NONE);
    centerContainer.setBackground(PaintShop.grayViewFormColor);
    centerContainer.setLayout(LayoutShop.createGridLayout(1, 1, 0));
    centerContainer.setMenu(quickviewMenu);

    /** Apply to ViewForm */
    toolbarViewForm.setTopCenter(centerContainer, false);

    /** Bottom Container GridLayout */
    GridLayout bottomContainerLayout = new GridLayout(5, true);
    bottomContainerLayout.marginWidth = 5;
    bottomContainerLayout.marginHeight = 3;
    bottomContainerLayout.marginTop = 1;

    /** Bottom Container */
    bottomContainer = new Composite(toolbarViewForm, SWT.NONE);
    bottomContainer.setLayout(bottomContainerLayout);
    bottomContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
    bottomContainer.setBackground(PaintShop.grayViewFormColor);
    bottomContainer.setMenu(quickviewMenu);

    /** Apply to ViewForm */
    toolbarViewForm.setContent(bottomContainer, true);

    /** QuickView Container */
    Composite quickviewContainer = new Composite(bottomContainer, SWT.NONE);
    quickviewContainer.setLayout(LayoutShop.createGridLayout(3, 0, 0));
    quickviewContainer.setBackground(PaintShop.grayViewFormColor);
    quickviewContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1));

    /** Label */
    urlLabelQuickView = new Label(quickviewContainer, SWT.LEFT);
    urlLabelQuickView.setBackground(PaintShop.grayViewFormColor);
    urlLabelQuickView.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
    urlLabelQuickView.setText(GUI.i18n.getTranslation("LABEL_ADDRESS"));
    urlLabelQuickView.setFont(FontShop.dialogFont);
    urlLabelQuickView.setMenu(quickviewMenu);

    /** Combo containing the newsfeed's url */
    urlTestCombo = new Combo(quickviewContainer, SWT.DROP_DOWN);
    urlTestCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    urlTestCombo.setFont(FontShop.dialogFont);

    /** Bug on Mac: Combo size not grabbed correctly */
    if (GlobalSettings.isMac()) {
      Point size = urlTestCombo.computeSize(SWT.DEFAULT, SWT.DEFAULT);
      ((GridData) urlTestCombo.getLayoutData()).heightHint = (size.y > 0) ? size.y + 3 : SWT.DEFAULT;
    }

    /** Allow to Drop Text into Combo */
    comboDNDTarget = new DropTarget(urlTestCombo, DND.DROP_MOVE);
    comboDNDTarget.setTransfer(new Transfer[] { TextTransfer.getInstance() });
    comboDNDTarget.addDropListener(new DropTargetAdapter() {
      public void drop(DropTargetEvent event) {

        /** Some Text is given */
        if (event.data != null && StringShop.isset(event.data.toString())) {

          /** First try to Extract Links */
          Vector links = new Vector();
          RegExShop.extractLinksFromText(event.data.toString(), links);
          if (links.size() > 0)
            urlTestCombo.setText(links.get(0).toString());

          /** No links given, just display the Text */
          else {
            String data = event.data.toString();

            /** This is a dragged TreeItem Category */
            if (data.indexOf(StringShop.CAT_TOKENIZER) >= 0) {
              String dataArray[] = data.split(StringShop.CAT_TOKENIZER);
              urlTestCombo.setText(dataArray[dataArray.length - 1]);
            }

            /** This is any other dragged Object containing Text */
            else {
              urlTestCombo.setText(org.jdom.Text.normalizeString(data));
            }
          }

          /** Transfer Focus into Combo */
          urlTestCombo.setFocus();
        }

        /** No valid Data given */
        else {
          event.feedback = DND.DROP_NONE;
        }
      }
    });

    /** Dispose DND Target on Combo Disposal */
    urlTestCombo.addDisposeListener(new DisposeListener() {
      public void widgetDisposed(DisposeEvent e) {
        comboDNDTarget.dispose();
      }
    });

    /** Open the selected URL from the combo */
    urlTestCombo.addSelectionListener(new SelectionAdapter() {

      /** Open the news feed that is entered in the Combo */
      public void widgetSelected(SelectionEvent e) {
        if (!StringShop.isWhiteSpaceOrEmpty(urlTestCombo.getText()))
          eventManager.actionOpenFeed(urlTestCombo.getText().trim());
      }
    });

    /** Open the URL when the user presses enter */
    urlTestCombo.addKeyListener(new KeyAdapter() {

      /** Open the news feed that is entered in the Combo */
      public void keyPressed(KeyEvent e) {
        if (e.character == SWT.CR && !StringShop.isWhiteSpaceOrEmpty(urlTestCombo.getText())) {
          String text = urlTestCombo.getText();
          addUrlToCombo(text.trim());
          eventManager.actionOpenFeed(text.trim());
          urlTestCombo.setSelection(new Point(0, text.length()));
        }
      }
    });

    /** Handle accelerators on focus gained / lost */
    urlTestCombo.addFocusListener(new FocusListener() {

      /** Disable printable accelerators while focus is in combo */
      public void focusGained(FocusEvent e) {
        rssOwlGui.getRSSOwlMenu().updateAccelerators(true);
        MenuManager.handleEditMenuState();
      }

      /** Enable printable accelerators when focus is lost */
      public void focusLost(FocusEvent e) {
        rssOwlGui.getRSSOwlMenu().updateAccelerators();
      }
    });

    /** Live Search Container */
    Composite liveSearchContainer = new Composite(bottomContainer, SWT.NONE);
    liveSearchContainer.setLayout(LayoutShop.createGridLayout(3, 0, 0));
    liveSearchContainer.setBackground(PaintShop.grayViewFormColor);
    liveSearchContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

    /** Separator */
    sep = new Label(liveSearchContainer, SWT.SEPARATOR | SWT.VERTICAL);
    sep.setBackground(PaintShop.grayViewFormColor);
    GridData sepGridDataA = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
    sepGridDataA.heightHint = urlTestCombo.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
    sep.setLayoutData(sepGridDataA);
    sep.setMenu(quickviewMenu);

    /** Image Label */
    liveSearchLabel = new CLabel(liveSearchContainer, SWT.NONE);
    liveSearchLabel.setImage(PaintShop.iconFind);
    liveSearchLabel.setToolTipText(GUI.i18n.getTranslation("TOOLTIP_QUICKSEARCH"));
    liveSearchLabel.setBackground(PaintShop.grayViewFormColor);
    liveSearchLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
    liveSearchLabel.setMenu(quickviewMenu);

    /** Live Search Input Field */
    liveSearch = new Text(liveSearchContainer, SWT.BORDER);
    liveSearch.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    liveSearch.setFont(FontShop.dialogFont);

    /** Perform Search upon Modify */
    liveSearch.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        search();
      }
    });

    /** Search on Enter Key pressed */
    liveSearch.addKeyListener(new KeyAdapter() {
      public void keyPressed(KeyEvent e) {

        /** Run Search */
        if (e.character == SWT.CR) {
          liveSearch.selectAll();
          rssOwlGui.getRSSOwlNewsTabFolder().searchInSelectedFeed(new SearchDefinition(liveSearch.getText(), SearchDefinition.SCOPE_NEWS), false);
        } else if (e.character == SWT.ESC && StringShop.isset(liveSearch.getText())) {
          stopLiveSearch = true;
          liveSearch.setText("");
          rssOwlGui.getRSSOwlNewsTabFolder().searchInSelectedFeed(SearchDefinition.NO_SEARCH, false);
          stopLiveSearch = false;
        }
      }
    });

    /** Handle accelerators on focus gained / lost */
    liveSearch.addFocusListener(new FocusListener() {

      /** Disable printable accelerators while focus is in combo */
      public void focusGained(FocusEvent e) {
        rssOwlGui.getRSSOwlMenu().updateAccelerators(true);
      }

      /** Enable printable accelerators when focus is lost */
      public void focusLost(FocusEvent e) {
        rssOwlGui.getRSSOwlMenu().updateAccelerators();
      }
    });

    /** Apply Wildcard Menu */
    createWildCardMenu();

    /** Register to MenuManager */
    MenuManager.regiserLiveSearch(liveSearch);

    /** Setup Drop Support */
    WidgetShop.setupDropSupport(liveSearch, null);

    /** Tweak */
    WidgetShop.tweakTextWidget(liveSearch);

    /** Set Text */
    updateI18N();
  }

  /**
   * Initialize the Context Menu showing two items to hide/show ToolBar and
   * Quickview control.
   * 
   * @param parent The parent to use for Initialization.
   */
  private void initContextMenu(Control parent) {

    /** Context Menu */
    quickviewMenu = new Menu(parent);

    /** Set ToolBar Visbility */
    toolBarState = new MenuItem(quickviewMenu, SWT.CHECK);
    toolBarState.setSelection(GlobalSettings.isToolBarShown);
    toolBarState.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        eventManager.actionShowToolBar(toolBarState.getSelection());
      }
    });

    /** Set Quickview Visibility */
    quickviewState = new MenuItem(quickviewMenu, SWT.CHECK);
    quickviewState.setSelection(GlobalSettings.isQuickviewShown);
    quickviewState.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        eventManager.actionShowQuickview(quickviewState.getSelection());
      }
    });

    /** Separator */
    new MenuItem(quickviewMenu, SWT.SEPARATOR);

    /** Customize ToolBar */
    customizeBar = new MenuItem(quickviewMenu, SWT.NONE);
    customizeBar.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        eventManager.actionCustomizeToolBar();
      }
    });
  }

  /**
   * Add the URL to the combo if its not yet in
   * 
   * @param url Any URL
   */
  void addUrlToCombo(String url) {

    /** Only add URL to Combo if not yet existing */
    if (getIndex(url) != -1)
      return;

    /** Add if URL does not exist already */
    urlTestCombo.add(url);
  }

  /**
   * Perform the search in the displayed channel. Delay the search using a
   * Thread that first sleeps for a short amount of time. This allows the user
   * to complete the typing of a word before the search is beginning.
   */
  void search() {

    /** Check Flag */
    if (!stopLiveSearch) {

      /** Stop any running Search Delay Thread */
      if (searchDelayThread != null) {
        searchDelayThread.stopThread();
        searchDelayThread.interrupt();
      }

      /** Create a new Search Delay Thread */
      searchDelayThread = new ExtendedThread() {
        public void run() {

          /** Delay the Search */
          try {
            sleep(SEARCH_DELAY);
          }

          /** Search Term changed meanwhile, return */
          catch (InterruptedException e) {
            return;
          }

          /** Load Feed with Search pattern */
          if (!isStopped() && GUI.isAlive()) {
            GUI.display.syncExec(new Runnable() {
              public void run() {

                /** Create SearchDefinition */
                SearchDefinition quickSearch = new SearchDefinition(liveSearch.getText(), SearchDefinition.SCOPE_NEWS);

                /** Perform the Search */
                rssOwlGui.getRSSOwlNewsTabFolder().searchInSelectedFeed(quickSearch, false);
              }
            });
          }
        }
      };

      /** Start the Search Delay Thread */
      searchDelayThread.setName("Search Delay Thread");
      searchDelayThread.startThread();
    }
  }
}