javamanager/javainstaller/installerui/javasrc/com/nokia/mj/impl/installer/ui/eswt2/ViewBase.java
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javamanager/javainstaller/installerui/javasrc/com/nokia/mj/impl/installer/ui/eswt2/ViewBase.java	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,746 @@
+/*
+* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.mj.impl.installer.ui.eswt2;
+
+import com.nokia.mj.impl.installer.ui.ApplicationInfo;
+import com.nokia.mj.impl.installer.ui.InstallInfo;
+import com.nokia.mj.impl.installer.ui.UninstallInfo;
+import com.nokia.mj.impl.security.midp.common.SigningCertificate;
+
+import java.io.InputStream;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+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.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Base class for different InstallerUi views.
+ */
+abstract public class ViewBase
+{
+    /** Maximum view height in percentage from display client area height. */
+    protected static final int MAX_VIEW_HEIGHT = 80;
+    /** Parent shell for this view. */
+    protected Shell iParent = null;
+    /** Container for the contents of the view */
+    private Composite iContainer = null;
+    /** ScrolledComposite for iComposite. */
+    private ScrolledComposite iScrolledComposite = null;
+    /** Composite to which subclasses add their widgets. */
+    private Composite iComposite = null;
+    /** ScrolledComposite for iAppInfoComposite. */
+    private ScrolledComposite iAppInfoScrolledComposite = null;
+    /** Composite to which application info is added. */
+    private Composite iAppInfoComposite = null;
+    /** Composite to which command buttons are added. */
+    private Composite iCommandComposite = null;
+    /** Application suite icon */
+    protected Image iSuiteIcon = null;
+    /** InstallerUi owning this view. */
+    protected InstallerUiEswt iInstallerUi = null;
+    /** True if this view is visible. */
+    private boolean iVisible = false;
+    /** Number of columns for this view's GridLayout. */
+    private int iColumns = 1;
+    /** Default content size. */
+    private Point iDefaultContentSize = null;
+    /** Certificate details view.  */
+    private CertificateDetailsView iCertificateDetailsView = null;
+    /** Certificates for this application. */
+    private SigningCertificate[] iCertificates = null;
+
+    /** Constructor */
+    protected ViewBase()
+    {
+    }
+
+    /** Constructor */
+    protected ViewBase(InstallerUiEswt aInstaller, Composite aParent, int aColumns)
+    {
+        this(aInstaller, aParent, aColumns, false);
+    }
+
+    /** Constructor */
+    protected ViewBase(InstallerUiEswt aInstaller, Composite aParent, int aColumns, boolean aScrollable)
+    {
+        iInstallerUi = aInstaller;
+
+        // Each view gets a shell to be used as a parameter.
+        iParent = (Shell)aParent;
+
+        iContainer = new Composite(iParent, 0);
+        iContainer.setVisible(false);
+
+        iColumns = aColumns;
+
+        // Store the default bounds for later height adjustments.
+        Rectangle defShellBounds = iInstallerUi.getDefaultShellBounds();
+        Rectangle defShellClientBounds = iInstallerUi.getDefaultShellClientBounds();
+        iContainer.setSize(defShellClientBounds.width, defShellClientBounds.height);
+
+        // Let the contents fill the Shell.
+        iContainer.setLayout(setZeroMargins(new GridLayout()));
+
+        if (aScrollable)
+        {
+            // Create a ScrolledComposite for views which need ScrollBars.
+            iScrolledComposite = new ScrolledComposite(iContainer, getStyle());
+            iScrolledComposite.setAlwaysShowScrollBars(false);
+            iScrolledComposite.setExpandHorizontal(true);
+            iScrolledComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+            // Create the content composite for the ScrolledComposite.
+            iComposite = new Composite(iScrolledComposite, SWT.NONE);
+            iComposite.setLayout(setZeroMargins(new GridLayout(getColumns(), true)));
+            iScrolledComposite.setContent(iComposite);
+        }
+        else
+        {
+            // Create the composite without ScrollBars.
+            iComposite = new Composite(iContainer, SWT.NONE);
+            GridLayout compLayout =
+                setZeroMargins(new GridLayout(getColumns(), true));
+            iComposite.setLayout(compLayout);
+            iComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+        }
+
+        // Create a composite for command buttons.
+        iCommandComposite = new Composite(iContainer, SWT.NONE);
+        GridLayout cmdLayout = setZeroMargins(new GridLayout(2, true));
+        cmdLayout.marginTop = 5;
+        iCommandComposite.setLayout(cmdLayout);
+        iCommandComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // Layout now and get the default size of the content area.
+        iContainer.layout(true);
+        Rectangle rect = null;
+        if (aScrollable)
+        {
+            rect = iScrolledComposite.getClientArea();
+        }
+        else
+        {
+            rect = iComposite.getClientArea();
+        }
+        iDefaultContentSize = new Point(rect.width, rect.height);
+    }
+
+    /**
+     * Returns composite which holds the contents of this view.
+     */
+    public Composite getContainer()
+    {
+        return iContainer;
+    }
+
+    /** Returns composite to which subclasses can add their widgets. */
+    public Composite getComposite()
+    {
+        return iComposite;
+    }
+
+    /** Returns ScrolledComposite for Composite. */
+    public ScrolledComposite getScrolledComposite()
+    {
+        return iScrolledComposite;
+    }
+
+    /** Returns composite for application info widgets. */
+    public Composite getAppInfoComposite()
+    {
+        return iAppInfoComposite;
+    }
+
+    /** Returns ScrolledComposite for AppInfoComposite. */
+    public ScrolledComposite getAppInfoScrolledComposite()
+    {
+        return iAppInfoScrolledComposite;
+    }
+
+    /** Returns composite to which command buttons are added. */
+    public Composite getCommandComposite()
+    {
+        return iCommandComposite;
+    }
+
+    /** Returns a shell for this view. */
+    public Shell getShell()
+    {
+        return iParent;
+    }
+
+    /** Returns display for this view. */
+    public Display getDisplay()
+    {
+        return getShell().getDisplay();
+    }
+
+    /**
+     * Returns title for this view. If the title has not been
+     * set, returns an empty string.
+     */
+    public String getTitle()
+    {
+        return iParent.getText();
+    }
+
+    /** Set title for this view. */
+    public void setTitle(String aTitle)
+    {
+        // Dialog shells have no title anymore
+    }
+
+    /** Disposes this view. */
+    public void dispose()
+    {
+        // This must be final because it is used from inner class.
+        final String className = this.toString();
+        log(className + ": disposing");
+        // UI updates must be executed in UI thread.
+        iParent.getDisplay().syncExec
+        (new Runnable()
+        {
+            public void run()
+            {
+                log(className + ": disposing view container");
+                iContainer.dispose();
+            }
+        });
+    }
+
+    /** Returns true this view has been disposed, false otherwise. */
+    public boolean isDisposed()
+    {
+        if (iContainer.isDisposed())
+        {
+            return true;
+        }
+        return false;
+    }
+
+    /** Set this view visible. Any previously visible view will be hidden.
+     *  The size of the dialog Shell host will be changed to fit this view.*/
+    public void setVisible(boolean aVisible)
+    {
+        if (iVisible == aVisible)
+        {
+            return;
+        }
+        log(this.toString() + ": setVisible " + aVisible);
+        iVisible = aVisible;
+        if (iVisible)
+        {
+            iInstallerUi.setActiveView(this);
+        }
+        else
+        {
+            if (iInstallerUi.getActiveView() == this)
+            {
+                iInstallerUi.setActiveView(null);
+            }
+        }
+        // UI updates must be executed in UI thread.
+        iParent.getDisplay().syncExec
+        (new Runnable()
+        {
+            public void run()
+            {
+                if (iVisible)
+                {
+                    updateSize();
+                }
+                iContainer.setVisible(iVisible);
+                if (iVisible)
+                {
+                    if (iParent.getDisplay().getActiveShell() != iParent)
+                    {
+                        iParent.open();
+                    }
+                    if (!iParent.isVisible())
+                    {
+                        iParent.setVisible(true);
+                    }
+                    if (forceFocusToView())
+                    {
+                        iContainer.forceFocus();
+                    }
+                }
+            }
+        });
+    }
+
+    /** Returns true if this view is visible, false otherwise. */
+    public boolean isVisible()
+    {
+        return iVisible;
+    }
+
+    /** Sets the view size according to display size. */
+    protected void updateSize()
+    {
+        getShell().setRedraw(false);
+        // First calculate size without vertical scrollbar.
+        doUpdateSize(false);
+        if (getScrolledComposite() != null &&
+                getScrolledComposite().getVerticalBar() != null &&
+                getScrolledComposite().getVerticalBar().getVisible())
+        {
+            // If scrollbar is visible recalculate size with scrollbar.
+            doUpdateSize(true);
+        }
+        getShell().setRedraw(true);
+    }
+
+    /** Sets the view size according to display size. */
+    private void doUpdateSize(boolean aVerticalScrollBarVisible)
+    {
+        Shell shell = getShell();
+        Composite comp = getComposite();
+        Composite cmdComp = getCommandComposite();
+
+        if (getAppInfoComposite() != null)
+        {
+            // Recalculate the size of the app info composite.
+            getAppInfoComposite().setSize(
+                getAppInfoComposite().computeSize(
+                    SWT.DEFAULT, SWT.DEFAULT));
+        }
+
+        int contentWidth = iDefaultContentSize.x;
+        if (aVerticalScrollBarVisible)
+        {
+            int verticalScrollBarWidth =
+                getScrolledComposite().getVerticalBar().getSize().x;
+            contentWidth = iDefaultContentSize.x - verticalScrollBarWidth;
+        }
+
+        // Recalculate the size of the content.
+        Point contentSize = comp.computeSize(contentWidth, SWT.DEFAULT);
+        comp.setSize(contentSize);
+        Point cmdContentSize = cmdComp.computeSize(iDefaultContentSize.x, SWT.DEFAULT);
+        cmdComp.setSize(cmdContentSize);
+
+        // Adjust Shell height. The Shell never changes the x position, nor the width.
+        Rectangle dispRect = shell.getDisplay().getClientArea();
+        int offset = iDefaultContentSize.y - contentSize.y - cmdContentSize.y;
+
+        Rectangle defShellBounds = iInstallerUi.getDefaultShellBounds();
+        int newHeight = defShellBounds.height - offset;
+        int maxHeight = dispRect.height * MAX_VIEW_HEIGHT / 100;
+
+        if (newHeight > maxHeight)
+        {
+            offset -= maxHeight - newHeight;
+            newHeight = maxHeight;
+        }
+
+        Rectangle dispBounds = shell.getDisplay().getBounds();
+        int y = dispBounds.height - newHeight;
+        // Always center vertically.
+        y /= 2;
+        // For landscape orientation center vertically
+        //if (dispRect.width > dispRect.height)
+        //{
+        //    y /= 2;
+        //}
+        // Set bounds when command Buttons are in use.
+        shell.setBounds(defShellBounds.x, y, defShellBounds.width, newHeight);
+        Rectangle clientArea = shell.getClientArea();
+        iContainer.setSize(clientArea.width, clientArea.height);
+        iContainer.layout(true);
+    }
+
+    /**
+     * Called when screen orientation changes.
+     */
+    protected void screenOrientationChanged()
+    {
+        updateSize();
+    }
+
+    /**
+     * Returns true if the View should have focus after it has been opened.
+     */
+    protected boolean forceFocusToView()
+    {
+        return true;
+    }
+
+    /**
+     * Returns SWT style for this view. Subclasses should override
+     * this method to return style with SWT.H_SCROLL and/or SWT.V_SCROLL
+     * if they need scrollbars.
+     */
+    protected int getStyle()
+    {
+        return SWT.NONE;
+    }
+
+    /**
+     * Returns number of columns for this view.
+     */
+    protected int getColumns()
+    {
+        return iColumns;
+    }
+
+    /**
+     * Adds header used in installation and uninstallation views.
+     */
+    protected void addHeader(
+        String aTitle, InstallInfo aInstallInfo, UninstallInfo aUninstallInfo)
+    {
+        // Add title.
+        String title = "Install?";
+        if (aInstallInfo != null)
+        {
+            if (aInstallInfo.getOldVersion() != null)
+            {
+                title = "Update?";
+            }
+            iCertificates = aInstallInfo.getCertificates();
+        }
+        if (aUninstallInfo != null)
+        {
+            title = "Uninstall?";
+            iCertificates = aUninstallInfo.getCertificates();
+        }
+        Label titleLabel = createLabel(aTitle, getColumns() - 1, SWT.WRAP);
+        titleLabel.setFont(iInstallerUi.getBoldFont());
+
+        // Add security icon.
+        createSecurityButton();
+
+        // Add suite icon.
+        InputStream iconInputStream = null;
+        String iconPath = null;
+        if (aInstallInfo != null)
+        {
+            iconInputStream = aInstallInfo.getIconInputStream();
+            iconPath = aInstallInfo.getIconPath();
+        }
+        if (aUninstallInfo != null)
+        {
+            iconInputStream = aUninstallInfo.getIconInputStream();
+            iconPath = aUninstallInfo.getIconPath();
+        }
+        if (iSuiteIcon == null && iconInputStream != null)
+        {
+            iSuiteIcon = InstallerUiEswt.loadImage(
+                             getComposite().getDisplay(), iconInputStream, iconPath);
+        }
+        int iconColumns = 0;
+        if (iSuiteIcon != null)
+        {
+            iconColumns = 2;
+            Label iconLabel = createLabel(iSuiteIcon, iconColumns, SWT.NONE);
+        }
+
+        // Create a Composite for displaying application info.
+        iAppInfoScrolledComposite =
+            new ScrolledComposite(getComposite(), SWT.H_SCROLL | SWT.V_SCROLL);
+        iAppInfoScrolledComposite.setAlwaysShowScrollBars(false);
+        iAppInfoScrolledComposite.setExpandHorizontal(true);
+        GridData gridData = new GridData(GridData.FILL_BOTH);
+        gridData.horizontalSpan = getColumns() - iconColumns;
+        iAppInfoScrolledComposite.setLayoutData(gridData);
+        iAppInfoComposite = new Composite(iAppInfoScrolledComposite, SWT.NONE);
+        iAppInfoComposite.setLayout(new GridLayout(1, true));
+        iAppInfoScrolledComposite.setContent(iAppInfoComposite);
+    }
+
+    /**
+     * Adds application information to the header.
+     */
+    protected void addAppInfo(InstallInfo aInstallInfo, boolean aFull)
+    {
+        if (aInstallInfo == null)
+        {
+            // Nothing to add.
+            return;
+        }
+
+        // Add suite name.
+        createAppInfoLabel(
+            aInstallInfo.getName() + " " + aInstallInfo.getVersion());
+        // Add size.
+        long size = 0;
+        if (aInstallInfo.getJarSize() > 0)
+        {
+            size += aInstallInfo.getJarSize();
+        }
+        if (aInstallInfo.getDataSize() > 0)
+        {
+            size += aInstallInfo.getDataSize();
+        }
+        if (size > 0)
+        {
+            createAppInfoLabel(
+                InstallerUiTexts.get(
+                    InstallerUiTexts.SIZE,
+                    new String[] { Long.toString(1 + size/1024) }));
+        }
+        if (aFull)
+        {
+            // Add vendor.
+            if (aInstallInfo.getCertificates() != null)
+            {
+                // Vendor information must be displayed only for
+                // identified applications.
+                createAppInfoLabel(
+                    InstallerUiTexts.get(
+                        InstallerUiTexts.VENDOR,
+                        new String[] { aInstallInfo.getVendor() }));
+            }
+            // Add application names.
+            ApplicationInfo[] apps = aInstallInfo.getApplications();
+            if (apps != null && apps.length > 0)
+            {
+                if (apps.length > 1 ||
+                        !aInstallInfo.getName().equals(apps[0].getName()))
+                {
+                    for (int i = 0; i < apps.length; i++)
+                    {
+                        createAppInfoLabel(apps[i].getName());
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a new label with given text and adds it to this view.
+     * The created label takes one column from this view's GridLayout.
+     *
+     * @param aText text for the label
+     * @param aStyle SWT style for the label
+     * @return label that was added to this view
+     */
+    protected Label createLabel(String aText, int aStyle)
+    {
+        return createLabel(aText, getColumns(), aStyle);
+    }
+
+    /**
+     * Creates a new label with given text and adds it to this view.
+     *
+     * @param aText text for the label
+     * @param aColumns number of columns the label takes
+     * @param aStyle SWT style for the label
+     * @return label that was added to this view
+     */
+    protected Label createLabel(String aText, int aColumns, int aStyle)
+    {
+        Label label = new Label(getComposite(), aStyle);
+        label.setText(aText);
+        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+        gridData.horizontalSpan = aColumns;
+        label.setLayoutData(gridData);
+        return label;
+    }
+
+    /**
+     * Creates a new label with given image and adds it to this view.
+     * The created label takes one column from this view's GridLayout.
+     *
+     * @param aImage image for the label
+     * @param aStyle SWT style for the label
+     * @return label that was added to this view
+     */
+    protected Label createLabel(Image aImage, int aStyle)
+    {
+        return createLabel(aImage, getColumns(), aStyle);
+    }
+
+    /**
+     * Creates a new label with given image and adds it to this view.
+     * The created label takes one column from this view's GridLayout.
+     *
+     * @param aImage image for the label
+     * @param aColumns number of columns the label takes
+     * @param aStyle SWT style for the label
+     * @return label that was added to this view
+     */
+    protected Label createLabel(Image aImage, int aColumns, int aStyle)
+    {
+        Label label = new Label(getComposite(), aStyle);
+        label.setImage(aImage);
+        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+        gridData.horizontalSpan = aColumns;
+        gridData.horizontalAlignment = SWT.CENTER;
+        gridData.verticalAlignment = SWT.CENTER;
+        label.setLayoutData(gridData);
+        return label;
+    }
+
+    /**
+     * Creates a new label with given text and adds it
+     * to application info composite for this view.
+     *
+     * @param aText text for the label
+     * @return label that was added to this view
+     */
+    protected Label createAppInfoLabel(String aText)
+    {
+        Label label = new Label(getAppInfoComposite(), SWT.WRAP);
+        label.setText(aText);
+        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+        gridData.horizontalSpan = 1;
+        label.setLayoutData(gridData);
+        return label;
+    }
+
+    /**
+     * Creates a new label with security icon.
+     *
+     * @param aIdentified true if security icon is for an
+     * identified application, false otherwise
+     * @return label that was added to this view
+     */
+    protected Label createSecurityLabel(boolean aIdentified)
+    {
+        Label label = createLabel((Image)null, 1, SWT.NONE);
+        Image securityIcon = null;
+        if (iInstallerUi instanceof InstallerUiEswt)
+        {
+            securityIcon = ((InstallerUiEswt)iInstallerUi).getSecurityIcon
+                           (getDisplay(), aIdentified);
+        }
+        if (securityIcon != null)
+        {
+            label.setImage(securityIcon);
+        }
+        else
+        {
+            label.setText(aIdentified? "I": "U");
+        }
+        return label;
+    }
+
+    protected Button createSecurityButton()
+    {
+        Button button = new Button(getComposite(), SWT.PUSH);
+        GridData gridData = new GridData(
+            GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
+        gridData.horizontalSpan = 1;
+        gridData.horizontalAlignment = SWT.CENTER;
+        gridData.verticalAlignment = SWT.CENTER;
+        button.setLayoutData(gridData);
+        Image securityIcon = null;
+        if (iInstallerUi instanceof InstallerUiEswt)
+        {
+            securityIcon =
+                ((InstallerUiEswt)iInstallerUi).getSecurityIcon(
+                    getDisplay(), iCertificates != null);
+        }
+        if (securityIcon != null)
+        {
+            button.setImage(securityIcon);
+        }
+        else
+        {
+            button.setText(iCertificates != null? "I": "U");
+        }
+        button.addSelectionListener(new SelectionListener()
+        {
+            public void widgetDefaultSelected(SelectionEvent aEvent)
+            {
+                widgetSelected(aEvent);
+            }
+            public void widgetSelected(SelectionEvent aEvent)
+            {
+                openCertsView(iCertificates, (iCertificates != null? 0: -1));
+            }
+        });
+        return button;
+    }
+
+    /**
+     * Sets margins and spacing for the given layout to zero.
+     */
+    protected GridLayout setZeroMargins(GridLayout aLayout)
+    {
+        aLayout.horizontalSpacing = 0;
+        aLayout.verticalSpacing = 0;
+        aLayout.marginBottom = 0;
+        aLayout.marginTop = 0;
+        aLayout.marginHeight = 0;
+        aLayout.marginWidth = 0;
+        aLayout.marginLeft = 0;
+        aLayout.marginRight = 0;
+        return aLayout;
+    }
+
+    protected void log(String aMsg)
+    {
+        if (iInstallerUi != null)
+        {
+            iInstallerUi.log(aMsg);
+        }
+    }
+
+    protected void logError(String aMsg, Throwable aThrowable)
+    {
+        if (iInstallerUi != null)
+        {
+            iInstallerUi.logError(aMsg, aThrowable);
+        }
+    }
+
+    /**
+     * Opens certificate information view.
+     */
+    protected void openCertsView(SigningCertificate[] aCerts, int aCertIndex)
+    {
+        iCertificateDetailsView = new CertificateDetailsView(
+            iInstallerUi, getShell(), getTitle(), aCerts, aCertIndex);
+        // New dialog must be opened in a new thread,
+        // because we cannot use the main thread and we
+        // cannot block the UI main thread
+        // where this method gets executed.
+        new Thread(new Runnable()
+        {
+            public void run()
+            {
+                if (iCertificateDetailsView.confirm())
+                {
+                    log("certificateDetailsView confirmed");
+                }
+                else
+                {
+                    log("certificateDetailsView cancelled");
+                }
+                iCertificateDetailsView.dispose();
+                iCertificateDetailsView = null;
+                setVisible(true);
+            }
+        }, "InstallerUiCertViewThread").start();
+    }
+}