Package org.rssowl.ui.internal.dialogs.properties

Source Code of org.rssowl.ui.internal.dialogs.properties.GeneralPropertyPage

/*   **********************************************************************  **
**   Copyright notice                                                       **
**                                                                          **
**   (c) 2005-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 v1.0 which accompanies this    **
**   distribution, and is available at:                                     **
**   http://www.rssowl.org/legal/epl-v10.html                               **
**                                                                          **
**   A copy is found in the file epl-v10.html and important notices to the  **
**   license from the team is found in the textfile LICENSE.txt distributed **
**   in this package.                                                       **
**                                                                          **
**   This copyright notice MUST APPEAR in all copies of the file!           **
**                                                                          **
**   Contributors:                                                          **
**     RSSOwl Development Team - initial API and implementation             **
**                                                                          **
**  **********************************************************************  */

package org.rssowl.ui.internal.dialogs.properties;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.rssowl.core.Owl;
import org.rssowl.core.connection.ConnectionException;
import org.rssowl.core.internal.persist.pref.DefaultPreferences;
import org.rssowl.core.persist.IBookMark;
import org.rssowl.core.persist.IEntity;
import org.rssowl.core.persist.IFeed;
import org.rssowl.core.persist.IFolder;
import org.rssowl.core.persist.IFolderChild;
import org.rssowl.core.persist.IMark;
import org.rssowl.core.persist.dao.DAOService;
import org.rssowl.core.persist.dao.DynamicDAO;
import org.rssowl.core.persist.pref.IPreferenceScope;
import org.rssowl.core.persist.reference.FeedLinkReference;
import org.rssowl.core.persist.reference.FeedReference;
import org.rssowl.core.util.ReparentInfo;
import org.rssowl.core.util.StringUtils;
import org.rssowl.core.util.URIUtils;
import org.rssowl.ui.dialogs.properties.IEntityPropertyPage;
import org.rssowl.ui.dialogs.properties.IPropertyDialogSite;
import org.rssowl.ui.internal.Controller;
import org.rssowl.ui.internal.FolderChooser;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.util.JobRunner;
import org.rssowl.ui.internal.util.LayoutUtils;
import org.rssowl.ui.internal.util.UIBackgroundJob;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
* General Properties.
*
* @author bpasero
*/
public class GeneralPropertyPage implements IEntityPropertyPage {

  /* Interval-Scopes in Seconds */
  private static final long DAY_IN_SECONDS = 24 * 60 * 60;
  private static final long HOUR_IN_SECONDS = 60 * 60;
  private static final long MINUTE_IN_SECONDS = 60;

  /* Interval-Indeces in Combo */
  private static final int MINUTES_SCOPE = 0;
  private static final int HOURS_SCOPE = 1;
  private static final int DAYS_SCOPE = 2;

  private IPropertyDialogSite fSite;
  private List<IEntity> fEntities;
  private Text fNameInput;
  private Text fFeedInput;
  private FolderChooser fFolderChooser;
  private Button fOpenOnStartupCheck;
  private boolean fReloadRequired;
  private boolean fSettingsChanged;
  private boolean fIsSingleBookMark;

  /* Settings */
  private List<IPreferenceScope> fEntityPreferences;
  private boolean fPrefUpdateIntervalState;
  private long fPrefUpdateInterval;
  private boolean fPrefOpenOnStartup;
  private Spinner fReloadSpinner;
  private int fUpdateIntervalScope;
  private Button fUpdateCheck;
  private Combo fReloadCombo;

  /*
   * @see org.rssowl.ui.dialogs.properties.IEntityPropertyPage#init(org.rssowl.ui.dialogs.properties.IPropertyDialogSite,
   * java.util.List)
   */
  public void init(IPropertyDialogSite site, List<IEntity> entities) {
    Assert.isTrue(!entities.isEmpty());
    fSite = site;
    fEntities = entities;

    /* Load Entity Preferences */
    fEntityPreferences = new ArrayList<IPreferenceScope>(fEntities.size());
    for (IEntity entity : entities)
      fEntityPreferences.add(Owl.getPreferenceService().getEntityScope(entity));

    /* Load initial Settings */
    loadInitialSettings();

    /* Pre-Cache the Feed if Entity is a single BookMark */
    if (fEntities.size() == 1 && fEntities.get(0) instanceof IBookMark)
      fIsSingleBookMark = true;
  }

