~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/embedding/browser/powerplant/source/CBrowserApp.cp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 
2
 *
 
3
 * The contents of this file are subject to the Mozilla Public
 
4
 * License Version 1.1 (the "License"); you may not use this file
 
5
 * except in compliance with the License. You may obtain a copy of
 
6
 * the License at http://www.mozilla.org/MPL/
 
7
 * 
 
8
 * Software distributed under the License is distributed on an "AS
 
9
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
10
 * implied. See the License for the specific language governing
 
11
 * rights and limitations under the License.
 
12
 * 
 
13
 * The Original Code is the Mozilla browser.
 
14
 * 
 
15
 * The Initial Developer of the Original Code is Netscape
 
16
 * Communications, Inc.  Portions created by Netscape are
 
17
 * Copyright (C) 1999, Mozilla.  All Rights Reserved.
 
18
 * 
 
19
 * Contributor(s):
 
20
 *   Conrad Carlen <ccarlen@netscape.com>
 
21
 */
 
22
 
 
23
#include "CBrowserApp.h"
 
24
 
 
25
#include <PP_Messages.h>
 
26
#include <PP_Resources.h>
 
27
#include <UDrawingState.h>
 
28
#include <UMemoryMgr.h>
 
29
#include <URegistrar.h>
 
30
#include <LPushButton.h>
 
31
#include <LStaticText.h>
 
32
#include <LIconControl.h>
 
33
#include <LWindow.h>
 
34
#include <LTextTableView.h>
 
35
#include <UControlRegistry.h>
 
36
#include <UGraphicUtils.h>
 
37
#include <UEnvironment.h>
 
38
#include <Appearance.h>
 
39
#include <LCMAttachment.h>
 
40
#include <UCMMUtils.h>
 
41
#include <UNavServicesDialogs.h>
 
42
 
 
43
#include "ApplIDs.h"
 
44
#include "CBrowserWindow.h"
 
45
#include "CBrowserShell.h"
 
46
#include "CBrowserChrome.h"
 
47
#include "CWindowCreator.h"
 
48
#include "CUrlField.h"
 
49
#include "CThrobber.h"
 
50
#include "CIconServicesIcon.h"
 
51
#include "CWebBrowserCMAttachment.h"
 
52
#include "UMacUnicode.h"
 
53
#include "CAppFileLocationProvider.h"
 
54
#include "EmbedEventHandling.h"
 
55
#include "AppComponents.h"
 
56
 
 
57
#include "nsEmbedAPI.h"
 
58
 
 
59
#include "nsIComponentRegistrar.h"
 
60
#include "nsIDirectoryService.h"
 
61
#include "nsDirectoryServiceDefs.h"
 
62
#include "nsAppDirectoryServiceDefs.h"
 
63
#include "nsIObserverService.h"
 
64
#include "nsObserverService.h"
 
65
#include "nsIPref.h"
 
66
#include "nsRepeater.h"
 
67
#include "nsILocalFile.h"
 
68
#include "nsILocalFileMac.h"
 
69
#include "nsIFileChannel.h"
 
70
#include "nsXPIDLString.h"
 
71
#include "nsReadableUtils.h"
 
72
#include "nsNetUtil.h"
 
73
#include "nsIWindowWatcher.h"
 
74
#include "nsIDOMWindow.h"
 
75
#include "nsIDownload.h"
 
76
#include "nsCRT.h"
 
77
 
 
78
#if defined(__MWERKS__) && !defined(__MACH__)
 
79
#include "macstdlibextras.h"
 
80
#include "SIOUX.h"
 
81
#endif
 
82
 
 
83
#include <TextServices.h>
 
84
 
 
85
#ifdef USE_PROFILES
 
86
#include "CProfileManager.h"
 
87
#include "nsIProfileChangeStatus.h"
 
88
#else
 
89
#include "nsProfileDirServiceProvider.h"
 
90
#endif
 
91
 
 
92
#ifdef SHARED_PROFILE
 
93
#include "nsIProfileSharingSetup.h"
 
94
#define kAppDataFolderName NS_LITERAL_STRING("PPEmbed Suite")
 
95
#else
 
96
#define kAppDataFolderName NS_LITERAL_STRING("PPEmbed")
 
97
#endif
 
98
 
 
99
// ===========================================================================
 
100
//      ļæ½ Main Program
 
101
// ===========================================================================
 
102
 
 
103
int main()
 
