org.eclipse.equinox.internal.p2.ui.sdk.scheduler.AutomaticUpdatesPopup.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.equinox.internal.p2.ui.sdk.scheduler.AutomaticUpdatesPopup.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2010 IBM Corporation and others.
 * 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.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Johannes Michler <orgler@gmail.com> - Bug 321568 -  [ui] Preference for automatic-update-reminder doesn't work in multilanguage-environments
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.sdk.scheduler;

import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
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.*;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * AutomaticUpdatesPopup is an async popup dialog for notifying
 * the user of updates.
 * 
 * @since 3.4
 */
public class AutomaticUpdatesPopup extends PopupDialog {
    public static final String[] ELAPSED_VALUES = { PreferenceConstants.PREF_REMIND_30Minutes,
            PreferenceConstants.PREF_REMIND_60Minutes, PreferenceConstants.PREF_REMIND_240Minutes };
    public static final String[] ELAPSED_LOCALIZED_STRINGS = {
            AutomaticUpdateMessages.AutomaticUpdateScheduler_30Minutes,
            AutomaticUpdateMessages.AutomaticUpdateScheduler_60Minutes,
            AutomaticUpdateMessages.AutomaticUpdateScheduler_240Minutes };
    private static final long MINUTE = 60 * 1000L;
    private static final String PREFS_HREF = "PREFS"; //$NON-NLS-1$
    private static final String DIALOG_SETTINGS_SECTION = "AutomaticUpdatesPopup"; //$NON-NLS-1$
    private static final int POPUP_OFFSET = 20;

    IPreferenceStore prefs;
    long remindDelay = -1L;
    IPropertyChangeListener prefListener;
    WorkbenchJob remindJob;
    boolean downloaded;
    Composite dialogArea;
    Link remindLink;
    MouseListener clickListener;

    public AutomaticUpdatesPopup(Shell parentShell, boolean alreadyDownloaded, IPreferenceStore prefs) {
        super(parentShell, PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE | SWT.MODELESS, false, true, true, false, false,
                AutomaticUpdateMessages.AutomaticUpdatesPopup_UpdatesAvailableTitle, null);
        downloaded = alreadyDownloaded;
        this.prefs = prefs;
        remindDelay = computeRemindDelay();
        clickListener = new MouseAdapter() {
            public void mouseDown(MouseEvent e) {
                AutomaticUpdatePlugin.getDefault().getAutomaticUpdater().launchUpdate();
            }
        };
    }

    protected Control createDialogArea(Composite parent) {
        dialogArea = new Composite(parent, SWT.NONE);
        dialogArea.setLayoutData(new GridData(GridData.FILL_BOTH));
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        dialogArea.setLayout(layout);
        dialogArea.addMouseListener(clickListener);

        // The "click to update" label
        Label infoLabel = new Label(dialogArea, SWT.NONE);
        if (downloaded)
            infoLabel.setText(AutomaticUpdateMessages.AutomaticUpdatesPopup_ClickToReviewDownloaded);
        else
            infoLabel.setText(AutomaticUpdateMessages.AutomaticUpdatesPopup_ClickToReviewNotDownloaded);
        infoLabel.setLayoutData(new GridData(GridData.FILL_BOTH));
        infoLabel.addMouseListener(clickListener);

        createRemindSection(dialogArea);

        return dialogArea;

    }