  private void loadInitialSettings() {

    /* Take the first scope as initial values */
    IPreferenceScope firstScope = fEntityPreferences.get(0);
    fPrefUpdateIntervalState = firstScope.getBoolean(DefaultPreferences.BM_UPDATE_INTERVAL_STATE);
    fPrefUpdateInterval = firstScope.getLong(DefaultPreferences.BM_UPDATE_INTERVAL);
    fPrefOpenOnStartup = firstScope.getBoolean(DefaultPreferences.BM_OPEN_ON_STARTUP);

    /* For any other scope not sharing the initial values, use the default */
    IPreferenceScope defaultScope = Owl.getPreferenceService().getDefaultScope();
    for (int i = 1; i < fEntityPreferences.size(); i++) {
      IPreferenceScope otherScope = fEntityPreferences.get(i);

      if (otherScope.getBoolean(DefaultPreferences.BM_UPDATE_INTERVAL_STATE) != fPrefUpdateIntervalState)
        fPrefUpdateIntervalState = defaultScope.getBoolean(DefaultPreferences.BM_UPDATE_INTERVAL_STATE);

      if (otherScope.getLong(DefaultPreferences.BM_UPDATE_INTERVAL) != fPrefUpdateInterval)
        fPrefUpdateInterval = defaultScope.getLong(DefaultPreferences.BM_UPDATE_INTERVAL);

      if (otherScope.getBoolean(DefaultPreferences.BM_OPEN_ON_STARTUP) != fPrefOpenOnStartup)
        fPrefOpenOnStartup = defaultScope.getBoolean(DefaultPreferences.BM_OPEN_ON_STARTUP);
    }

    fUpdateIntervalScope = getUpdateIntervalScope();
  }