104
{
 
105
                                
 
106
    SetDebugThrow_(PP_PowerPlant::debugAction_Alert);   // Set Debugging options
 
107
    SetDebugSignal_(PP_PowerPlant::debugAction_Alert);
 
108
 
 
109
#ifdef POWERPLANT_IS_FRAMEWORK
 
110
    // A framework's Resource Mgr resources must be opened explicitly.
 
111
    CFBundleRef powerplantBundle = ::CFBundleGetBundleWithIdentifier(
 
112
                                      CFSTR("org.mozilla.PowerPlant"));
 
113
    SInt16 powerPlantResRefNum = -1;
 
114
    if (powerplantBundle) {
 
115
      powerPlantResRefNum = ::CFBundleOpenBundleResourceMap(powerplantBundle);
 
116
      ::CFRelease(powerplantBundle);
 
117
    }
 
118
#endif
 
119
 
 
120
    PP_PowerPlant::InitializeHeap(3);       // Initialize Memory Manager
 
121
                                            // Parameter is number of Master Pointer
 
122
                                            // blocks to allocate
 
123
    
 
124
    PP_PowerPlant::UQDGlobals::InitializeToolbox();
 
125
    
 
126
#if defined(__MWERKS__) && !TARGET_CARBON
 
127
    ::InitializeSIOUX(false);
 
128
#endif
 
129
 
 
130
#if !TARGET_CARBON
 
131
    new PP_PowerPlant::LGrowZone(20000);    // Install a GrowZone function to catch low memory situations.      
 
132
    ::InitTSMAwareApplication();
 
133
#endif
 
134
    
 
135
    {
 
136
        CBrowserApp theApp;         // create instance of your application
 
137
        theApp.Run();
 
138
    }
 
139
 
 
140
#if !TARGET_CARBON  
 
141
    ::CloseTSMAwareApplication();
 
142
#endif
 
143
    
 
144
    return 0;
 
145
}
 
146
 
 
147
 
 
148
// ===========================================================================
 
149
//  class CStartupTask
 
150
// 
 
151
//  A one-shot repeater which calls the application method to handle startup.
 
152
// ===========================================================================
 
153
 
 
154
class CStartUpTask : public LPeriodical
 
155
{
 
156
public:
 
157
    CStartUpTask(CBrowserApp *aBrowserApp) :
 
158
        mBrowserApp(aBrowserApp)
 
159
    {
 
160
        StartRepeating();
 
161
    }
 
162
    
 
163
    ~CStartUpTask() { }
 
164
    
 
165
    void SpendTime(const EventRecord& inMacEvent)
 
166
    {
 
167
        StopRepeating();
 
168
        mBrowserApp->OnStartUp();
 
169
        delete this;
 
170
    }
 
171
private:
 
172
    CBrowserApp     *mBrowserApp;
 
173
};
 
174
 
 
175
// ---------------------------------------------------------------------------
 
176
//      ļæ½ CBrowserApp
 
177
// ---------------------------------------------------------------------------
 
178
//  Constructor
 
179
 
 
180
CBrowserApp::CBrowserApp()
 
181
{
 
182
 
 
183
#ifdef USE_PROFILES
 
184
    mRefCnt = 1;
 
185
#else
 
186
    mProfDirServiceProvider = nsnull;
 
187
#endif
 
188
 
 
189
#if TARGET_CARBON
 
190
    InstallCarbonEventHandlers();
 
191
#endif
 
192
 
 
193
    if ( PP_PowerPlant::UEnvironment::HasFeature( PP_PowerPlant::env_HasAppearance ) ) {
 
194
        ::RegisterAppearanceClient();
 
195
    }
 
196
 
 
197
    RegisterClass_(PP_PowerPlant::LWindow); // You must register each kind of
 
198
    RegisterClass_(PP_PowerPlant::LCaption);    // PowerPlant classes that you use in your PPob resource.
 
199
    RegisterClass_(PP_PowerPlant::LTabGroupView);
 
200
    RegisterClass_(PP_PowerPlant::LIconControl);
 
201
    RegisterClass_(PP_PowerPlant::LView);
 
202
    RegisterClass_(PP_PowerPlant::LDialogBox);
 
203
    
 
204
    // Register the Appearance Manager/GA classes
 
205
    PP_PowerPlant::UControlRegistry::RegisterClasses();
 
206
    
 
207
    // QuickTime is used by CThrobber
 
208
    UQuickTime::Initialize();
 
209
    
 
210
    // Register classes used by embedding
 
211
    RegisterClass_(CBrowserShell);
 
212
    RegisterClass_(CBrowserWindow);
 
213
    RegisterClass_(CUrlField);
 
214
    RegisterClass_(CThrobber);
 
215
    RegisterClass_(CIconServicesIcon);
 
216
 
 
217
#ifdef USE_PROFILES 
 
218
    RegisterClass_(LScroller);
 
219
    RegisterClass_(LTextTableView);
 
220
    RegisterClass_(LColorEraseAttachment);
 
221
#endif
 
222
 
 
223
   // Contexual Menu Support
 
224
   UCMMUtils::Initialize();
 
225
   RegisterClass_(LCMAttachment);
 
226
   RegisterClass_(CWebBrowserCMAttachment);
 
227
   AddAttachment(new LCMAttachment);
 
228
 
 
229
   SetSleepTime(5);
 
230
    
 
231
   // Get the directory which contains the mozilla parts
 
232
   // In this case it is the app directory but it could
 
233
   // be anywhere (an existing install of mozilla)
 
234
 
 
235
   nsresult        rv;
 
236
   ProcessSerialNumber psn;
 
237
   ProcessInfoRec  processInfo;
 
238
   FSSpec          appSpec;
 
239
   nsCOMPtr<nsILocalFileMac> macDir;
 
240
 
 
241
   if (!::GetCurrentProcess(&psn)) {
 
242
      processInfo.processInfoLength = sizeof(processInfo);
 
243
      processInfo.processName = NULL;
 
244
      processInfo.processAppSpec = &appSpec;    
 
245
      if (!::GetProcessInformation(&psn, &processInfo)) {
 
246
         // Turn the FSSpec of the app into an FSSpec of the app's directory
 
247
         OSErr err = ::FSMakeFSSpec(appSpec.vRefNum, appSpec.parID, "\p", &appSpec);
 
248
         // Make an nsILocalFile out of it
 
249
         if (err == noErr)
 
250
            (void)NS_NewLocalFileWithFSSpec(&appSpec, PR_TRUE, getter_AddRefs(macDir));
 
251
      }
 
252
   }
 
253
   
 
254
   CAppFileLocationProvider *fileLocProvider = new CAppFileLocationProvider(kAppDataFolderName);
 
255
   ThrowIfNil_(fileLocProvider);
 
256
 
 
257
   rv = NS_InitEmbedding(macDir, fileLocProvider);
 
258
 
 
259
   OverrideComponents();
 
260
   CWindowCreator::Initialize();
 
261
   InitializeEmbedEventHandling(this);
 
262
}
 
