javamanager/javainstaller/installerui/javasrc/com/nokia/mj/impl/installer/ui/eswt/InstallerUiEswt.java
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 package com.nokia.mj.impl.installer.ui.eswt;
       
    20 
       
    21 import com.nokia.mj.impl.fileutils.FileUtility;
       
    22 import com.nokia.mj.impl.installer.ui.ApplicationInfo;
       
    23 import com.nokia.mj.impl.installer.ui.DownloadInfo;
       
    24 import com.nokia.mj.impl.installer.ui.InstallerUi;
       
    25 import com.nokia.mj.impl.installer.ui.InstallerUiListener;
       
    26 import com.nokia.mj.impl.installer.ui.InstallInfo;
       
    27 import com.nokia.mj.impl.installer.ui.LaunchAppInfo;
       
    28 import com.nokia.mj.impl.installer.ui.PermissionInfo;
       
    29 import com.nokia.mj.impl.installer.ui.UninstallInfo;
       
    30 import com.nokia.mj.impl.rt.ui.RuntimeUi;
       
    31 import com.nokia.mj.impl.rt.ui.RuntimeUiFactory;
       
    32 import com.nokia.mj.impl.utils.ResourceUtil;
       
    33 import com.nokia.mj.impl.utils.StartUpTrace;
       
    34 import com.nokia.mj.impl.utils.exception.InstallerExceptionBase;
       
    35 
       
    36 import java.io.InputStream;
       
    37 import java.io.IOException;
       
    38 import java.util.Hashtable;
       
    39 
       
    40 import org.eclipse.swt.SWT;
       
    41 import org.eclipse.swt.events.ControlEvent;
       
    42 import org.eclipse.swt.events.ControlListener;
       
    43 import org.eclipse.swt.graphics.Font;
       
    44 import org.eclipse.swt.graphics.FontData;
       
    45 import org.eclipse.swt.graphics.Image;
       
    46 import org.eclipse.swt.graphics.ImageData;
       
    47 import org.eclipse.swt.graphics.ImageLoader;
       
    48 import org.eclipse.swt.graphics.Point;
       
    49 import org.eclipse.swt.graphics.Rectangle;
       
    50 import org.eclipse.swt.widgets.Display;
       
    51 import org.eclipse.swt.widgets.Event;
       
    52 import org.eclipse.swt.widgets.Composite;
       
    53 import org.eclipse.swt.widgets.Listener;
       
    54 import org.eclipse.swt.widgets.Shell;
       
    55 //import org.eclipse.swt.widgets.MessageBox;
       
    56 
       
    57 /**
       
    58  * JavaInstaller eSWT UI.
       
    59  *
       
    60  * @author Nokia Corporation
       
    61  * @version $Rev: 0 $
       
    62  */
       
    63 public class InstallerUiEswt extends InstallerUi
       
    64 {
       
    65     /** Default shell style. */
       
    66     private static final int SHELL_STYLE =
       
    67         SWT.BORDER | SWT.APPLICATION_MODAL | SWT.ON_TOP;
       
    68 
       
    69     private Shell iParent = null;
       
    70     private Shell iDialog = null;
       
    71     private ProgressView iProgressView = null;
       
    72     private ProgressView iDlProgressView = null;
       
    73     private ProgressView iOcspProgressView = null;
       
    74     private InstallConfirmationView iInstallConfirmationView = null;
       
    75     private UninstallConfirmationView iUninstallConfirmationView = null;
       
    76     private PermissionConfirmationView iPermissionConfirmationView = null;
       
    77     private UsernamePasswordView iUsernamePasswordView = null;
       
    78     private LaunchAppQueryView iLaunchAppQueryView = null;
       
    79     /** Synchronization object for waiting for the UI initialization. */
       
    80     private Object iInitWaitObject = new Object();
       
    81     /** Synchronization object for waiting for the UI termination. */
       
    82     private Object iExitWaitObject = new Object();
       
    83     /**
       
    84      * Synchronization object for synchronizing progress updates
       
    85      * and confirmation dialogs. Used to guard disabling and
       
    86      * getting iDisplayProgress variable.
       
    87      */
       
    88     private Object iProgressSyncObject = new Object();
       
    89     /** Flag telling if UI main thread exists. */
       
    90     private boolean iUiThreadExists = false;
       
    91     /** Name of the application to be installed. */
       
    92     private String iAppName = null;
       
    93     /** Security icon.  */
       
    94     private Image iSecurityIcon = null;
       
    95     /** Flag telling if progress bar should be displayed. */
       
    96     private boolean iDisplayProgress = false;
       
    97     /** Flag telling if the first progress bar update has been traced. */
       
    98     private boolean iProgressBarUpdateTraced = false;
       
    99     /** Flag telling if MinimalUi should be used if UI creation fails. */
       
   100     private boolean iMinimalUiEnabled = true;
       
   101 
       
   102     /** Hashtable for storing the loaded icons. */
       
   103     private static Hashtable iImageTable = null;
       
   104 
       
   105     /** Default shell bounds. */
       
   106     private Rectangle iDefaultShellBounds = null;
       
   107     private Rectangle iDefaultShellClientBounds = null;
       
   108 
       
   109     /** Bold font for views. */
       
   110     private Font iBoldFont = null;
       
   111 
       
   112     private ViewBase iActiveView = null;
       
   113 
       
   114     /**
       
   115      * Constructor.
       
   116      */
       
   117     public InstallerUiEswt()
       
   118     {
       
   119         super();
       
   120     }
       
   121 
       
   122     /**
       
   123      * Initialise InstallerUi after construction.
       
   124      */
       
   125     public void init(int aMode, InstallerUiListener aListener)
       
   126     {
       
   127         super.init(aMode, aListener);
       
   128         StartUpTrace.doTrace("InstallerUiEswt init");
       
   129         // Create a hashtable for icons.
       
   130         iImageTable = new Hashtable();
       
   131         // Create a new thread to be the UI main thread.
       
   132         iUiThreadExists = true;
       
   133         new Thread(new Runnable()
       
   134         {
       
   135             public void run()
       
   136             {
       
   137                 uiMain();
       
   138             }
       
   139         }, "InstallerUiMainThread").start();
       
   140         // To wait InstallerUi to be ready before installer main thread
       
   141         // continues, uncomment the following line.
       
   142         //waitForUi();
       
   143     }
       
   144 
       
   145     /**
       
   146      * This method is executed in UI main thread.
       
   147      */
       
   148     private void uiMain()
       
   149     {
       
   150         log("uiMain: thread started");
       
   151         try
       
   152         {
       
   153             // Create the necessary views.
       
   154             Display display = new Display();
       
   155             StartUpTrace.doTrace("InstallerUiEswt display created");
       
   156             display.setAppName(""); // Remove display title.
       
   157             iParent = new Shell(display);
       
   158             iDialog = new Shell(iParent, SHELL_STYLE);
       
   159             iDefaultShellBounds = iDialog.internal_getDefaultBounds();
       
   160             iDefaultShellClientBounds = iDialog.getClientArea();
       
   161             iBoldFont = getBoldFont();
       
   162             StartUpTrace.doTrace("InstallerUiEswt shell created");
       
   163             iProgressView = new ProgressView(this, iDialog, getTitle());
       
   164 
       
   165             iParent.addControlListener(new CListener(this));
       
   166             log("InstallerUiEswt CListener added");
       
   167 
       
   168             display.addListener(SWT.Dispose, new Listener()
       
   169             {
       
   170                 public void handleEvent(Event aEvent)
       
   171                 {
       
   172                     log("Dispose event for display");
       
   173                     // Prevent UI from being automatically disposed.
       
   174                     //aEvent.doit = false;
       
   175                 }
       
   176             });
       
   177 
       
   178             synchronized (iInitWaitObject)
       
   179             {
       
   180                 // Notify that UI is now ready.
       
   181                 iInitWaitObject.notify();
       
   182             }
       
   183             StartUpTrace.doTrace("InstallerUiEswt ready");
       
   184 
       
   185             // If there has been ui update requests, update the ui right
       
   186             // away.
       
   187             if (iMode == MODE_INSTALL && getOcspIndicator())
       
   188             {
       
   189                 setOcspIndicator(getOcspIndicator());
       
   190             }
       
   191             else if (iMode == MODE_APP_CONVERSION &&
       
   192                      iAppConversionTotal > 0)
       
   193             {
       
   194                 updateAppConversionIndicator(
       
   195                     iAppConversionCurrent, iAppConversionTotal);
       
   196             }
       
   197 
       
   198             // UI event loop must be executed in UI main thread,
       
   199             // which is the thread where Display is created.
       
   200             while (isUiReady())
       
   201             {
       
   202                 if (!display.readAndDispatch())
       
   203                 {
       
   204                     display.sleep();
       
   205                 }
       
   206             }
       
   207             if (iBoldFont != null && !iBoldFont.isDisposed())
       
   208             {
       
   209                 iBoldFont.dispose();
       
   210             }
       
   211             display.dispose();
       
   212             log("uiMain: display disposed");
       
   213             synchronized (iExitWaitObject)
       
   214             {
       
   215                 // Notify that UI main thread has been terminated.
       
   216                 iExitWaitObject.notify();
       
   217             }
       
   218         }
       
   219         catch (Throwable t)
       
   220         {
       
   221             logError("Exception in uiMain", t);
       
   222             // Release wait object in case someone is waiting for them.
       
   223             synchronized (iInitWaitObject)
       
   224             {
       
   225                 iUiThreadExists = false;
       
   226                 iInitWaitObject.notify();
       
   227             }
       
   228             synchronized (iExitWaitObject)
       
   229             {
       
   230                 iExitWaitObject.notify();
       
   231             }
       
   232         }
       
   233         iUiThreadExists = false;
       
   234         log("uiMain: thread ended");
       
   235     }
       
   236 
       
   237     /**
       
   238      * Cancels all confirmation views that are currently displayed.
       
   239      */
       
   240     public void cancelConfirmations()
       
   241     {
       
   242         super.cancelConfirmations();
       
   243         if (iInstallConfirmationView != null)
       
   244         {
       
   245             iInstallConfirmationView.confirmCancel();
       
   246         }
       
   247         if (iUninstallConfirmationView != null)
       
   248         {
       
   249             iUninstallConfirmationView.confirmCancel();
       
   250         }
       
   251         if (iPermissionConfirmationView != null)
       
   252         {
       
   253             iPermissionConfirmationView.confirmCancel();
       
   254         }
       
   255         if (iUsernamePasswordView != null)
       
   256         {
       
   257             iUsernamePasswordView.confirmCancel();
       
   258         }
       
   259         if (iLaunchAppQueryView != null)
       
   260         {
       
   261             iLaunchAppQueryView.confirmCancel();
       
   262         }
       
   263         // Remove download progress bar if it visible.
       
   264         if (iDlProgressView != null && !iDlProgressView.isDisposed())
       
   265         {
       
   266             iDlProgressView.dispose();
       
   267             iDlProgressView = null;
       
   268         }
       
   269     }
       
   270 
       
   271     /**
       
   272      * Confirm installation. UI should display an installation
       
   273      * confirmation dialog to the user. UI must update
       
   274      * aInstallInfo basing on user selections.
       
   275      * This method blocks until user has answered to the dialog.
       
   276      *
       
   277      * @param aInstallInfo installation information
       
   278      * @return true if user has accepted installation, false otherwise
       
   279      */
       
   280     public boolean confirm(InstallInfo aInstallInfo)
       
   281     {
       
   282         super.confirm(aInstallInfo);
       
   283 
       
   284         waitForUi();
       
   285         boolean result = true;
       
   286         if (!isUiReady())
       
   287         {
       
   288             result = false;
       
   289             if (iMinimalUiEnabled)
       
   290             {
       
   291                 result = MinimalUi.confirmStatic(aInstallInfo);
       
   292                 log("MinimalUi installation confirmation returns " + result);
       
   293                 return result;
       
   294             }
       
   295             else
       
   296             {
       
   297                 // If UI is not ready by the time confirmation is requested,
       
   298                 // throw an exception.
       
   299                 throw new RuntimeException("JavaInstallerUi not ready");
       
   300             }
       
   301         }
       
   302 
       
   303         if (result)
       
   304         {
       
   305             StartUpTrace.doTrace("InstallerUiEswt confirm");
       
   306             if (iInstallConfirmationView == null)
       
   307             {
       
   308                 final Display display = iParent.getDisplay();
       
   309                 final InstallerUiEswt self = this;
       
   310                 display.syncExec
       
   311                 (new Runnable()
       
   312                 {
       
   313                     public void run()
       
   314                     {
       
   315                         iInstallConfirmationView =
       
   316                             new InstallConfirmationView(self, iDialog);
       
   317                     }
       
   318                 });
       
   319             }
       
   320             result = iInstallConfirmationView.confirm(aInstallInfo);
       
   321             iInstallConfirmationView.dispose();
       
   322             iInstallConfirmationView = null;
       
   323         }
       
   324         if (result)
       
   325         {
       
   326             iAppName = aInstallInfo.getName();
       
   327             if (iUsernamePasswordView != null)
       
   328             {
       
   329                 // UsernamePasswordView blocks prompting until
       
   330                 // app name is set so that username/password
       
   331                 // prompt will not be displayed if the user
       
   332                 // does not confirm installation.
       
   333                 iUsernamePasswordView.setAppName(iAppName);
       
   334             }
       
   335             else
       
   336             {
       
   337                 // UsernamePasswordView is not being displayed,
       
   338                 // let's allow progress to be displayed.
       
   339                 iDisplayProgress = true;
       
   340                 // If download progress view is in use,
       
   341                 // display it to user only after confirmation.
       
   342                 if (iDlProgressView != null && !iDlProgressView.isVisible())
       
   343                 {
       
   344                     iDlProgressView.setVisible(true);
       
   345                 }
       
   346             }
       
   347         }
       
   348         else
       
   349         {
       
   350             // The install confirmation has been rejected,
       
   351             // nothing to display anymore.
       
   352             iParent.getDisplay().syncExec
       
   353             (new Runnable()
       
   354             {
       
   355                 public void run()
       
   356                 {
       
   357                     iParent.dispose();
       
   358                 }
       
   359             });
       
   360         }
       
   361         log("Installation confirmation returns " + result);
       
   362         return result;
       
   363     }
       
   364 
       
   365     /**
       
   366      * Confirm permissions. UI should display a permission
       
   367      * confirmation dialog to the user.
       
   368      * This method blocks until user has answered to the dialog.
       
   369      *
       
   370      * @param aPermissionInfo permission information
       
   371      * @return true if user has accepted permissions, false otherwise
       
   372      */
       
   373     public boolean confirmPermissions(PermissionInfo aPermissionInfo)
       
   374     {
       
   375         super.confirmPermissions(aPermissionInfo);
       
   376 
       
   377         waitForUi();
       
   378         if (!isUiReady())
       
   379         {
       
   380             aPermissionInfo.setPermissionAllowed(false);
       
   381             return true;
       
   382         }
       
   383 
       
   384         synchronized (iProgressSyncObject)
       
   385         {
       
   386             // Do not display progress bar during dialog.
       
   387             iDisplayProgress = false;
       
   388         }
       
   389         if (iPermissionConfirmationView == null)
       
   390         {
       
   391             final Display display = iParent.getDisplay();
       
   392             final InstallerUiEswt self = this;
       
   393             display.syncExec
       
   394             (new Runnable()
       
   395             {
       
   396                 public void run()
       
   397                 {
       
   398                     iPermissionConfirmationView =
       
   399                         new PermissionConfirmationView(self, iDialog);
       
   400                 }
       
   401             });
       
   402         }
       
   403         boolean result = iPermissionConfirmationView.confirm(
       
   404                              iInstallInfo, aPermissionInfo);
       
   405         iPermissionConfirmationView.dispose();
       
   406         iPermissionConfirmationView = null;
       
   407         iDisplayProgress = true;
       
   408         iProgressView.setVisible(true);
       
   409         log("Permission confirmation returns " + result +
       
   410             ", user selection " + aPermissionInfo.isPermissionAllowed());
       
   411         return result;
       
   412     }
       
   413 
       
   414     /**
       
   415      * Confirm uninstallation. UI should display an uninstallation
       
   416      * confirmation dialog to the user.
       
   417      * This method blocks until user has answered to the dialog.
       
   418      *
       
   419      * @param aUninstallInfo uninstallation information
       
   420      * @return true if user has accepted uninstallation, false otherwise
       
   421      */
       
   422     public boolean confirm(UninstallInfo aUninstallInfo)
       
   423     {
       
   424         super.confirm(aUninstallInfo);
       
   425 
       
   426         waitForUi();
       
   427         boolean result = true;
       
   428         if (!isUiReady())
       
   429         {
       
   430             result = false;
       
   431             if (iMinimalUiEnabled)
       
   432             {
       
   433                 result = MinimalUi.confirmStatic(aUninstallInfo);
       
   434                 log("MinimalUi uninstallation confirmation returns " + result);
       
   435                 return result;
       
   436             }
       
   437             else
       
   438             {
       
   439                 // If UI is not ready by the time confirmation is requested,
       
   440                 // throw an exception.
       
   441                 throw new RuntimeException("JavaInstallerUi not ready");
       
   442             }
       
   443         }
       
   444         if (result)
       
   445         {
       
   446             StartUpTrace.doTrace("InstallerUiEswt confirm");
       
   447             if (iUninstallConfirmationView == null)
       
   448             {
       
   449                 final Display display = iParent.getDisplay();
       
   450                 final InstallerUiEswt self = this;
       
   451                 display.syncExec
       
   452                 (new Runnable()
       
   453                 {
       
   454                     public void run()
       
   455                     {
       
   456                         iUninstallConfirmationView =
       
   457                             new UninstallConfirmationView(self, iDialog);
       
   458                     }
       
   459                 });
       
   460             }
       
   461             result = iUninstallConfirmationView.confirm(aUninstallInfo);
       
   462             iUninstallConfirmationView.dispose();
       
   463             iUninstallConfirmationView = null;
       
   464         }
       
   465         if (result)
       
   466         {
       
   467             iDisplayProgress = true;
       
   468         }
       
   469         else
       
   470         {
       
   471             // The uninstall confirmation has been rejected,
       
   472             // nothing to display anymore.
       
   473             iParent.getDisplay().syncExec
       
   474             (new Runnable()
       
   475             {
       
   476                 public void run()
       
   477                 {
       
   478                     iParent.dispose();
       
   479                 }
       
   480             });
       
   481         }
       
   482         log("Uninstallation confirmation returns " + result);
       
   483         return result;
       
   484     }
       
   485 
       
   486     /**
       
   487      * This method is used to notify UI that installation or
       
   488      * uninstallation has started. Upon this call UI could
       
   489      * for example display progress bar.
       
   490      * This method must return quickly.
       
   491      */
       
   492     public void started()
       
   493     {
       
   494         super.started();
       
   495     }
       
   496 
       
   497     /**
       
   498      * This method is used to notify UI that installation or
       
   499      * uninstallation has progressed. Upon this call UI can
       
   500      * update progress bar.
       
   501      * This method must return quickly.
       
   502      *
       
   503      * @param aProgress progress value between 0 and 100
       
   504      */
       
   505     public void updateProgress(int aProgress)
       
   506     {
       
   507         super.updateProgress(aProgress);
       
   508         if (!isUiReady())
       
   509         {
       
   510             return;
       
   511         }
       
   512         // UI is created asynchronously, so it might be that
       
   513         // UI was not yet ready when started() was called.
       
   514         // Ensure that iProgressView has been opened before
       
   515         // updating it.
       
   516         synchronized (iProgressSyncObject)
       
   517         {
       
   518             if (iDisplayProgress && !iProgressView.isVisible())
       
   519             {
       
   520                 iProgressView.setVisible(true);
       
   521             }
       
   522             if (iDisplayProgress && !iProgressBarUpdateTraced)
       
   523             {
       
   524                 StartUpTrace.doTrace(
       
   525                     "InstallerUiEswt progress " + aProgress + " %");
       
   526                 iProgressBarUpdateTraced = true;
       
   527             }
       
   528         }
       
   529         iProgressView.updateProgress(aProgress);
       
   530 
       
   531     }
       
   532 
       
   533     /**
       
   534      * This method is used to notify UI that installation or
       
   535      * uninstallation has ended. Upon this call UI can
       
   536      * stop displaying progress bar.
       
   537      * This method must return quickly.
       
   538      */
       
   539     public void ended()
       
   540     {
       
   541         super.ended();
       
   542         if (!isUiReady())
       
   543         {
       
   544             return;
       
   545         }
       
   546         Display display = iParent.getDisplay();
       
   547         display.syncExec
       
   548         (new Runnable()
       
   549         {
       
   550             public void run()
       
   551             {
       
   552                 iParent.dispose();
       
   553             }
       
   554         });
       
   555         log("ended: parent disposed");
       
   556         // Let's wait for ui to be properly terminated before returning.
       
   557         synchronized (iExitWaitObject)
       
   558         {
       
   559             try
       
   560             {
       
   561                 if (!display.isDisposed())
       
   562                 {
       
   563                     iExitWaitObject.wait();
       
   564                 }
       
   565             }
       
   566             catch (InterruptedException ie)
       
   567             {
       
   568                 // Ignore silently.
       
   569             }
       
   570         }
       
   571         log("ended returns");
       
   572     }
       
   573 
       
   574     /**
       
   575      * This method is used to notify UI that a download has started.
       
   576      * Upon this call UI can for example prepare to display a download
       
   577      * progress bar.
       
   578      * NOTE: When this method is called, the totalSize in DownlodInfo
       
   579      * is not yet initialized.
       
   580      * This method must return quickly.
       
   581      *
       
   582      * @param aDownloadInfo information about download
       
   583      */
       
   584     public void started(DownloadInfo aDownloadInfo)
       
   585     {
       
   586         super.started(aDownloadInfo);
       
   587         if (!isUiReady())
       
   588         {
       
   589             return;
       
   590         }
       
   591         // Ensure that download progress bar is displayed and
       
   592         // updated to zero progress.
       
   593         long oldCurrentSize = aDownloadInfo.getCurrentSize();
       
   594         long oldTotalSize = aDownloadInfo.getTotalSize();
       
   595         aDownloadInfo.setCurrentSize(0);
       
   596         aDownloadInfo.setTotalSize(100);
       
   597         updateProgress(aDownloadInfo);
       
   598         aDownloadInfo.setCurrentSize(oldCurrentSize);
       
   599         aDownloadInfo.setTotalSize(oldTotalSize);
       
   600     }
       
   601 
       
   602     /**
       
   603      * This method is used to notify UI that a download
       
   604      * has progressed. Upon this call UI can
       
   605      * update download progress bar.
       
   606      * This method must return quickly.
       
   607      *
       
   608      * @param aDownloadInfo information about download
       
   609      */
       
   610     public void updateProgress(DownloadInfo aDownloadInfo)
       
   611     {
       
   612         super.updateProgress(aDownloadInfo);
       
   613         if (!isUiReady())
       
   614         {
       
   615             return;
       
   616         }
       
   617 
       
   618         if (iDlProgressView == null)
       
   619         {
       
   620             final boolean indeterminate =
       
   621                 (aDownloadInfo.getTotalSize() <= 0);
       
   622             final InstallerUiEswt self = this;
       
   623             iParent.getDisplay().syncExec(new Runnable()
       
   624             {
       
   625                 public void run()
       
   626                 {
       
   627                     iDlProgressView = new ProgressView(
       
   628                         self, iDialog,
       
   629                         InstallerUiTexts.get(InstallerUiTexts.DOWNLOADING),
       
   630                         indeterminate);
       
   631                 }
       
   632             });
       
   633             iDlProgressView.addCancelCommand();
       
   634         }
       
   635 
       
   636         synchronized (iProgressSyncObject)
       
   637         {
       
   638             if (iDisplayProgress && !iDlProgressView.isVisible())
       
   639             {
       
   640                 iDlProgressView.setVisible(true);
       
   641             }
       
   642         }
       
   643         if (aDownloadInfo.getTotalSize() > 0)
       
   644         {
       
   645             int progress = (int)((aDownloadInfo.getCurrentSize()*100)/
       
   646                                  aDownloadInfo.getTotalSize());
       
   647             iDlProgressView.updateProgress(progress);
       
   648         }
       
   649     }
       
   650 
       
   651     /**
       
   652      * This method is used to notify UI that a download
       
   653      * has ended. Upon this call UI can stop
       
   654      * displaying download progress bar.
       
   655      * This method must return quickly.
       
   656      *
       
   657      * @param aDownloadInfo information about download
       
   658      */
       
   659     public void ended(DownloadInfo aDownloadInfo)
       
   660     {
       
   661         super.ended(aDownloadInfo);
       
   662         if (!isUiReady())
       
   663         {
       
   664             return;
       
   665         }
       
   666         if (iDlProgressView != null)
       
   667         {
       
   668             iDlProgressView.dispose();
       
   669             iDlProgressView = null;
       
   670         }
       
   671         synchronized (iProgressSyncObject)
       
   672         {
       
   673             if (iDisplayProgress && !iProgressView.isVisible())
       
   674             {
       
   675                 iProgressView.setVisible(true);
       
   676             }
       
   677         }
       
   678     }
       
   679 
       
   680     /**
       
   681      * Set OCSP indicator on or off.
       
   682      *
       
   683      * @param aOn true when OCSP is started, false when OCSP is stopped
       
   684      */
       
   685     public void setOcspIndicator(boolean aOn)
       
   686     {
       
   687         super.setOcspIndicator(aOn);
       
   688         waitForUi();
       
   689         if (!isUiReady())
       
   690         {
       
   691             log("UI not ready, could not set OCSP indicator to " + aOn);
       
   692             return;
       
   693         }
       
   694         if (aOn)
       
   695         {
       
   696             if (iOcspProgressView == null)
       
   697             {
       
   698                 final InstallerUiEswt self = this;
       
   699                 iParent.getDisplay().syncExec
       
   700                 (new Runnable()
       
   701                 {
       
   702                     public void run()
       
   703                     {
       
   704                         iOcspProgressView = new ProgressView(self, iDialog,
       
   705                                                              InstallerUiTexts.get(InstallerUiTexts.OCSP_CHECK_PROGRESS),
       
   706                                                              true);
       
   707                     }
       
   708                 });
       
   709                 iOcspProgressView.addCancelCommand();
       
   710             }
       
   711             if (iOcspProgressView != null)
       
   712             {
       
   713                 if (!iOcspProgressView.isVisible())
       
   714                 {
       
   715                     iOcspProgressView.setVisible(true);
       
   716                 }
       
   717             }
       
   718         }
       
   719         else
       
   720         {
       
   721             if (iOcspProgressView != null)
       
   722             {
       
   723                 if (iOcspProgressView.isVisible())
       
   724                 {
       
   725                     iOcspProgressView.setVisible(false);
       
   726                 }
       
   727                 iOcspProgressView.dispose();
       
   728                 iOcspProgressView = null;
       
   729             }
       
   730         }
       
   731     }
       
   732 
       
   733     /**
       
   734      * Update application conversion indicator.
       
   735      *
       
   736      * @param aCurrent Index of the current application (1..total).
       
   737      * @param aTotal Total number of applications. Setting aTotal to
       
   738      * zero indicates that application conversion has been completed
       
   739      * and ui can be disposed.
       
   740      */
       
   741     public void updateAppConversionIndicator(int aCurrent, int aTotal)
       
   742     {
       
   743         super.updateAppConversionIndicator(aCurrent, aTotal);
       
   744         if (!isUiReady())
       
   745         {
       
   746             log("UI not ready, could not update app conversion indicator");
       
   747             return;
       
   748         }
       
   749         int progress = 101;
       
   750         if (aTotal > 0)
       
   751         {
       
   752             progress = (aCurrent*100)/aTotal;
       
   753         }
       
   754         if (progress <= 100)
       
   755         {
       
   756             iProgressView.setText(getTitle());
       
   757             iProgressView.updateProgress(progress);
       
   758             if (!iProgressView.isVisible())
       
   759             {
       
   760                 iProgressView.removeCancelCommand();
       
   761                 iProgressView.setVisible(true);
       
   762             }
       
   763             iParent.getDisplay().syncExec(new Runnable()
       
   764             {
       
   765                 public void run()
       
   766                 {
       
   767                     // Ensure that conversion indicator
       
   768                     // is drawn to the foreground.
       
   769                     iParent.setMaximized(true);
       
   770                 }
       
   771             });
       
   772         }
       
   773         else
       
   774         {
       
   775             iProgressView.updateProgress(100);
       
   776             // Call ended() method which will dispose the ui.
       
   777             ended();
       
   778         }
       
   779     }
       
   780 
       
   781     /**
       
   782      * Notify user that an error has occurred.
       
   783      * This method must return quickly.
       
   784      *
       
   785      * @param aInstallerException exception indicating the error reason
       
   786      */
       
   787     public void error(InstallerExceptionBase aInstallerException)
       
   788     {
       
   789         super.error(aInstallerException);
       
   790 
       
   791         waitForUi();
       
   792         // InstallerUi does not have to be ready as long as
       
   793         // RuntimeUi is used to display error messages.
       
   794         //if (!isUiReady()) {
       
   795         //    return;
       
   796         //}
       
   797 
       
   798         boolean identified = false;
       
   799         //String tmpAppName = null;
       
   800         if (iInstallInfo != null)
       
   801         {
       
   802             //tmpAppName = iInstallInfo.getName();
       
   803             if (iInstallInfo.getCertificates() != null)
       
   804             {
       
   805                 identified = true;
       
   806             }
       
   807         }
       
   808         else if (iUninstallInfo != null)
       
   809         {
       
   810             //tmpAppName = iUninstallInfo.getName();
       
   811             if (iUninstallInfo.getCertificates() != null)
       
   812             {
       
   813                 identified = true;
       
   814             }
       
   815         }
       
   816         String tmpTitle = "";
       
   817         if (iMode == MODE_INSTALL)
       
   818         {
       
   819             tmpTitle = InstallerUiTexts.get(InstallerUiTexts.INSTALL_FAILED);
       
   820         }
       
   821         else if (iMode == MODE_UNINSTALL)
       
   822         {
       
   823             tmpTitle = InstallerUiTexts.get(InstallerUiTexts.UNINSTALL_FAILED);
       
   824         }
       
   825 
       
   826         // Ensure that no confirmations are being displayed.
       
   827         cancelConfirmations();
       
   828         // Hide progress view before displaying error message.
       
   829         if (iProgressView != null)
       
   830         {
       
   831             iProgressView.setVisible(false);
       
   832         }
       
   833         // Use RuntimeUi to display error message.
       
   834         RuntimeUi runtimeUi = RuntimeUiFactory.getRuntimeUi(identified);
       
   835         runtimeUi.error(tmpTitle, aInstallerException);
       
   836         runtimeUi.destroy();
       
   837 
       
   838         /*
       
   839         // Display error message using eSWT MessageBox.
       
   840         final String appName = tmpAppName;
       
   841         final String title = tmpTitle;
       
   842         final String shortMsg = aInstallerException.getShortMessage();
       
   843         final String detailedMsg = aInstallerException.getDetailedMessage();
       
   844         // UI updates must be executed in UI thread.
       
   845         iParent.getDisplay().syncExec
       
   846             (new Runnable() {
       
   847                     public void run() {
       
   848                         if (detailedMsg == null || detailedMsg.length() == 0) {
       
   849                             // No detailed msg, display only short msg.
       
   850                             MessageBox messageBox = new MessageBox
       
   851                                 (iParent, SWT.ICON_ERROR | SWT.OK);
       
   852                             messageBox.setText(title);
       
   853                             messageBox.setMessage
       
   854                                 (getMessage(title, appName, shortMsg, false));
       
   855                             messageBox.open();
       
   856                         } else {
       
   857                             // Display both short and detailed msgs.
       
   858                             MessageBox messageBox = new MessageBox
       
   859                                 (iParent, SWT.ICON_ERROR | SWT.YES | SWT.NO);
       
   860                             messageBox.setText(title);
       
   861                             messageBox.setMessage
       
   862                                 (getMessage(title, appName, shortMsg, true));
       
   863                             int answer = messageBox.open();
       
   864                             if ((answer & SWT.YES) != 0) {
       
   865                                 // User wants to see details, display them.
       
   866                                 messageBox = new MessageBox
       
   867                                     (iParent, SWT.ICON_ERROR | SWT.OK);
       
   868                                 messageBox.setText(title);
       
   869                                 messageBox.setMessage
       
   870                                     (getMessage(title, appName, detailedMsg, false));
       
   871                                 messageBox.open();
       
   872                             }
       
   873                         }
       
   874                     }
       
   875                     private String getMessage(String aTitle, String aAppName,
       
   876                                               String aMsg, boolean aDetailsQuery) {
       
   877                         //String result = aTitle + "\n\n";
       
   878                         String result = "";
       
   879                         if (aAppName == null) {
       
   880                             result += aMsg;
       
   881                         } else {
       
   882                             result += aAppName + "\n\n" + aMsg;
       
   883                         }
       
   884                         if (aDetailsQuery) {
       
   885                             result += "\n\n";
       
   886                             result += InstallerUiTexts.get
       
   887                                 (InstallerUiTexts.DETAILS_QUERY);
       
   888                         }
       
   889                         return result;
       
   890                     }
       
   891                 });
       
   892 
       
   893         */
       
   894     }
       
   895 
       
   896     /**
       
   897      * Ask username and password for http authentication.
       
   898      * This method blocks until user has answered to the dialog.
       
   899      *
       
   900      * @param aUrl url for which authentication is required
       
   901      * @return Array of two strings, the first being username
       
   902      * and second being password. If username and password
       
   903      * cannot be obtained, this method returns null.
       
   904      */
       
   905     public String[] getUsernamePassword(String aUrl)
       
   906     {
       
   907         waitForUi();
       
   908         if (!isUiReady())
       
   909         {
       
   910             return null;
       
   911         }
       
   912 
       
   913         synchronized (iProgressSyncObject)
       
   914         {
       
   915             // Do not display progress bar during dialog.
       
   916             iDisplayProgress = false;
       
   917         }
       
   918         if (iUsernamePasswordView == null)
       
   919         {
       
   920             final Display display = iParent.getDisplay();
       
   921             final InstallerUiEswt self = this;
       
   922             display.syncExec(new Runnable()
       
   923             {
       
   924                 public void run()
       
   925                 {
       
   926                     iUsernamePasswordView =
       
   927                         new UsernamePasswordView(self, iDialog);
       
   928                 }
       
   929             });
       
   930         }
       
   931         iUsernamePasswordView.setAppName(iAppName);
       
   932         final String[] usernamePassword =
       
   933             iUsernamePasswordView.getUsernamePassword(aUrl);
       
   934         iUsernamePasswordView.dispose();
       
   935         iUsernamePasswordView = null;
       
   936         iDisplayProgress = true;
       
   937 
       
   938         if (usernamePassword != null)
       
   939         {
       
   940             log("Username: " + usernamePassword[0]);
       
   941             // Do not write confidential information (password) to log.
       
   942             //log("Password: " + usernamePassword[1]);
       
   943         }
       
   944         else
       
   945         {
       
   946             log("No username and password provided");
       
   947         }
       
   948         return usernamePassword;
       
   949     }
       
   950 
       
   951     /**
       
   952      * Asks from the user if the installed application should be launched.
       
   953      *
       
   954      * @param aLaunchAppInfo Information about application that can
       
   955      * be launched. Unless the user cancels the query,
       
   956      * this data will be filled in with user's answer upon return.
       
   957      * @return true if the user has chosen to launch the application,
       
   958      * false if the user has canceled the query
       
   959      */
       
   960     public boolean launchAppQuery(LaunchAppInfo aLaunchAppInfo)
       
   961     {
       
   962         waitForUi();
       
   963         if (!isUiReady() || iConfirmationsCanceled)
       
   964         {
       
   965             // Either UI is not yet ready, or user has cancelled
       
   966             // installation, in both cases do nothing.
       
   967             return false;
       
   968         }
       
   969 
       
   970         if (iLaunchAppQueryView == null)
       
   971         {
       
   972             final Display display = iParent.getDisplay();
       
   973             final InstallerUiEswt self = this;
       
   974             display.syncExec
       
   975             (new Runnable()
       
   976             {
       
   977                 public void run()
       
   978                 {
       
   979                     iLaunchAppQueryView =
       
   980                         new LaunchAppQueryView(self, iDialog);
       
   981                 }
       
   982             });
       
   983         }
       
   984 
       
   985         boolean result = iLaunchAppQueryView.launchAppQuery(aLaunchAppInfo);
       
   986         iParent.getDisplay().syncExec
       
   987         (new Runnable()
       
   988         {
       
   989             public void run()
       
   990             {
       
   991                 iParent.dispose();
       
   992             }
       
   993         });
       
   994         iLaunchAppQueryView = null;
       
   995         log("LaunchAppQuery returns " + result + " for " + aLaunchAppInfo);
       
   996         return result;
       
   997     }
       
   998 
       
   999     /**
       
  1000      * Returns string title basing on mode of this InstallerUi.
       
  1001      */
       
  1002     protected String getTitle()
       
  1003     {
       
  1004         String result = null;
       
  1005         if (iMode == MODE_INSTALL)
       
  1006         {
       
  1007             result = InstallerUiTexts.get(InstallerUiTexts.INSTALLING);
       
  1008         }
       
  1009         else if (iMode == MODE_UNINSTALL)
       
  1010         {
       
  1011             result = InstallerUiTexts.get(InstallerUiTexts.UNINSTALLING);
       
  1012         }
       
  1013         else if (iMode == MODE_APP_CONVERSION)
       
  1014         {
       
  1015             result = InstallerUiTexts.get(
       
  1016                          InstallerUiTexts.APP_CONVERSION_PROGRESS,
       
  1017                          new Object[] { new Integer(iAppConversionCurrent),
       
  1018                                         new Integer(iAppConversionTotal)
       
  1019                                       });
       
  1020         }
       
  1021         return result;
       
  1022     }
       
  1023 
       
  1024     /**
       
  1025      * Returns icon for indicating identified or unidentified application.
       
  1026      *
       
  1027      * @param aDisplay display to which the icon will be added
       
  1028      * @param aIdentified if true returns icon for identified application,
       
  1029      * otherwise returns icon for unidentified application
       
  1030      * @return icon for identified or unidentified application, or null
       
  1031      * if icon cannot be loaded
       
  1032      */
       
  1033     protected Image getSecurityIcon(Display aDisplay, boolean aIdentified)
       
  1034     {
       
  1035         if (iSecurityIcon != null)
       
  1036         {
       
  1037             return iSecurityIcon;
       
  1038         }
       
  1039         String iconFilename = ResourceUtil.UNTRUSTED_ICON_NAME;
       
  1040         if (aIdentified)
       
  1041         {
       
  1042             iconFilename = ResourceUtil.TRUSTED_ICON_NAME;
       
  1043         }
       
  1044         String resourceDir = ResourceUtil.getResourceDir(0);
       
  1045         for (int i = 1; iSecurityIcon == null && resourceDir != null; i++)
       
  1046         {
       
  1047             iSecurityIcon = loadImage(aDisplay, resourceDir + iconFilename, false);
       
  1048             resourceDir = ResourceUtil.getResourceDir(i);
       
  1049         }
       
  1050         return iSecurityIcon;
       
  1051     }
       
  1052 
       
  1053     /**
       
  1054      * Loads image from specified InputStream. This method scales the image
       
  1055      * to optimum size.
       
  1056      *
       
  1057      * @param aDisplay display to which the icon will be added
       
  1058      * @param aInputStream InputStream where the image is loaded
       
  1059      * @param aImageName name of the image to be loaded
       
  1060      * @return image from InputStream or null if image cannot be loaded
       
  1061      */
       
  1062     protected static Image loadImage(
       
  1063         Display aDisplay, InputStream aInputStream, String aImageName)
       
  1064     {
       
  1065         return loadImage(aDisplay, aInputStream, aImageName, true);
       
  1066     }
       
  1067 
       
  1068     /**
       
  1069      * Loads image from specified file.
       
  1070      *
       
  1071      * @param aDisplay display to which the icon will be added
       
  1072      * @param aImageFilename name of the image file to be loaded
       
  1073      * @param aScaleImage flag telling if the loaded image should be scaled
       
  1074      * @return image from file or null if image cannot be loaded
       
  1075      */
       
  1076     private static Image loadImage(
       
  1077         Display aDisplay, String aImageFilename, boolean aScaleImage)
       
  1078     {
       
  1079         Image result = null;
       
  1080         InputStream imageInputStream = null;
       
  1081         try
       
  1082         {
       
  1083             FileUtility imageFile = new FileUtility(aImageFilename);
       
  1084             if (imageFile.exists())
       
  1085             {
       
  1086                 imageInputStream = imageFile.openInputStream();
       
  1087                 result = loadImage(aDisplay, imageInputStream,
       
  1088                                    aImageFilename, aScaleImage);
       
  1089             }
       
  1090         }
       
  1091         catch (IOException ioe)
       
  1092         {
       
  1093             log("Can not get InputStream for " + aImageFilename + ": " + ioe);
       
  1094         }
       
  1095         finally
       
  1096         {
       
  1097             if (imageInputStream != null)
       
  1098             {
       
  1099                 try
       
  1100                 {
       
  1101                     imageInputStream.close();
       
  1102                     imageInputStream = null;
       
  1103                 }
       
  1104                 catch (IOException ioe)
       
  1105                 {
       
  1106                     logError("Closing image InputStream failed", ioe);
       
  1107                 }
       
  1108             }
       
  1109         }
       
  1110         return result;
       
  1111     }
       
  1112 
       
  1113     /**
       
  1114      * Loads image from specified InputStream.
       
  1115      *
       
  1116      * @param aDisplay display to which the icon will be added
       
  1117      * @param aInputStream InputStream where the image is loaded
       
  1118      * @param aImageName name of the image to be loaded
       
  1119      * @param aScaleImage flag telling if the loaded image should be scaled
       
  1120      * @return image from InputStream or null if image cannot be loaded
       
  1121      */
       
  1122     private static Image loadImage(
       
  1123         Display aDisplay, InputStream aInputStream,
       
  1124         String aImageName, boolean aScaleImage)
       
  1125     {
       
  1126         Image result = null;
       
  1127         if (aImageName != null)
       
  1128         {
       
  1129             result = (Image)iImageTable.get(aImageName);
       
  1130         }
       
  1131         if (result != null)
       
  1132         {
       
  1133             log("Using already loaded image " + aImageName);
       
  1134             return result;
       
  1135         }
       
  1136         try
       
  1137         {
       
  1138             long startTime = System.currentTimeMillis();
       
  1139             ImageData[] imageDatas = new ImageLoader().load(aInputStream);
       
  1140             ImageData imageData = imageDatas[0];
       
  1141             if (aScaleImage)
       
  1142             {
       
  1143                 Point bestSize = getBestImageSize(
       
  1144                                      imageData.width, imageData.height);
       
  1145                 if (bestSize.x != imageData.width ||
       
  1146                         bestSize.y != imageData.height)
       
  1147                 {
       
  1148                     imageData = imageData.scaledTo(bestSize.x, bestSize.y);
       
  1149                     log("Image " + aImageName + " scaled from " +
       
  1150                         imageDatas[0].width + "x" + imageDatas[0].height +
       
  1151                         " to " + bestSize.x + "x" + bestSize.y);
       
  1152                 }
       
  1153             }
       
  1154             result = new Image(aDisplay, imageData);
       
  1155             long endTime = System.currentTimeMillis();
       
  1156             log("Loaded image " + aImageName + " (load time " +
       
  1157                 (endTime - startTime) + " ms)");
       
  1158             iImageTable.put(aImageName, result);
       
  1159         }
       
  1160         catch (Throwable t)
       
  1161         {
       
  1162             log("Can not load image " + aImageName + ": " + t);
       
  1163             //logError("Exception while loading image " + aImageName, t);
       
  1164         }
       
  1165         return result;
       
  1166     }
       
  1167 
       
  1168     /**
       
  1169      * Determines the best image size for the image of given size.
       
  1170      */
       
  1171     private static Point getBestImageSize(int aWidth, int aHeight)
       
  1172     {
       
  1173         // Actually maximum image width and height should be obtained with
       
  1174         // org.eclipse.swt.internal.extension.DisplayExtension
       
  1175         // getBestImageWidth() and getBestImageHeight().
       
  1176         final int MAX_WIDTH = 50; // max width in pixels
       
  1177         final int MAX_HEIGHT = 50; // max height in pixels
       
  1178         Point result = new Point(aWidth, aHeight);
       
  1179         if (result.x > MAX_WIDTH || result.y > MAX_HEIGHT)
       
  1180         {
       
  1181             if (result.x >= MAX_WIDTH)
       
  1182             {
       
  1183                 result.x = MAX_WIDTH;
       
  1184                 result.y = MAX_WIDTH * aHeight / aWidth;
       
  1185             }
       
  1186             if (result.y >= MAX_HEIGHT)
       
  1187             {
       
  1188                 result.x = MAX_HEIGHT * aWidth / aHeight;
       
  1189                 result.y = MAX_HEIGHT;
       
  1190             }
       
  1191         }
       
  1192         return result;
       
  1193     }
       
  1194 
       
  1195     /** Returns true if UI has been created and can be used. */
       
  1196     protected boolean isUiReady()
       
  1197     {
       
  1198         if (iProgressView == null)
       
  1199         {
       
  1200             log("ui not ready, iProgressView is null");
       
  1201             return false;
       
  1202         }
       
  1203         if (iProgressView.isDisposed())
       
  1204         {
       
  1205             log("ui not ready, iProgressView is disposed");
       
  1206             return false;
       
  1207         }
       
  1208         return true;
       
  1209     }
       
  1210 
       
  1211     /**
       
  1212      * Blocks until UI has became ready.
       
  1213      */
       
  1214     private void waitForUi()
       
  1215     {
       
  1216         synchronized (iInitWaitObject)
       
  1217         {
       
  1218             try
       
  1219             {
       
  1220                 if (iUiThreadExists && iProgressView == null)
       
  1221                 {
       
  1222                     iInitWaitObject.wait();
       
  1223                 }
       
  1224             }
       
  1225             catch (InterruptedException ie)
       
  1226             {
       
  1227                 // Ignore silently.
       
  1228             }
       
  1229         }
       
  1230     }
       
  1231 
       
  1232     /**
       
  1233      * Called when screen orientation changes.
       
  1234      */
       
  1235     private void screenOrientationChanged()
       
  1236     {
       
  1237         iDefaultShellBounds = iDialog.internal_getDefaultBounds();
       
  1238 
       
  1239         if (iActiveView != null)
       
  1240         {
       
  1241             iActiveView.screenOrientationChanged();
       
  1242         }
       
  1243     }
       
  1244 
       
  1245     private static class CListener implements ControlListener
       
  1246     {
       
  1247         private InstallerUiEswt iInstallerUi = null;
       
  1248 
       
  1249         CListener(InstallerUiEswt aInstallerUi)
       
  1250         {
       
  1251             iInstallerUi = aInstallerUi;
       
  1252         }
       
  1253 
       
  1254         public void controlMoved(ControlEvent aEvent)
       
  1255         {
       
  1256         }
       
  1257 
       
  1258         public void controlResized(ControlEvent aEvent)
       
  1259         {
       
  1260             iInstallerUi.screenOrientationChanged();
       
  1261         }
       
  1262     }
       
  1263 
       
  1264     Rectangle defaultShellBounds()
       
  1265     {
       
  1266         return iDefaultShellBounds;
       
  1267     }
       
  1268 
       
  1269     Rectangle defaultShellClientBounds()
       
  1270     {
       
  1271         return iDefaultShellClientBounds;
       
  1272     }
       
  1273 
       
  1274     /** Get bold font for the current view. */
       
  1275     Font getBoldFont()
       
  1276     {
       
  1277         if (iBoldFont == null)
       
  1278         {
       
  1279             FontData[] fontDatas = iParent.getFont().getFontData();
       
  1280             FontData[] boldFontDatas = new FontData[fontDatas.length];
       
  1281             for (int i = 0; i < boldFontDatas.length; i++)
       
  1282             {
       
  1283                 boldFontDatas[i] = new FontData
       
  1284                 (fontDatas[i].getName(), fontDatas[i].getHeight()+1, SWT.BOLD);
       
  1285             }
       
  1286             iBoldFont = new Font(iParent.getDisplay(), boldFontDatas);
       
  1287         }
       
  1288         return iBoldFont;
       
  1289     }
       
  1290 
       
  1291     void setActiveView(ViewBase aView)
       
  1292     {
       
  1293         if (iActiveView != null && iActiveView != aView &&
       
  1294                 !iActiveView.isDisposed())
       
  1295         {
       
  1296             iActiveView.setVisible(false);
       
  1297         }
       
  1298         iActiveView = aView;
       
  1299     }
       
  1300 
       
  1301     ViewBase getActiveView()
       
  1302     {
       
  1303         return iActiveView;
       
  1304     }
       
  1305 }