  /*
   * @see org.rssowl.ui.internal.dialogs.properties.IEntityPropertyPage#createContents(org.eclipse.swt.widgets.Composite)
   */
  public Control createContents(Composite parent) {
    boolean separateFromTop = false;
    Composite container = new Composite(parent, SWT.NONE);
    container.setLayout(LayoutUtils.createGridLayout(2, 10, 10));

    /* Fields for single Selection */
    if (fEntities.size() == 1) {
      IEntity entity = fEntities.get(0);
      separateFromTop = true;

      /* Link */
      if (entity instanceof IBookMark) {
        Label feedLabel = new Label(container, SWT.None);
        feedLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
        feedLabel.setText("Link: ");

        fFeedInput = new Text(container, SWT.BORDER);
        fFeedInput.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
        fFeedInput.setText(((IBookMark) entity).getFeedLinkReference().getLink().toString());
        ((GridData) fFeedInput.getLayoutData()).widthHint = fSite.getHorizontalPixels(IDialogConstants.ENTRY_FIELD_WIDTH);

        /* Name */
        Label nameLabel = new Label(container, SWT.None);
        nameLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
        nameLabel.setText("Name: ");

        Composite nameContainer = new Composite(container, SWT.BORDER);
        nameContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
        nameContainer.setLayout(LayoutUtils.createGridLayout(2, 0, 0));
        nameContainer.setBackground(container.getDisplay().getSystemColor(SWT.COLOR_WHITE));

        fNameInput = new Text(nameContainer, SWT.NONE);
        fNameInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
        fNameInput.setText(getName(entity));

        ToolBar grabTitleBar = new ToolBar(nameContainer, SWT.FLAT);
        grabTitleBar.setBackground(container.getDisplay().getSystemColor(SWT.COLOR_WHITE));

        ToolItem grabTitleItem = new ToolItem(grabTitleBar, SWT.PUSH);
        grabTitleItem.setImage(OwlUI.getImage(fSite.getResourceManager(), "icons/etool16/info.gif"));
        grabTitleItem.setToolTipText("Load name from feed");
        grabTitleItem.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            onGrabTitle();
          }
        });
      }

      /* Other */
      else {

        /* Name */
        Label nameLabel = new Label(container, SWT.None);
        nameLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
        nameLabel.setText("Name: ");

        fNameInput = new Text(container, SWT.BORDER);
        fNameInput.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
        fNameInput.setText(getName(entity));
      }
    }

    /* Location */
    IFolder sameParent = getSameParent(fEntities);
    if (sameParent != null) {
      separateFromTop = true;

      Label locationLabel = new Label(container, SWT.None);
      locationLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
      locationLabel.setText("Location: ");

      /* Exclude Folders that are selected from Chooser */
      List<IFolder> excludes = new ArrayList<IFolder>();
      for (IEntity entity : fEntities) {
        if (entity instanceof IFolder)
          excludes.add((IFolder) entity);
      }

      fFolderChooser = new FolderChooser(container, sameParent, excludes, SWT.BORDER);
      fFolderChooser.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
      fFolderChooser.setLayout(LayoutUtils.createGridLayout(1, 0, 0, 2, 5, false));
      fFolderChooser.setBackground(container.getDisplay().getSystemColor(SWT.COLOR_WHITE));
    }

    /* Other Settings */
    Composite otherSettingsContainer = new Composite(container, SWT.NONE);
    otherSettingsContainer.setLayout(LayoutUtils.createGridLayout(1, 0, 0));
    otherSettingsContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, true, 2, 1));

    if (separateFromTop)
      ((GridLayout) otherSettingsContainer.getLayout()).marginTop = 15;

    /* Auto-Reload */
    Composite autoReloadContainer = new Composite(otherSettingsContainer, SWT.NONE);
    autoReloadContainer.setLayout(LayoutUtils.createGridLayout(3, 0, 0));
    autoReloadContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, true));

    fUpdateCheck = new Button(autoReloadContainer, SWT.CHECK);
    fUpdateCheck.setText("Automatically update the " + (fIsSingleBookMark ? "feed" : "feeds") + " every ");
    fUpdateCheck.setSelection(fPrefUpdateIntervalState);
    fUpdateCheck.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        fReloadSpinner.setEnabled(fUpdateCheck.getSelection());
        fReloadCombo.setEnabled(fUpdateCheck.getSelection());
      }
    });

    fReloadSpinner = new Spinner(autoReloadContainer, SWT.BORDER);
    fReloadSpinner.setMinimum(1);
    fReloadSpinner.setMaximum(999);
    fReloadSpinner.setEnabled(fPrefUpdateIntervalState);

    if (fUpdateIntervalScope == MINUTES_SCOPE)
      fReloadSpinner.setSelection((int) (fPrefUpdateInterval / MINUTE_IN_SECONDS));
    else if (fUpdateIntervalScope == HOURS_SCOPE)
      fReloadSpinner.setSelection((int) (fPrefUpdateInterval / HOUR_IN_SECONDS));
    else if (fUpdateIntervalScope == DAYS_SCOPE)
      fReloadSpinner.setSelection((int) (fPrefUpdateInterval / DAY_IN_SECONDS));

    fReloadCombo = new Combo(autoReloadContainer, SWT.READ_ONLY);
    fReloadCombo.add("Minutes");
    fReloadCombo.add("Hours");
    fReloadCombo.add("Days");
    fReloadCombo.select(fUpdateIntervalScope);
    fReloadCombo.setEnabled(fPrefUpdateIntervalState);

    /* Open on Startup */
    fOpenOnStartupCheck = new Button(otherSettingsContainer, SWT.CHECK);
    fOpenOnStartupCheck.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
    fOpenOnStartupCheck.setText("Display the " + (fIsSingleBookMark ? "feed" : "feeds") + " on start-up");
    fOpenOnStartupCheck.setSelection(fPrefOpenOnStartup);

    return container;
  }

  private void onGrabTitle() {
    if (StringUtils.isSet(fFeedInput.getText())) {
      fFeedInput.getShell().setCursor(fFeedInput.getDisplay().getSystemCursor(SWT.CURSOR_APPSTARTING));
      final String linkText = fFeedInput.getText();
      JobRunner.runUIUpdater(new UIBackgroundJob(fFeedInput.getShell()) {
        private String fLabel;

        @Override
        protected void runInBackground(IProgressMonitor monitor) {
          try {
            URI link = new URI(linkText);
            fLabel = Owl.getConnectionService().getLabel(link);
          } catch (ConnectionException e) {
            /* Ignore */
          } catch (URISyntaxException e) {
            /* Ignore */
          }
        }

        @Override
        protected void runInUI(IProgressMonitor monitor) {
          if (StringUtils.isSet(fLabel))
            fNameInput.setText(fLabel);
          fFeedInput.getShell().setCursor(null);
        }
      });
    }
  }

  /*
   * @see org.rssowl.ui.dialogs.properties.IEntityPropertyPage#setFocus()
   */
  public void setFocus() {
    if (fFeedInput != null) {
      fFeedInput.setFocus();
      fFeedInput.selectAll();
    } else if (fNameInput != null) {
      fNameInput.setFocus();
      fNameInput.selectAll();
    }
  }

  private IFolder getSameParent(List<IEntity> entities) {
    IFolder parent = null;

    for (IEntity entity : entities) {
      if (!(entity instanceof IFolderChild))
        return null;

      IFolderChild folderChild = (IFolderChild) entity;
      IFolder folder = folderChild.getParent();
      if (parent == null)
        parent = folder;
      else if (parent != folder)
        return null;
    }

    return parent;
  }

  private int getUpdateIntervalScope() {
    if (fPrefUpdateInterval % DAY_IN_SECONDS == 0)
      return DAYS_SCOPE;

    if (fPrefUpdateInterval % HOUR_IN_SECONDS == 0)
      return HOURS_SCOPE;

    return MINUTES_SCOPE;
  }

  private String getName(IEntity entity) {
    if (entity instanceof IFolder)
      return ((IFolder) entity).getName();

    if (entity instanceof IMark)
      return ((IMark) entity).getName();

    return "";
  }

  /*
   * @see org.rssowl.ui.dialogs.properties.IEntityPropertyPage#performOk(java.util.Set)
   */
  public boolean performOk(Set<IEntity> entitiesToSave) {

    /* First handle single-entity Preferences */
    if (fEntities.size() == 1) {
      boolean proceed = internalPerformSingle(entitiesToSave);

      /* Check for abortion due to error here */
      if (!proceed)
        return false;
    }

    /* Now handle single/multi entity Preferences */
    for (IPreferenceScope scope : fEntityPreferences) {
      if (updatePreferences(scope)) {
        IEntity entityToSave = fEntities.get(fEntityPreferences.indexOf(scope));
        entitiesToSave.add(entityToSave);
        fSettingsChanged = true;
      }
    }

    /* Update changes to all Childs as well if Folder */
    for (IEntity entity : fEntities) {
      if (fSettingsChanged && entity instanceof IFolder)
        updateChildPreferences((IFolder) entity);
    }

    return true;
  }

  /* Perform Update on single Entity */
  private boolean internalPerformSingle(Set<IEntity> entitiesToSave) {
    IEntity entity = fEntities.get(0);

    /* Require a Link */
    if (entity instanceof IBookMark && fFeedInput.getText().length() == 0) {
      fSite.select(this);
      fFeedInput.setFocus();

      fSite.setMessage("Please enter a link for the bookmark.", IPropertyDialogSite.MessageType.ERROR);

      return false;
    }

    /* Require a Name */
    if (fNameInput.getText().length() == 0) {
      fSite.select(this);
      fNameInput.setFocus();

      if (entity instanceof IFolder)
        fSite.setMessage("Please enter a name for the folder.", IPropertyDialogSite.MessageType.ERROR);
      else if (entity instanceof IBookMark)
        fSite.setMessage("Please enter a name for the bookmark.", IPropertyDialogSite.MessageType.ERROR);

      return false;
    }

    /* Update Folder */
    if (entity instanceof IFolder) {
      IFolder folder = (IFolder) entity;

      /* Name */
      if (!folder.getName().equals(fNameInput.getText())) {
        folder.setName(fNameInput.getText());
        entitiesToSave.add(folder);
      }
    }

    /* Update BookMark */
    else if (entity instanceof IBookMark) {
      IBookMark bookmark = (IBookMark) entity;

      /* Check for changed Name */
      if (!bookmark.getName().equals(fNameInput.getText())) {
        bookmark.setName(fNameInput.getText());
        entitiesToSave.add(bookmark);
      }

      /* Append "http" to Link if missing */
      String uriAsString = fFeedInput.getText();
      if (URIUtils.looksLikeLink(uriAsString)) {
        if (!uriAsString.contains("://"))
          uriAsString = "http://" + uriAsString;
      }

      /* Check for changed Feed */
      if (!bookmark.getFeedLinkReference().getLink().toString().equals(uriAsString)) {
        try {
          DAOService daoService = Owl.getPersistenceService().getDAOService();

          /* Create URL */
          URI newFeedLink = new URI(uriAsString.trim());
          fReloadRequired = true;

          /* Try to load this Feed from the DB (might be existing already) */
          FeedReference feedRef = daoService.getFeedDAO().loadReference(newFeedLink);

          /* This is a new Feed, so create it! */
          if (feedRef == null) {
            IFeed feed = Owl.getModelFactory().createFeed(null, newFeedLink);
            feed = DynamicDAO.save(feed);
          }

          /* Remember the old Reference */
          FeedLinkReference oldFeedRef = bookmark.getFeedLinkReference();

          /* Apply the new Reference */
          bookmark.setFeedLinkReference(new FeedLinkReference(newFeedLink));
          entitiesToSave.add(bookmark);

          /* Check if the old reference can be deleted now */
          if (daoService.getBookMarkDAO().loadAll(oldFeedRef).size() == 1)
            DynamicDAO.delete(oldFeedRef.resolve());

          /* Delete the Favicon since the feed has changed */
          OwlUI.deleteImage(bookmark.getId());
        }

        /* Supplied Feed Link not valid */
        catch (URISyntaxException e) {
          fSite.select(this);
          fFeedInput.selectAll();
          fFeedInput.setFocus();
          fSite.setMessage("The feed's link is not valid (e.g. 'http://www.link.com').", IPropertyDialogSite.MessageType.ERROR);
          return false;
        }
      }
    }

    return true;
  }

  /*
   * @see org.rssowl.ui.internal.dialogs.properties.IEntityPropertyPage#finish()
   */
  public void finish() {

    /* Reload if required */
    if (fReloadRequired && fEntities.size() == 1)
      Controller.getDefault().reloadQueued((IBookMark) fEntities.get(0), getWorkbenchShell());

    /* Reparent if necessary */
    IFolder sameParent = getSameParent(fEntities);
    if (sameParent != null && sameParent != fFolderChooser.getFolder()) {
      List<ReparentInfo<IFolderChild, IFolder>> reparenting = new ArrayList<ReparentInfo<IFolderChild, IFolder>>();
      for (IEntity entity : fEntities) {
        /* Check BookMark and Folder */
        if (entity instanceof IBookMark || entity instanceof IFolder) {
          IFolderChild folderChild = (IFolderChild) entity;
          reparenting.add(ReparentInfo.create(folderChild, fFolderChooser.getFolder(), null, null));
        }
      }

      /* Perform Reparenting */
      Owl.getPersistenceService().getDAOService().getFolderDAO().reparent(reparenting);
    }
  }

  private Shell getWorkbenchShell() {
    IWorkbenchWindow wWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
    if (wWindow != null)
      return wWindow.getShell();

    return null;
  }

  private boolean updatePreferences(IPreferenceScope scope) {
    boolean changed = false;

    /* Update Interval State */
    boolean bVal = fUpdateCheck.getSelection();
    if (fPrefUpdateIntervalState != bVal) {
      scope.putBoolean(DefaultPreferences.BM_UPDATE_INTERVAL_STATE, bVal);
      changed = true;
    }

    /* Update Interval */
    long lVal;
    fUpdateIntervalScope = fReloadCombo.getSelectionIndex();

    if (fUpdateIntervalScope == MINUTES_SCOPE)
      lVal = fReloadSpinner.getSelection() * MINUTE_IN_SECONDS;
    else if (fUpdateIntervalScope == HOURS_SCOPE)
      lVal = fReloadSpinner.getSelection() * HOUR_IN_SECONDS;
    else
      lVal = fReloadSpinner.getSelection() * DAY_IN_SECONDS;

    if (fPrefUpdateInterval != lVal) {
      scope.putLong(DefaultPreferences.BM_UPDATE_INTERVAL, lVal);
      changed = true;
    }

    /* Open on Startup */
    bVal = fOpenOnStartupCheck.getSelection();
    if (fPrefOpenOnStartup != bVal) {
      scope.putBoolean(DefaultPreferences.BM_OPEN_ON_STARTUP, bVal);
      changed = true;
    }

    return changed;
  }

  private void updateChildPreferences(IFolder folder) {

    /* Update changes to Child-BookMarks */
    List<IMark> marks = folder.getMarks();
    for (IMark mark : marks) {
      if (mark instanceof IBookMark) {
        IPreferenceScope scope = Owl.getPreferenceService().getEntityScope(mark);
        updatePreferences(scope);
      }
    }

    /* Update changes to Child-Folders */
    List<IFolder> folders = folder.getFolders();
    for (IFolder childFolder : folders) {
      IPreferenceScope scope = Owl.getPreferenceService().getEntityScope(childFolder);
      updatePreferences(scope);

      /* Recursively Proceed */
      updateChildPreferences(childFolder);
    }
  }
}
TOP

Related Classes of org.rssowl.ui.internal.dialogs.properties.GeneralPropertyPage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.