263
 
 
264
// ---------------------------------------------------------------------------
 
265
//      ļæ½ ~CBrowserApp
 
266
// ---------------------------------------------------------------------------
 
267
//  Destructor
 
268
//
 
269
 
 
270
CBrowserApp::~CBrowserApp()
 
271
{
 
272
#ifdef USE_PROFILES    
 
273
    nsCOMPtr<nsIProfile> profileService = 
 
274
        do_GetService(NS_PROFILE_CONTRACTID, &rv);
 
275
    if (profileService)
 
276
      profileService->ShutDownCurrentProfile(nsIProfile::SHUTDOWN_PERSIST);
 
277
#else
 
278
    if (mProfDirServiceProvider) {
 
279
      mProfDirServiceProvider->Shutdown();
 
280
      NS_RELEASE(mProfDirServiceProvider);
 
281
    }
 
282
#endif
 
283
 
 
284
   NS_TermEmbedding();
 
285
}
 
286
 
 
287
nsresult
 
288
CBrowserApp::OverrideComponents()
 
289
{
 
290
    nsresult rv = NS_OK;
 
291
 
 
292
    nsCOMPtr<nsIComponentRegistrar> cr;
 
293
    NS_GetComponentRegistrar(getter_AddRefs(cr));
 
294
    if (!cr)
 
295
        return NS_ERROR_FAILURE;
 
296
 
 
297
    int numComponents;
 
298
    const nsModuleComponentInfo* componentInfo = GetAppModuleComponentInfo(&numComponents);
 
299
    for (int i = 0; i < numComponents; ++i) {
 
300
        nsCOMPtr<nsIGenericFactory> componentFactory;
 
301
        rv = NS_NewGenericFactory(getter_AddRefs(componentFactory), &(componentInfo[i]));
 
302
            if (NS_FAILED(rv)) {
 
303
            NS_ASSERTION(PR_FALSE, "Unable to create factory for component");
 
304
            continue;
 
305
        }
 
306
 
 
307
        rv = cr->RegisterFactory(componentInfo[i].mCID,
 
308
                             componentInfo[i].mDescription,
 
309
                             componentInfo[i].mContractID,
 
310
                             componentFactory);
 
311
        NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to register factory for component");
 
312
    }
 
313
 
 
314
    return rv;
 
315
}
 
316
 
 
317
 
 
318
// ---------------------------------------------------------------------------
 
319
//      ļæ½ MakeMenuBar
 
320
// ---------------------------------------------------------------------------
 
321
 
 
322
void
 
323
CBrowserApp::MakeMenuBar()
 
324
{
 
325
    LApplication::MakeMenuBar();
 
326
    
 
327
    // Insert a menu which is not in the menu bar but which contains
 
328
    // items which appear only in contextual menus. We have to do this hack
 
329
    // because LCMAttachment::AddCommand needs a command which is in
 
330
    // some LMenu in order to get the text for a contextual menu item.
 
331
    
 
332
    LMenuBar::GetCurrentMenuBar()->InstallMenu(new LMenu(menu_Buzzwords), hierMenu);
 
333
}
 
