Back to index

lightning-sunbird  0.9+nobinonly
progressui_osx.mm
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* vim:set ts=2 sw=2 sts=2 et cindent: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org code.
00017  *
00018  * The Initial Developer of the Original Code is Google Inc.
00019  * Portions created by the Initial Developer are Copyright (C) 2005
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *  Josh Aas <josh@mozillafoundation.org>
00024  *  Darin Fisher <darin@meer.net>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #import <Cocoa/Cocoa.h>
00041 #include <stdio.h>
00042 #include <unistd.h>
00043 #include "progressui.h"
00044 #include "readstrings.h"
00045 #include "errors.h"
00046 
00047 #define TIMER_INTERVAL 0.2
00048 
00049 static float sProgressVal;  // between 0 and 100
00050 static BOOL sQuit = FALSE;
00051 static StringTable sLabels;
00052 static const char *sProgramPath;
00053 
00054 @interface UpdaterUI : NSObject
00055 {
00056   IBOutlet NSProgressIndicator *progressBar;
00057   IBOutlet NSTextField *progressTextField;
00058 }
00059 @end
00060 
00061 @implementation UpdaterUI
00062 
00063 -(void)awakeFromNib
00064 {
00065   NSWindow *w = [progressBar window];
00066   [w center];
00067   
00068   [w setTitle:[NSString stringWithUTF8String:sLabels.title]];
00069   [progressTextField setStringValue:[NSString stringWithUTF8String:sLabels.info]];
00070   
00071   [progressBar setIndeterminate:NO];
00072   [progressBar setDoubleValue:0.0];
00073   
00074   [[NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self
00075                                   selector:@selector(updateProgressUI:)
00076                                   userInfo:nil repeats:YES] retain];
00077 
00078   // Make sure we are on top initially
00079   [NSApp activateIgnoringOtherApps:YES];
00080 }
00081 
00082 // called when the timer goes off
00083 -(void)updateProgressUI:(NSTimer *)aTimer
00084 {
00085   if (sQuit) {
00086     [aTimer invalidate];
00087     [aTimer release];
00088 
00089     // It seems to be necessary to activate and hide ourselves before we stop,
00090     // otherwise the "run" method will not return until the user focuses some
00091     // other app.  The activate step is necessary if we are not the active app.
00092     // This is a big hack, but it seems to do the trick.
00093     [NSApp activateIgnoringOtherApps:YES];
00094     [NSApp hide:self];
00095     [NSApp stop:self];
00096   }
00097   
00098   float progress = sProgressVal;
00099   
00100   [progressBar setDoubleValue:(double)progress];
00101 }
00102 
00103 // leave this as returning a BOOL instead of NSApplicationTerminateReply
00104 // for backward compatibility
00105 - (BOOL)applicationShouldTerminate:(NSApplication *)sender
00106 {
00107   return sQuit;
00108 }
00109 
00110 @end
00111 
00112 int
00113 InitProgressUI(int *pargc, char ***pargv)
00114 {
00115   sProgramPath = (*pargv)[0];
00116   
00117   return 0;
00118 }
00119 
00120 int
00121 ShowProgressUI()
00122 {
00123   // Only show the Progress UI if the process is taking significant time.
00124   // Here we measure significant time as taking more than one second.
00125   
00126   usleep(500000);
00127   
00128   if (sQuit || sProgressVal > 50.0f)
00129     return 0;
00130 
00131   char path[PATH_MAX];
00132   snprintf(path, sizeof(path), "%s.ini", sProgramPath);
00133   if (ReadStrings(path, &sLabels) != OK)
00134     return -1;
00135   
00136   [NSApplication sharedApplication];
00137   [NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
00138   [NSApp run];
00139 
00140   return 0;
00141 }
00142 
00143 // Called on a background thread
00144 void
00145 QuitProgressUI()
00146 {
00147   sQuit = TRUE;
00148 }
00149 
00150 // Called on a background thread
00151 void
00152 UpdateProgressUI(float progress)
00153 {
00154   sProgressVal = progress;  // 32-bit writes are atomic
00155 }