    private void createRemindSection(Composite parent) {
        remindLink = new Link(parent, SWT.MULTI | SWT.WRAP | SWT.RIGHT);
        updateRemindText();
        remindLink.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(getShell(),
                        PreferenceConstants.PREF_PAGE_AUTO_UPDATES, null, null);
                dialog.open();

            }
        });
        remindLink.setLayoutData(new GridData(GridData.FILL_BOTH));
    }

    private void updateRemindText() {
        if (prefs.getBoolean(PreferenceConstants.PREF_REMIND_SCHEDULE))
            remindLink.setText(NLS.bind(AutomaticUpdateMessages.AutomaticUpdatesPopup_RemindAndPrefLink,
                    new String[] { getElapsedTimeString(prefs.getString(PreferenceConstants.PREF_REMIND_ELAPSED)),
                            PREFS_HREF }));
        else
            remindLink.setText(AutomaticUpdateMessages.AutomaticUpdatesPopup_PrefLinkOnly);
        remindLink.getParent().layout(true);
    }

    protected IDialogSettings getDialogBoundsSettings() {
        IDialogSettings settings = AutomaticUpdatePlugin.getDefault().getDialogSettings();
        IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION);
        if (section == null) {
            section = settings.addNewSection(DIALOG_SETTINGS_SECTION);
        }
        return section;
    }

    public int open() {
        prefListener = new IPropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                handlePreferenceChange(event);
            }
        };
        prefs.addPropertyChangeListener(prefListener);
        return super.open();
    }

    public boolean close() {
        return close(true);
    }

    public boolean close(boolean remind) {
        if (remind && prefs.getBoolean(PreferenceConstants.PREF_REMIND_SCHEDULE))
            scheduleRemindJob();
        else
            cancelRemindJob();
        if (prefListener != null) {
            prefs.removePropertyChangeListener(prefListener);
            prefListener = null;
        }
        return super.close();

    }

    void scheduleRemindJob() {
        // Cancel any pending remind job if there is one
        if (remindJob != null)
            remindJob.cancel();
        // If no updates have been found, there is nothing to remind
        if (remindDelay < 0)
            return;
        remindJob = new WorkbenchJob(AutomaticUpdateMessages.AutomaticUpdatesPopup_ReminderJobTitle) {
            public IStatus runInUIThread(IProgressMonitor monitor) {
                if (monitor.isCanceled())
                    return Status.CANCEL_STATUS;
                open();
                return Status.OK_STATUS;
            }
        };
        remindJob.setSystem(true);
        remindJob.setPriority(Job.INTERACTIVE);
        remindJob.schedule(remindDelay);

    }

    /*
     * Computes the number of milliseconds for the delay
     * in reminding the user of updates
     */
    long computeRemindDelay() {
        if (prefs.getBoolean(PreferenceConstants.PREF_REMIND_SCHEDULE)) {
            String elapsed = prefs.getString(PreferenceConstants.PREF_REMIND_ELAPSED);
            for (int d = 0; d < ELAPSED_VALUES.length; d++)
                if (ELAPSED_VALUES[d].equals(elapsed))
                    switch (d) {
                    case 0:
                        // 30 minutes
                        return 30 * MINUTE;
                    case 1:
                        // 60 minutes
                        return 60 * MINUTE;
                    case 2:
                        // 240 minutes
                        return 240 * MINUTE;
                    }
        }
        return -1L;
    }

    void cancelRemindJob() {
        if (remindJob != null) {
            remindJob.cancel();
            remindJob = null;
        }
    }

    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setText(AutomaticUpdateMessages.AutomaticUpdatesPopup_UpdatesAvailableTitle);
    }

    /**
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point)
     */
    protected Point getInitialLocation(Point initialSize) {
        Shell parent = getParentShell();
        Point parentSize, parentLocation;

        if (parent != null) {
            parentSize = parent.getSize();
            parentLocation = parent.getLocation();
        } else {
            Rectangle bounds = getShell().getDisplay().getBounds();
            parentSize = new Point(bounds.width, bounds.height);
            parentLocation = new Point(0, 0);
        }
        // We have to take parent location into account because SWT considers all
        // shell locations to be in display coordinates, even if the shell is parented.
        return new Point(parentSize.x - initialSize.x + parentLocation.x - POPUP_OFFSET,
                parentSize.y - initialSize.y + parentLocation.y - POPUP_OFFSET);
    }

    void handlePreferenceChange(PropertyChangeEvent event) {
        if (PreferenceConstants.PREF_REMIND_SCHEDULE.equals(event.getProperty())) {
            // Reminders turned on
            if (prefs.getBoolean(PreferenceConstants.PREF_REMIND_SCHEDULE)) {
                if (remindLink == null)
                    createRemindSection(dialogArea);
                else {
                    updateRemindText();
                    getShell().layout(true, true);
                }
                computeRemindDelay();
                scheduleRemindJob();
            } else { // reminders turned off
                if (remindLink != null) {
                    updateRemindText();
                    getShell().layout(true, true);
                }
                cancelRemindJob();
            }
        } else if (PreferenceConstants.PREF_REMIND_ELAPSED.equals(event.getProperty())) {
            // Reminding schedule changed
            computeRemindDelay();
            scheduleRemindJob();
        }
    }

    /*
     * Overridden so that clicking in the title menu area closes the dialog.
     * Also creates a close box menu in the title area.
     */
    protected Control createTitleMenuArea(Composite parent) {
        Composite titleComposite = (Composite) super.createTitleMenuArea(parent);
        titleComposite.addMouseListener(clickListener);

        ToolBar toolBar = new ToolBar(titleComposite, SWT.FLAT);
        ToolItem closeButton = new ToolItem(toolBar, SWT.PUSH, 0);

        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(toolBar);
        closeButton.setImage(
                AutomaticUpdatePlugin.getDefault().getImageRegistry().get((AutomaticUpdatePlugin.IMG_TOOL_CLOSE)));
        closeButton.setHotImage(AutomaticUpdatePlugin.getDefault().getImageRegistry()
                .get((AutomaticUpdatePlugin.IMG_TOOL_CLOSE_HOT)));
        closeButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                close();
            }
        });
        // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=177183
        toolBar.addMouseListener(new MouseAdapter() {
            public void mouseDown(MouseEvent e) {
                close();
            }
        });
        return titleComposite;
    }

    /*
     * Overridden to adjust the span of the title label.
     * Reachy, reachy....
     * (non-Javadoc)
     * @see org.eclipse.jface.dialogs.PopupDialog#createTitleControl(org.eclipse.swt.widgets.Composite)
     */
    protected Control createTitleControl(Composite parent) {
        Control control = super.createTitleControl(parent);
        Object data = control.getLayoutData();
        if (data instanceof GridData) {
            ((GridData) data).horizontalSpan = 1;
        }
        return control;
    }

    public static String getElapsedTimeString(String elapsedTimeKey) {
        for (int i = 0; i < AutomaticUpdatesPopup.ELAPSED_VALUES.length; i++) {
            if (AutomaticUpdatesPopup.ELAPSED_VALUES[i].equals(elapsedTimeKey))
                return AutomaticUpdatesPopup.ELAPSED_LOCALIZED_STRINGS[i];
        }
        return AutomaticUpdatesPopup.ELAPSED_LOCALIZED_STRINGS[0];
    }
}