334
 
 
335
// ---------------------------------------------------------------------------
 
336
//      ļæ½ Initialize
 
337
// ---------------------------------------------------------------------------
 
338
//  Initializes profile manager or directory service provider. If the user has
 
339
//  chosen to be prompted to choose a profile at startup so the profile dialog
 
340
//  appears and they cancel from that dialog, startup will terminate.
 
341
 
 
342
void
 
343
CBrowserApp::Initialize()
 
344
{
 
345
    nsresult rv;
 
346
 
 
347
#ifdef SHARED_PROFILE    
 
348
    CFBundleRef appBundle = CFBundleGetMainBundle();
 
349
    ThrowIfNil_(appBundle);
 
350
 
 
351
    nsAutoString suiteMemberStr;
 
352
    // We don't get an owning reference here, so no CFRelease.
 
353
    CFStringRef bundleStrRef = (CFStringRef)CFBundleGetValueForInfoDictionaryKey(
 
354
                                appBundle, CFSTR("ProfilesSuiteMemberName"));
 
355
                                
 
356
    if (bundleStrRef && (CFGetTypeID(bundleStrRef) == CFStringGetTypeID())) {
 
357
        UniChar buffer[256];
 
358
        CFIndex strLen = CFStringGetLength(bundleStrRef);
 
359
        ThrowIf_(strLen >= (sizeof(buffer) / sizeof(buffer[0])));
 
360
        CFStringGetCharacters(bundleStrRef, CFRangeMake(0, strLen), buffer);
 
361
        buffer[strLen] = 0;
 
362
        suiteMemberStr.Assign(static_cast<PRUnichar*>(buffer));
 
363
    }
 
364
    ThrowIf_(suiteMemberStr.IsEmpty());
 
365
    
 
366
    nsCOMPtr<nsIProfileSharingSetup> sharingSetup =
 
367
        do_GetService("@mozilla.org/embedcomp/profile-sharing-setup;1");
 
368
    ThrowIfNil_(sharingSetup);
 
369
    rv = sharingSetup->EnableSharing(suiteMemberStr);
 
370
    ThrowIfError_(rv);
 
371
#endif
 
372
        
 
373
#ifdef USE_PROFILES
 
374
 
 
375
    // Register for profile changes    
 
376
    nsCOMPtr<nsIObserverService> observerService = 
 
377
             do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
 
378
    ThrowIfNil_(observerService);
 
379
    observerService->AddObserver(this, "profile-approve-change", PR_FALSE);
 
380
    observerService->AddObserver(this, "profile-change-teardown", PR_FALSE);
 
381
    observerService->AddObserver(this, "profile-after-change", PR_FALSE);
 
382
 
 
383
    CProfileManager *profileMgr = new CProfileManager;
 
384
    profileMgr->StartUp();
 
385
    AddAttachment(profileMgr);
 
386
 
 
387
#else
 
388
    
 
389
    // If we don't want different user profiles, all that's needed is
 
390
    // to make an nsProfileDirServiceProvider. This will provide the same file
 
391
    // locations as the profile service but always within the specified folder.
 
392
    
 
393
    nsCOMPtr<nsIFile> appDataDir;
 
394
    rv = NS_GetSpecialDirectory(NS_APP_APPLICATION_REGISTRY_DIR, getter_AddRefs(appDataDir));
 
395
    ThrowIfNil_(appDataDir);
 
396
    
 
397
    nsCOMPtr<nsProfileDirServiceProvider> profDirServiceProvider;
 
398
    NS_NewProfileDirServiceProvider(PR_TRUE, getter_AddRefs(profDirServiceProvider));
 
399
    ThrowIfNil_(profDirServiceProvider);
 
400
    rv = profDirServiceProvider->Register();
 
401
    ThrowIfError_(rv);
 
402
    
 
403
    nsCOMPtr<nsILocalFile> localAppDataDir(do_QueryInterface(appDataDir));
 
404
    rv = profDirServiceProvider->SetProfileDir(localAppDataDir);
 
405
    ThrowIfError_(rv);
 
406
    NS_ADDREF(mProfDirServiceProvider = profDirServiceProvider);
 
407
#endif
 
408
 
 
409
    // Now that we know profile selection wasn't canceled and we're gonna run...
 
410
    CStartUpTask *startupTask = new CStartUpTask(this);
 
411
}
 
412
 
 
413
// ---------------------------------------------------------------------------
 
414
//  ļæ½ AdjustCursor                                                    [public]
 
415
// ---------------------------------------------------------------------------
 
416
 
 
417
void CBrowserApp::AdjustCursor(const EventRecord& inMacEvent)
 
418
{
 
419
  // Needed in order to give an attachment to the application a
 
420
  // msg_AdjustCursor. CEmbedEventAttachment needs this.
 
421
  
 
422
  if (ExecuteAttachments(msg_AdjustCursor, (void*) &inMacEvent))
 
423
      LEventDispatcher::AdjustCursor(inMacEvent);
 
424
}
 
425
 
 
426
 
 
427
// ---------------------------------------------------------------------------
 
428
//  ļæ½ HandleAppleEvent                                                [public]
 
429
// ---------------------------------------------------------------------------
 
430
 
 
431
void CBrowserApp::HandleAppleEvent(const AppleEvent&    inAppleEvent,
 
432
                                   AppleEvent&          outAEReply,
 
433
                                   AEDesc&              outResult,
 
434
                                   long                 inAENumber)
 
435
{
 
436
    switch (inAENumber) {
 
437
    
 
438
        case 5000:
 
439
            {
 
440
                OSErr err;
 
441
                
 
442
                StAEDescriptor urlDesc;
 
443
                err = ::AEGetParamDesc(&inAppleEvent, keyDirectObject, typeChar, urlDesc);
 
444
                ThrowIfOSErr_(err);
 
445
                    
 
446
                Size dataSize = ::AEGetDescDataSize(urlDesc);
 
447
                StPointerBlock urlPtr(dataSize);
 
448
                err = ::AEGetDescData(urlDesc, urlPtr.Get(), dataSize);
 
449
                ThrowIfOSErr_(err);
 
450
 
 
451
                const nsACString& urlAsStr = Substring(urlPtr.Get(), urlPtr.Get() + dataSize);
 
452
                
 
453
                // If the URL begins with "view-source:", go with less chrome
 
454
                PRUint32 chromeFlags;
 
455
                NS_NAMED_LITERAL_CSTRING(kViewSourceProto, "view-source:");
 
456
                if (Substring(urlAsStr, 0, kViewSourceProto.Length()).Equals(kViewSourceProto))
 
457
                    chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_CLOSE +
 
458
                                  nsIWebBrowserChrome::CHROME_WINDOW_RESIZE;
 
459
                else
 
460
                    chromeFlags = nsIWebBrowserChrome::CHROME_DEFAULT;
 
461
                                                
 
462
                // See if we have a referrer
 
463
                nsCAutoString referrerAsStr;
 
464
                StAEDescriptor referrerDesc;
 
465
                err = ::AEGetParamDesc(&inAppleEvent, keyGetURLReferrer, typeChar, referrerDesc);
 
466
                if (err == noErr) {
 
467
                    dataSize = ::AEGetDescDataSize(referrerDesc);
 
468
                    StPointerBlock referrerPtr(dataSize);
 
469
                    err = ::AEGetDescData(referrerDesc, referrerPtr.Get(), dataSize);
 
470
                    ThrowIfOSErr_(err);
 
471
                    referrerAsStr = Substring(referrerPtr.Get(), referrerPtr.Get() + dataSize);
 
472
                }           
 
473
                LWindow *theWindow = CWindowCreator::CreateWindowInternal(chromeFlags, PR_TRUE, -1, -1);
 
474
                ThrowIfNil_(theWindow);
 
475
                CBrowserShell *theBrowser = dynamic_cast<CBrowserShell*>(theWindow->FindPaneByID(CBrowserShell::paneID_MainBrowser));
 
476
                ThrowIfNil_(theBrowser);
 
477
                theBrowser->LoadURL(urlAsStr, referrerAsStr);
 
478
                                
 
479
                theWindow->Show();
 
480
            }
 
481
            break;
 
482
            
 
483
        case ae_ApplicationDied: // We get these from opening downloaded files with Stuffit - ignore.
 
484
            break;
 
485
            
 
486
        default:
 
487
            LApplication::HandleAppleEvent(inAppleEvent, outAEReply, outResult, inAENumber);
 
488
    }
 
489
}
 
490
 
 
491
 
 
492
// ---------------------------------------------------------------------------
 
493
//      ļæ½ ObeyCommand
 
494
// ---------------------------------------------------------------------------
 
495
//  This method lets the application respond to commands like Menu commands
 
496
 
 
497
Boolean
 
498
CBrowserApp::ObeyCommand(
 
499
    PP_PowerPlant::CommandT inCommand,
 
500
    void                    *ioParam)
 
501
{
 
502
    Boolean     cmdHandled = true;
 
503
 
 
504
    switch (inCommand) {
 
505
    
 
506
        case PP_PowerPlant::cmd_About:
 
507
      break;
 
508
        
 
509
        case PP_PowerPlant::cmd_New:
 
510
            {           
 
511
                LWindow *theWindow = CWindowCreator::CreateWindowInternal(nsIWebBrowserChrome::CHROME_DEFAULT, PR_TRUE, -1, -1);
 
512
                ThrowIfNil_(theWindow);
 
513
                CBrowserShell *theBrowser = dynamic_cast<CBrowserShell*>(theWindow->FindPaneByID(CBrowserShell::paneID_MainBrowser));
 
514
                ThrowIfNil_(theBrowser);
 
515
                // Just for demo sake, load a URL
 
516
                theBrowser->LoadURL(nsDependentCString("http://www.mozilla.org"));
 
517
                theWindow->Show();
 
518
            }
 
519
            break;
 
520
 
 
521
        case PP_PowerPlant::cmd_Open:
 
522
        case cmd_OpenDirectory:
 
523
            {
 
524
                FSSpec fileSpec;
 
525
                if (SelectFileObject(inCommand, fileSpec))
 
526
                {
 
527
                    nsresult rv;
 
528
                    nsCOMPtr<nsILocalFileMac> macFile;
 
529
                    
 
530
                    rv = NS_NewLocalFileWithFSSpec(&fileSpec, PR_TRUE, getter_AddRefs(macFile));
 
531
                    ThrowIfError_(NS_ERROR_GET_CODE(rv));
 
532
 
 
533
                    nsCAutoString urlSpec;                    
 
534
                    rv = NS_GetURLSpecFromFile(macFile, urlSpec);
 
535
                    ThrowIfError_(NS_ERROR_GET_CODE(rv));
 
536
                                            
 
537
                    LWindow *theWindow = CWindowCreator::CreateWindowInternal(nsIWebBrowserChrome::CHROME_DEFAULT, PR_TRUE, -1, -1);
 
538
                    ThrowIfNil_(theWindow);
 
539
                    CBrowserShell *theBrowser = dynamic_cast<CBrowserShell*>(theWindow->FindPaneByID(CBrowserShell::paneID_MainBrowser));
 
540
                    ThrowIfNil_(theBrowser);
 
541
                    theBrowser->LoadURL(urlSpec);
 
542
                    theWindow->Show();
 
543
                }
 
544
            }
 
545
            break;
 
546
 
 
547
        case PP_PowerPlant::cmd_Preferences:
 
548
        {
 
549
            nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
 
550
            ThrowIfNil_(wwatch);
 
551
                
 
552
            // Note: We're not making this window modal even though it looks like a modal
 
553
            // dialog (has OK and Cancel buttons). Reason is, the help window which can
 
554
            // be opened from the prefs dialog is non-modal. If the prefs dialog was modal,
 
555
            // the help window would be stuck behind it in the non-modal layer.
 
556
            
 
557
            // And, since its non-modal, we have to check for an already open prefs window
 
558
            // and just select it rather than making a new one.
 
559
            nsCOMPtr<nsIDOMWindow> extantPrefsWindow;
 
560
            wwatch->GetWindowByName(NS_LITERAL_STRING("_prefs").get(), nsnull, getter_AddRefs(extantPrefsWindow));
 
561
            if (extantPrefsWindow) {
 
562
                // activate the window
 
563
                LWindow *extantPrefsLWindow = CBrowserChrome::GetLWindowForDOMWindow(extantPrefsWindow);
 
564
                ThrowIfNil_(extantPrefsLWindow);
 
565
                extantPrefsLWindow->Select();
 
566
            }
 
567
            else {
 
568
                nsCOMPtr<nsIDOMWindow> domWindow;
 
569
                wwatch->OpenWindow(nsnull,
 
570
                                  "chrome://communicator/content/pref/pref.xul",
 
571
                                  "_prefs",
 
572
                                  "centerscreen,chrome,dialog,titlebar",
 
573
                                  nsnull,
 
574
                                  getter_AddRefs(domWindow));
 
575
            }
 
576
        }
 
577
        break;
 
578
 
 
579
        // Any that you don't handle, such as cmd_About and cmd_Quit,
 
580
        // will be passed up to LApplication
 
581
        default:
 
582
            cmdHandled = PP_PowerPlant::LApplication::ObeyCommand(inCommand, ioParam);
 
583
            break;
 
584
    }
 
585
    
 
586
    return cmdHandled;
 
587
}
 
588
 
 
589
// ---------------------------------------------------------------------------
 
590
//      ļæ½ FindCommandStatus
 
591
// ---------------------------------------------------------------------------
 
592
//  This function enables menu commands.
 
593
//
 
594
 
 
595
void
 
596
CBrowserApp::FindCommandStatus(
 
597
    PP_PowerPlant::CommandT inCommand,
 
598
    Boolean                 &outEnabled,
 
599
    Boolean                 &outUsesMark,
 
600
    UInt16                  &outMark,
 
601
    Str255                  outName)
 
602
{
 
603
 
 
604
    switch (inCommand) {
 
605
    
 
606
        case PP_PowerPlant::cmd_About:
 
607
            outEnabled = false;
 
608
      break;
 
609
      
 
610
        case PP_PowerPlant::cmd_New:
 
611
            outEnabled = true;
 
612
            break;
 
613
 
 
614
        case PP_PowerPlant::cmd_Open:
 
615
        case cmd_OpenDirectory:
 
616
            outEnabled = true;
 
617
            break;
 
618
 
 
619
        case PP_PowerPlant::cmd_Preferences:
 
620
            outEnabled = true;
 
621
            break;      
 
622
 
 
623
        // Any that you don't handle, such as cmd_About and cmd_Quit,
 
624
        // will be passed up to LApplication
 
625
        default:
 
626
            PP_PowerPlant::LApplication::FindCommandStatus(inCommand, outEnabled,
 
627
                                                outUsesMark, outMark, outName);
 
628
            break;
 
629
    }
 
630
}
 
631
 
 
632
 
 
633
Boolean CBrowserApp::AttemptQuitSelf(SInt32 inSaveOption)
 
634
{       
 
635
   // IMPORTANT: This is one unfortunate thing about Powerplant - Windows don't
 
636
   // get destroyed until the destructor of LCommander. We need to delete
 
637
   // all of the CBrowserWindows though before we terminate embedding.
 
638
    
 
639
    TArrayIterator<LCommander*> iterator(mSubCommanders, LArrayIterator::from_End);
 
640
    LCommander*     theSub;
 
641
    while (iterator.Previous(theSub)) {
 
642
        if (dynamic_cast<CBrowserWindow*>(theSub)) {
 
643
            mSubCommanders.RemoveItemsAt(1, iterator.GetCurrentIndex());
 
644
            delete theSub;
 
645
        }
 
646
    }
 
647
    
 
648
   return true;
 
649
}
 
650
 
 
651
#if TARGET_CARBON
 
652
 
 
653
void CBrowserApp::InstallCarbonEventHandlers()
 
654
{
 
655
    EventTypeSpec appEventList[] = {{kEventClassCommand, kEventCommandProcess},
 
656
                                    {kEventClassCommand, kEventCommandUpdateStatus}};
 
657
 
 
658
    InstallApplicationEventHandler(NewEventHandlerUPP(AppEventHandler), 2, appEventList, this, NULL);                                    
 
659
}
 
660
 
 
661
pascal OSStatus CBrowserApp::AppEventHandler(EventHandlerCallRef aHandlerChain,
 
662
                                             EventRef event,
 
663
                                             void* userData)
 
664
{
 
665
    HICommand       command;
 
666
    OSStatus        result = eventNotHandledErr; /* report failure by default */
 
667
 
 
668
    if (::GetEventParameter(event, kEventParamDirectObject, 
 
669
                            typeHICommand, NULL, sizeof(HICommand), 
 
670
                            NULL, &command) != noErr)
 
671
        return result;
 
672
    
 
673
    switch (::GetEventKind(event))
 
674
    {
 
675
        case kEventCommandProcess:
 
676
            {
 
677
                switch (command.commandID)
 
678
                {
 
679
                    case kHICommandPreferences:
 
680
                    {
 
681
                        CBrowserApp *theApp = reinterpret_cast<CBrowserApp*>(userData);
 
682
                        theApp->ObeyCommand(PP_PowerPlant::cmd_Preferences, nsnull);
 
683
                        result = noErr;
 
684
                        break;
 
685
                    }
 
686
                    default:
 
687
                        break;
 
688
                }
 
689
            }
 
690
            break;
 
691
 
 
692
        case kEventCommandUpdateStatus:
 
693
            {
 
694
                switch (command.commandID)
 
695
                {
 
696
                    case kHICommandPreferences:
 
697
                        ::EnableMenuCommand(nsnull, kHICommandPreferences);
 
698
                        result = noErr;
 
699
                        break;
 
700
                    default:
 
701
                        break;
 
702
                }
 
703
            }
 
704
            break;
 
705
 
 
706
        default:
 
707
            break; 
 
708
    }
 
709
    return result;
 
710
}
 
711
 
 
712
#endif // TARGET_CARBON
 
713
 
 
714
nsresult CBrowserApp::InitializePrefs()
 
715
{
 
716
    nsresult rv;
 
717
    nsCOMPtr<nsIPrefService> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
 
718
    if (NS_FAILED(rv))
 
719
        return rv;    
 
720
 
 
721
    // We are using the default prefs from mozilla. If you were
 
722
    // disributing your own, this would be done simply by editing
 
723
    // the default pref files.
 
724
    nsCOMPtr<nsIPrefBranch> branch;
 
725
    rv = prefs->GetBranch(nsnull, getter_AddRefs(branch));
 
726
    if (NS_FAILED(rv))
 
727
        return rv;    
 
728
 
 
729
    const char kVariableFontSizePref[] = "font.size.variable.x-western";
 
730
    const char kFixedFontSizePref[] = "font.size.fixed.x-western";
 
731
    
 
732
    PRInt32 intValue;
 
733
    rv = branch->GetIntPref(kVariableFontSizePref, &intValue);
 
734
    if (NS_FAILED(rv))
 
735
        branch->SetIntPref(kVariableFontSizePref, 14);
 
736
        
 
737
    rv = branch->GetIntPref(kFixedFontSizePref, &intValue);    
 
738
    if (NS_FAILED(rv))
 
739
        branch->SetIntPref(kFixedFontSizePref, 13);
 
740
        
 
741
    return NS_OK;
 
742
}
 
743
 
 
744
// ---------------------------------------------------------------------------
 
745
//  CBrowserApp::DoStartUp
 
746
//
 
747
//  Called from CStartUpTask. We must use this INSTEAD of LApplication::StartUp.
 
748
//  Reason is, LApplication::StartUp happens in response to the open application AE
 
749
//  which is processed as soon as we process any events - as in while the profile
 
750
//  manager dialog is up :-/ 
 
751
// ---------------------------------------------------------------------------
 
752
 
 
753
void CBrowserApp::OnStartUp()
 
754
{
 
755
    ObeyCommand(PP_PowerPlant::cmd_New, nil);
 
756
}
 
757
 
 
758
Boolean CBrowserApp::SelectFileObject(PP_PowerPlant::CommandT   inCommand,
 
759
                                      FSSpec& outSpec)
 
760
{
 
761
    UNavServicesDialogs::LFileChooser   chooser;
 
762
    
 
763
    NavDialogOptions *theDialogOptions = chooser.GetDialogOptions();
 
764
    if (theDialogOptions) {
 
765
        theDialogOptions->dialogOptionFlags |= kNavSelectAllReadableItem;
 
766
    }
 
767
 
 
768
    Boolean     result;
 
769
    SInt32      dirID;
 
770
    
 
771
    if (inCommand == cmd_OpenDirectory)
 
772
    {
 
773
        result = chooser.AskChooseFolder(outSpec, dirID);
 
774
    }
 
775
    else
 
776
    {
 
777
        result = chooser.AskOpenFile(LFileTypeList(fileTypes_All));
 
778
        if (result)
 
779
            chooser.GetFileSpec(1, outSpec);
 
780
    }
 
781
    return result;
 
782
}
 
783
 
 
784
#ifdef USE_PROFILES
 
785
 
 
786
// ---------------------------------------------------------------------------
 
787
//  CBrowserApp : nsISupports
 
788
// ---------------------------------------------------------------------------
 
789
 
 
790
NS_IMPL_ISUPPORTS2(CBrowserApp, nsIObserver, nsISupportsWeakReference)
 
791
 
 
792
// ---------------------------------------------------------------------------
 
793
//  CBrowserApp : nsIObserver
 
794
// ---------------------------------------------------------------------------
 
795
 
 
796
NS_IMETHODIMP CBrowserApp::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
 
797
{
 
798
    #define CLOSE_WINDOWS_ON_SWITCH 1
 
799
 
 
800
    nsresult rv = NS_OK;
 
801
    
 
802
    if (!nsCRT::strcmp(aTopic, "profile-approve-change"))
 
803
    {
 
804
        // Ask the user if they want to
 
805
        DialogItemIndex item = UModalAlerts::StopAlert(alrt_ConfirmProfileSwitch);
 
806
        if (item != kStdOkItemIndex)
 
807
        {
 
808
            nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
 
809
            NS_ENSURE_TRUE(status, NS_ERROR_FAILURE);
 
810
            status->VetoChange();
 
811
        }
 
812
    }
 
813
    else if (!nsCRT::strcmp(aTopic, "profile-change-teardown"))
 
814
    {
 
815
        // Close all open windows. Alternatively, we could just call CBrowserWindow::Stop()
 
816
        // on each. Either way, we have to stop all network activity on this phase.
 
817
        
 
818
        TArrayIterator<LCommander*> iterator(mSubCommanders, LArrayIterator::from_End);
 
819
        LCommander*     theSub;
 
820
        while (iterator.Previous(theSub)) {
 
821
            CBrowserWindow *browserWindow = dynamic_cast<CBrowserWindow*>(theSub);
 
822
            if (browserWindow) {
 
823
                //browserWindow->Stop();
 
824
                mSubCommanders.RemoveItemsAt(1, iterator.GetCurrentIndex());
 
825
                delete browserWindow;
 
826
            }
 
827
        }
 
828
    }
 
829
    else if (!nsCRT::strcmp(aTopic, "profile-after-change"))
 
830
    {
 
831
        InitializePrefs();
 
832
 
 
833
        if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("switch").get())) {
 
834
            // Make a new default window
 
835
            ObeyCommand(PP_PowerPlant::cmd_New, nil);
 
836
        }
 
837
    }
 
838
    return rv;
 
839
}
 
840
 
 
841
#endif // USE_PROFILES