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

« back to all changes in this revision

Viewing changes to mozilla/embedding/tests/mfcembed/MfcEmbed.cpp

  • 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: 4 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: Mozilla-sample-code 1.0
 
4
 *
 
5
 * Copyright (c) 2002 Netscape Communications Corporation and
 
6
 * other contributors
 
7
 *
 
8
 * Permission is hereby granted, free of charge, to any person obtaining a
 
9
 * copy of this Mozilla sample software and associated documentation files
 
10
 * (the "Software"), to deal in the Software without restriction, including
 
11
 * without limitation the rights to use, copy, modify, merge, publish,
 
12
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 
13
 * persons to whom the Software is furnished to do so, subject to the
 
14
 * following conditions:
 
15
 *
 
16
 * The above copyright notice and this permission notice shall be included
 
17
 * in all copies or substantial portions of the Software.
 
18
 *
 
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
20
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
22
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
24
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
25
 * DEALINGS IN THE SOFTWARE.
 
26
 *
 
27
 * Contributor(s):
 
28
 *   Chak Nanga <chak@netscape.com> 
 
29
 *   Conrad Carlen <ccarlen@netscape.com> 
 
30
 *
 
31
 * ***** END LICENSE BLOCK ***** */
 
32
 
 
33
// File Overview....
 
34
//
 
35
// The typical MFC app, frame creation code + AboutDlg handling
 
36
//
 
37
// NS_InitEmbedding() is called in InitInstance()
 
38
// 
 
39
// NS_TermEmbedding() is called in ExitInstance()
 
40
// ExitInstance() also takes care of cleaning up of
 
41
// multiple browser frame windows on app exit
 
42
//
 
43
// Code to handle the creation of a new browser window
 
44
 
 
45
// Next suggested file to look at : BrowserFrm.cpp
 
46
 
 
47
// Local Includes
 
48
#include "stdafx.h"
 
49
#include "MfcEmbed.h"
 
50
#include "nsXPCOMGlue.h"
 
51
#include "nsIComponentRegistrar.h"
 
52
#include "BrowserFrm.h"
 
53
#include "EditorFrm.h"
 
54
#include "winEmbedFileLocProvider.h"
 
55
#include "BrowserImpl.h"
 
56
#include "nsIWindowWatcher.h"
 
57
#include "plstr.h"
 
58
#include "Preferences.h"
 
59
#include <io.h>
 
60
#include <fcntl.h>
 
61
 
 
62
#ifdef USE_PROFILES
 
63
#include "ProfileMgr.h"
 
64
#else
 
65
#include "nsProfileDirServiceProvider.h"
 
66
#endif
 
67
 
 
68
#ifdef MOZ_PROFILESHARING
 
69
#include "nsIProfileSharingSetup.h"
 
70
#endif
 
71
 
 
72
#ifdef _BUILD_STATIC_BIN
 
73
#include "nsStaticComponent.h"
 
74
nsresult PR_CALLBACK
 
75
app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count);
 
76
#endif
 
77
 
 
78
 
 
79
#ifdef NS_TRACE_MALLOC
 
80
#include "nsTraceMalloc.h"
 
81
#endif
 
82
 
 
83
#ifdef _DEBUG
 
84
#define new DEBUG_NEW
 
85
#undef THIS_FILE
 
86
static char THIS_FILE[] = __FILE__;
 
87
#endif
 
88
 
 
89
// this is for overriding the Mozilla default PromptService component
 
90
#include "PromptService.h"
 
91
#define kComponentsLibname _T("mfcEmbedComponents.dll")
 
92
#define NS_PROMPTSERVICE_CID \
 
93
 {0xa2112d6a, 0x0e28, 0x421f, {0xb4, 0x6a, 0x25, 0xc0, 0xb3, 0x8, 0xcb, 0xd0}}
 
94
static NS_DEFINE_CID(kPromptServiceCID, NS_PROMPTSERVICE_CID);
 
95
 
 
96
// this is for overriding the Mozilla default PrintingPromptService component
 
97
#include "PrintingPromptService.h"
 
98
#define NS_PRINTINGPROMPTSERVICE_CID \
 
99
 {0xe042570c, 0x62de, 0x4bb6, { 0xa6, 0xe0, 0x79, 0x8e, 0x3c, 0x7, 0xb4, 0xdf}}
 
100
static NS_DEFINE_CID(kPrintingPromptServiceCID, NS_PRINTINGPROMPTSERVICE_CID);
 
101
 
 
102
// this is for overriding the Mozilla default HelperAppLauncherDialog
 
103
#include "HelperAppService.h"
 
104
#define NS_HELPERAPPLAUNCHERDIALOG_CID \
 
105
    {0xf68578eb, 0x6ec2, 0x4169, {0xae, 0x19, 0x8c, 0x62, 0x43, 0xf0, 0xab, 0xe1}}
 
106
static NS_DEFINE_CID(kHelperAppLauncherDialogCID, NS_HELPERAPPLAUNCHERDIALOG_CID);
 
107
 
 
108
class CMfcEmbedCommandLine : public CCommandLineInfo
 
109
{
 
110
public:
 
111
 
 
112
    CMfcEmbedCommandLine(CMfcEmbedApp& app) : CCommandLineInfo(),
 
113
                                              mApp(app)
 
114
    {
 
115
    }
 
116
 
 
117
    // generic parser which bundles up flags and their parameters, to
 
118
    // pass to HandleFlag() or HandleNakedParameter()
 
119
    // if you're adding new parameters, please don't touch this
 
120
    // function and instead add your own handler below
 
121
    virtual void ParseParam(LPCTSTR szParam, BOOL bFlag, BOOL bLast)
 
122
    {
 
123
        CCommandLineInfo::ParseParam(szParam, bFlag, bLast);
 
124
        if (bFlag) {
 
125
            // advance past extra stuff like --foo
 
126
            while (*szParam && *szParam == '-')
 
127
                szParam++;
 
128
 
 
129
            // previous argument was a flag too, so process that first
 
130
            if (!mLastFlag.IsEmpty())
 
131
                HandleFlag(mLastFlag);
 
132
            
 
133
            mLastFlag = szParam;
 
134
 
 
135
            // oops, no more arguments coming, so handle this now
 
136
            if (bLast)
 
137
                HandleFlag(mLastFlag);
 
138
            
 
139
        } else {
 
140
            if (!mLastFlag.IsEmpty())
 
141
                HandleFlag(mLastFlag, szParam);
 
142
                
 
143
            mLastFlag.Truncate();
 
144
        }
 
145
    }
 
146
 
 
147
    // handle flag-based parameters
 
148
#ifdef _UNICODE
 
149
    void HandleFlag(const nsAString& flag, const TCHAR * param = nsnull)
 
150
#else
 
151
    void HandleFlag(const nsACString& flag, const TCHAR * param = nsnull)
 
152
#endif
 
153
    {
 
154
        if (flag.Equals(_T("console")))
 
155
            DoConsole();
 
156
        else if (flag.Equals(_T("chrome")))
 
157
            DoChrome();
 
158
#ifdef NS_TRACE_MALLOC
 
159
        else if (flag.Equals(_T("trace-malloc")))
 
160
        {
 
161
            USES_CONVERSION;
 
162
            DoTraceMalloc(flag, T2CA(param));
 
163
        }
 
164
#endif
 
165
        // add new flag handlers here (please add a DoFoo() method below!)
 
166
    }
 
167
 
 
168
    void HandleNakedParameter(const char* flag) {
 
169
        // handle non-flag arguments here
 
170
    }
 
171
 
 
172
    // add your specific handlers here
 
173
    void DoConsole() {
 
174
        mApp.ShowDebugConsole();
 
175
    }
 
176
 
 
177
    void DoChrome() {
 
178
        mApp.m_bChrome = TRUE;
 
179
    }
 
180
 
 
181
#ifdef NS_TRACE_MALLOC
 
182
    void DoTraceMalloc(const nsACString& flag, const char* param)
 
183
    {
 
184
        if (!param) {
 
185
            NS_WARNING("--trace-malloc needs a filename as a parameter");
 
186
            return;
 
187
        }
 
188
 
 
189
        // build up fake argv/argc arguments for tracemalloc stuff
 
190
        char* argv[] = { "mfcembed", "--trace-malloc",
 
191
                         NS_CONST_CAST(char*, param) };
 
192
        
 
193
        NS_TraceMallocStartupArgs(3, argv);
 
194
    }
 
195
#endif
 
196
    
 
197
private:
 
198
    // autostring is fine, this is a stack based object anyway
 
199
#ifdef _UNICODE
 
200
    nsAutoString mLastFlag;
 
201
#else
 
202
    nsCAutoString mLastFlag;
 
203
#endif
 
204
 
 
205
    CMfcEmbedApp& mApp;
 
206
};
 
207
 
 
208
 
 
209
BEGIN_MESSAGE_MAP(CMfcEmbedApp, CWinApp)
 
210
    //{{AFX_MSG_MAP(CMfcEmbedApp)
 
211
    ON_COMMAND(ID_NEW_BROWSER, OnNewBrowser)
 
212
    ON_COMMAND(ID_NEW_EDITORWINDOW, OnNewEditor)
 
213
#ifdef USE_PROFILES
 
214
    ON_COMMAND(ID_MANAGE_PROFILES, OnManageProfiles)
 
215
#endif
 
216
    ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
 
217
    ON_COMMAND(ID_EDIT_PREFERENCES, OnEditPreferences)
 
218
    // NOTE - the ClassWizard will add and remove mapping macros here.
 
219
    //    DO NOT EDIT what you see in these blocks of generated code!
 
220
    //}}AFX_MSG_MAP
 
221
END_MESSAGE_MAP()
 
222
 
 
223
CMfcEmbedApp::CMfcEmbedApp()
 
224
{
 
225
    mRefCnt = 1; // Start at one - nothing is going to addref this object
 
226
 
 
227
#ifdef USE_PROFILES
 
228
    m_ProfileMgr = NULL;
 
229
#endif
 
230
 
 
231
    m_strHomePage = "";
 
232
 
 
233
    m_iStartupPage = 0; 
 
234
 
 
235
    m_bChrome = FALSE;
 
236
}
 
237
 
 
238
CMfcEmbedApp theApp;
 
239
 
 
240
/* Some Gecko interfaces are implemented as components, automatically
 
241
   registered at application initialization. nsIPrompt is an example:
 
242
   the default implementation uses XUL, not native windows. Embedding
 
243
   apps can override the default implementation by implementing the
 
244
   nsIPromptService interface and registering a factory for it with
 
245
   the same CID and Contract ID as the default's.
 
246
 
 
247
   Note that this example implements the service in a separate DLL,
 
248
   replacing the default if the override DLL is present. This could
 
249
   also have been done in the same module, without a separate DLL.
 
250
   See the PowerPlant example for, well, an example.
 
251
*/
 
252
nsresult CMfcEmbedApp::OverrideComponents()
 
253
{
 
254
    nsCOMPtr<nsIComponentRegistrar> compReg;
 
255
    nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(compReg));
 
256
    NS_ENSURE_SUCCESS(rv, rv);
 
257
    
 
258
    // replace Mozilla's default PromptService with our own, if the
 
259
    // expected override DLL is present
 
260
    HMODULE overlib = ::LoadLibrary(kComponentsLibname);
 
261
    if (overlib) {
 
262
        InitPromptServiceType InitLib;
 
263
        MakeFactoryType MakeFactory;
 
264
        InitLib = reinterpret_cast<InitPromptServiceType>(::GetProcAddress(overlib, kPromptServiceInitFuncName));
 
265
        MakeFactory = reinterpret_cast<MakeFactoryType>(::GetProcAddress(overlib, kPromptServiceFactoryFuncName));
 
266
 
 
267
        if (InitLib && MakeFactory) {
 
268
            InitLib(overlib);
 
269
 
 
270
            nsCOMPtr<nsIFactory> promptFactory;
 
271
            rv = MakeFactory(getter_AddRefs(promptFactory));
 
272
            if (NS_SUCCEEDED(rv)) {
 
273
                compReg->RegisterFactory(kPromptServiceCID,
 
274
                                         "Prompt Service",
 
275
                                         "@mozilla.org/embedcomp/prompt-service;1",
 
276
                                         promptFactory);
 
277
            }
 
278
        } else
 
279
          ::FreeLibrary(overlib);
 
280
    }
 
281
 
 
282
    // Replace Mozilla's helper app launcher dialog with our own
 
283
    overlib = ::LoadLibrary(kComponentsLibname);
 
284
    if (overlib) {
 
285
        InitHelperAppDlgType InitLib;
 
286
        MakeFactoryType MakeFactory;
 
287
        InitLib = reinterpret_cast<InitHelperAppDlgType>(::GetProcAddress(overlib, kHelperAppDlgInitFuncName));
 
288
        MakeFactory = reinterpret_cast<MakeFactoryType>(::GetProcAddress(overlib, kHelperAppDlgFactoryFuncName));
 
289
 
 
290
        if (InitLib && MakeFactory) {
 
291
            InitLib(overlib);
 
292
 
 
293
            nsCOMPtr<nsIFactory> helperAppDlgFactory;
 
294
            rv = MakeFactory(getter_AddRefs(helperAppDlgFactory));
 
295
            if (NS_SUCCEEDED(rv))
 
296
                compReg->RegisterFactory(kHelperAppLauncherDialogCID,
 
297
                                         "Helper App Launcher Dialog",
 
298
                                         "@mozilla.org/helperapplauncherdialog;1",
 
299
                                         helperAppDlgFactory);
 
300
        } else
 
301
          ::FreeLibrary(overlib);
 
302
    }
 
303
 
 
304
    // replace Mozilla's default PrintingPromptService with our own, if the
 
305
    // expected override DLL is present
 
306
    overlib = ::LoadLibrary(kComponentsLibname);
 
307
    if (overlib) {
 
308
        InitPrintingPromptServiceType InitLib;
 
309
        MakeFactoryType MakeFactory;
 
310
        InitLib = reinterpret_cast<InitPrintingPromptServiceType>(::GetProcAddress(overlib, kPrintingPromptServiceInitFuncName));
 
311
        MakeFactory = reinterpret_cast<MakeFactoryType>(::GetProcAddress(overlib, kPrintingPromptServiceFactoryFuncName));
 
312
 
 
313
        if (InitLib && MakeFactory) {
 
314
            InitLib(overlib);
 
315
 
 
316
            nsCOMPtr<nsIFactory> printingPromptFactory;
 
317
            rv = MakeFactory(getter_AddRefs(printingPromptFactory));
 
318
            if (NS_SUCCEEDED(rv))
 
319
                compReg->RegisterFactory(kPrintingPromptServiceCID,
 
320
                                         "Printing Prompt Service",
 
321
                                         "@mozilla.org/embedcomp/printingprompt-service;1",
 
322
                                         printingPromptFactory);
 
323
        } else
 
324
          ::FreeLibrary(overlib);
 
325
    }
 
326
    return rv;
 
327
}
 
328
 
 
329
void CMfcEmbedApp::ShowDebugConsole()
 
330
{
 
331
#ifdef _DEBUG
 
332
    // Show console only in debug mode
 
333
 
 
334
    if(! AllocConsole())
 
335
        return;
 
336
 
 
337
    // Redirect stdout to the console
 
338
    int hCrtOut = _open_osfhandle(
 
339
                (long) GetStdHandle(STD_OUTPUT_HANDLE),
 
340
                _O_TEXT);
 
341
    if(hCrtOut == -1)
 
342
        return;
 
343
 
 
344
    FILE *hfOut = _fdopen(hCrtOut, "w");
 
345
    if(hfOut != NULL)
 
346
    {
 
347
        // Setup for unbuffered I/O so the console 
 
348
        // output shows up right away
 
349
        *stdout = *hfOut;
 
350
        setvbuf(stdout, NULL, _IONBF, 0); 
 
351
    }
 
352
 
 
353
    // Redirect stderr to the console
 
354
    int hCrtErr = _open_osfhandle(
 
355
                (long) GetStdHandle(STD_ERROR_HANDLE),
 
356
                _O_TEXT);
 
357
    if(hCrtErr == -1)
 
358
        return;
 
359
 
 
360
    FILE *hfErr = _fdopen(hCrtErr, "w");
 
361
    if(hfErr != NULL)
 
362
    {
 
363
        // Setup for unbuffered I/O so the console 
 
364
        // output shows up right away
 
365
        *stderr = *hfErr;
 
366
        setvbuf(stderr, NULL, _IONBF, 0); 
 
367
    }
 
368
#endif
 
369
}
 
370
 
 
371
 
 
372
// Initialize our MFC application and also init
 
373
// the Gecko embedding APIs
 
374
// Note that we're also init'ng the profile switching
 
375
// code here
 
376
// Then, create a new BrowserFrame and load our
 
377
// default homepage
 
378
//
 
379
BOOL CMfcEmbedApp::InitInstance()
 
380
{
 
381
#ifdef _BUILD_STATIC_BIN
 
382
    // Initialize XPCOM's module info table
 
383
    NSGetStaticModuleInfo = app_getModuleInfo;
 
384
#endif
 
385
 
 
386
    CMfcEmbedCommandLine cmdLine(*this);
 
387
    ParseCommandLine(cmdLine);
 
388
    
 
389
    Enable3dControls();
 
390
 
 
391
#ifdef XPCOM_GLUE
 
392
    if (NS_FAILED(XPCOMGlueStartup(GRE_GetXPCOMPath()))) {
 
393
        MessageBox(NULL, "Could not initialize XPCOM. Perhaps the GRE\nis not installed or could not be found?", "MFCEmbed", MB_OK | MB_ICONERROR);
 
394
        return FALSE;
 
395
    }
 
396
#endif
 
397
 
 
398
    //
 
399
    // 1. Determine the name of the dir from which the GRE based app is being run
 
400
    // from [It's OK to do this even if you're not running in an GRE env]
 
401
    //
 
402
    // 2. Create an nsILocalFile out of it which will passed in to NS_InitEmbedding()
 
403
    //
 
404
    // Please see http://www.mozilla.org/projects/embedding/GRE.html
 
405
    // for more info. on GRE
 
406
 
 
407
    TCHAR path[_MAX_PATH+1];
 
408
    ::GetModuleFileName(0, path, _MAX_PATH);
 
409
    TCHAR* lastSlash = _tcsrchr(path, _T('\\'));
 
410
    if (!lastSlash) {
 
411
        NS_ERROR("No slash in module file name... something is wrong.");
 
412
        return FALSE;
 
413
    }
 
414
    *lastSlash = _T('\0');
 
415
 
 
416
    USES_CONVERSION;
 
417
    nsresult rv;
 
418
    nsCOMPtr<nsILocalFile> mreAppDir;
 
419
    rv = NS_NewNativeLocalFile(nsDependentCString(T2A(path)), TRUE, getter_AddRefs(mreAppDir));
 
420
    NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create mreAppDir localfile");
 
421
 
 
422
    // Take a look at 
 
423
    // http://www.mozilla.org/projects/xpcom/file_locations.html
 
424
    // for more info on File Locations
 
425
 
 
426
    CString strRes;
 
427
    strRes.LoadString(IDS_PROFILES_FOLDER_NAME);
 
428
    winEmbedFileLocProvider *provider = new winEmbedFileLocProvider(nsDependentCString(strRes));
 
429
    if(!provider)
 
430
    {
 
431
        ASSERT(FALSE);
 
432
        return FALSE;
 
433
    }
 
434
 
 
435
    rv = NS_InitEmbedding(mreAppDir, provider);
 
436
    if(NS_FAILED(rv))
 
437
    {
 
438
        ASSERT(FALSE);
 
439
        return FALSE;
 
440
    }
 
441
 
 
442
    rv = OverrideComponents();
 
443
    if(NS_FAILED(rv))
 
444
    {
 
445
        ASSERT(FALSE);
 
446
        return FALSE;
 
447
    }
 
448
 
 
449
 
 
450
    rv = InitializeWindowCreator();
 
451
    if (NS_FAILED(rv))
 
452
    {
 
453
        ASSERT(FALSE);
 
454
        return FALSE;
 
455
    }
 
456
 
 
457
    if(!InitializeProfiles())
 
458
    {
 
459
        ASSERT(FALSE);
 
460
        NS_TermEmbedding();
 
461
        return FALSE;
 
462
    }
 
463
 
 
464
 
 
465
    if(!CreateHiddenWindow())
 
466
    {
 
467
        ASSERT(FALSE);
 
468
        NS_TermEmbedding();
 
469
        return FALSE;
 
470
    }
 
471
 
 
472
    // Create the first browser frame window
 
473
    OnNewBrowser();
 
474
 
 
475
    return TRUE;
 
476
}
 
477
 
 
478
CBrowserFrame* CMfcEmbedApp::CreateNewBrowserFrame(PRUint32 chromeMask,
 
479
                                                   PRInt32 x, PRInt32 y,
 
480
                                                   PRInt32 cx, PRInt32 cy,
 
481
                                                   PRBool bShowWindow,
 
482
                                                   PRBool bIsEditor
 
483
                                                   )
 
484
{
 
485
    UINT resId = bIsEditor ? IDR_EDITOR : IDR_MAINFRAME;
 
486
 
 
487
    // Setup a CRect with the requested window dimensions
 
488
    CRect winSize(x, y, cx, cy);
 
489
 
 
490
    // Use the Windows default if all are specified as -1
 
491
    if(x == -1 && y == -1 && cx == -1 && cy == -1)
 
492
        winSize = CFrameWnd::rectDefault;
 
493
 
 
494
    // Load the window title from the string resource table
 
495
    CString strTitle;
 
496
    strTitle.LoadString(IDR_MAINFRAME);
 
497
 
 
498
    // Now, create the browser frame
 
499
    CBrowserFrame* pFrame = bIsEditor ? ( new  CEditorFrame(chromeMask) ) :
 
500
                        ( new  CBrowserFrame(chromeMask) );
 
501
    pFrame->SetEditable(bIsEditor);
 
502
 
 
503
    if (!pFrame->Create(NULL, strTitle, WS_OVERLAPPEDWINDOW, 
 
504
                    winSize, NULL, MAKEINTRESOURCE(resId), 0L, NULL))
 
505
    {
 
506
        return NULL;
 
507
    }
 
508
 
 
509
    // load accelerator resource
 
510
    pFrame->LoadAccelTable(MAKEINTRESOURCE(IDR_MAINFRAME));
 
511
 
 
512
    // Show the window...
 
513
    if(bShowWindow)
 
514
    {
 
515
        pFrame->ShowWindow(SW_SHOW);
 
516
        pFrame->UpdateWindow();
 
517
    }
 
518
 
 
519
    // Add to the list of BrowserFrame windows
 
520
    m_FrameWndLst.AddHead(pFrame);
 
521
 
 
522
    return pFrame;
 
523
}
 
524
 
 
525
void CMfcEmbedApp::OnNewBrowser()
 
526
{
 
527
    CBrowserFrame *pBrowserFrame = CreateNewBrowserFrame();
 
528
 
 
529
    //Load the HomePage into the browser view
 
530
    if(pBrowserFrame && (GetStartupPageMode() == 1))
 
531
        pBrowserFrame->m_wndBrowserView.LoadHomePage();
 
532
}
 
533
 
 
534
void CMfcEmbedApp::OnNewEditor() 
 
535
{
 
536
    CEditorFrame *pEditorFrame = (CEditorFrame *)CreateNewBrowserFrame(nsIWebBrowserChrome::CHROME_ALL, 
 
537
                                    -1, -1, -1, -1,
 
538
                                    PR_TRUE,PR_TRUE);
 
539
    if (pEditorFrame)
 
540
    {
 
541
        pEditorFrame->InitEditor();
 
542
        pEditorFrame->m_wndBrowserView.OpenURL("about:blank");
 
543
    }
 
544
}
 
545
 
 
546
// This gets called anytime a BrowserFrameWindow is
 
547
// closed i.e. by choosing the "close" menu item from
 
548
// a window's system menu or by dbl clicking on the
 
549
// system menu box
 
550
// 
 
551
// Sends a WM_QUIT to the hidden window which results
 
552
// in ExitInstance() being called and the app is
 
553
// properly cleaned up and shutdown
 
554
//
 
555
void CMfcEmbedApp::RemoveFrameFromList(CBrowserFrame* pFrm, BOOL bCloseAppOnLastFrame/*= TRUE*/)
 
556
{
 
557
    POSITION pos = m_FrameWndLst.Find(pFrm);
 
558
    m_FrameWndLst.RemoveAt(pos);
 
559
 
 
560
    // Send a WM_QUIT msg. to the hidden window if we've
 
561
    // just closed the last browserframe window and
 
562
    // if the bCloseAppOnLastFrame is TRUE. This be FALSE
 
563
    // only in the case we're switching profiles
 
564
    // Without this the hidden window will stick around
 
565
    // i.e. the app will never die even after all the 
 
566
    // visible windows are gone.
 
567
    if(m_FrameWndLst.GetCount() == 0 && bCloseAppOnLastFrame)
 
568
        m_pMainWnd->PostMessage(WM_QUIT);
 
569
}
 
570
 
 
571
int CMfcEmbedApp::ExitInstance()
 
572
{
 
573
    // When File/Exit is chosen and if the user
 
574
    // has opened multiple browser windows shut all
 
575
    // of them down properly before exiting the app
 
576
 
 
577
    CBrowserFrame* pBrowserFrame = NULL;
 
578
 
 
579
    POSITION pos = m_FrameWndLst.GetHeadPosition();
 
580
    while( pos != NULL )
 
581
    {
 
582
        pBrowserFrame = (CBrowserFrame *) m_FrameWndLst.GetNext(pos);
 
583
        if(pBrowserFrame)
 
584
        {
 
585
            pBrowserFrame->ShowWindow(false);
 
586
            pBrowserFrame->DestroyWindow();
 
587
        }
 
588
    }
 
589
    m_FrameWndLst.RemoveAll();
 
590
 
 
591
    if (m_pMainWnd)
 
592
        m_pMainWnd->DestroyWindow();
 
593
 
 
594
#ifdef USE_PROFILES
 
595
    delete m_ProfileMgr;
 
596
#else
 
597
    if (m_ProfileDirServiceProvider)
 
598
    {
 
599
        m_ProfileDirServiceProvider->Shutdown();
 
600
        NS_RELEASE(m_ProfileDirServiceProvider);
 
601
    }
 
602
#endif
 
603
 
 
604
    NS_TermEmbedding();
 
605
 
 
606
#ifdef XPCOM_GLUE
 
607
    XPCOMGlueShutdown();
 
608
#endif
 
609
 
 
610
    return 1;
 
611
}
 
612
 
 
613
BOOL CMfcEmbedApp::OnIdle(LONG lCount)
 
614
{
 
615
    CWinApp::OnIdle(lCount);
 
616
 
 
617
    return FALSE;
 
618
}
 
619
 
 
620
void CMfcEmbedApp::OnManageProfiles()
 
621
{
 
622
#ifdef USE_PROFILES
 
623
    m_ProfileMgr->DoManageProfilesDialog(PR_FALSE);
 
624
#endif
 
625
}
 
626
 
 
627
void CMfcEmbedApp::OnEditPreferences()
 
628
{
 
629
    CPreferences prefs(_T("Preferences"));
 
630
    
 
631
    prefs.m_startupPage.m_iStartupPage = m_iStartupPage;
 
632
    prefs.m_startupPage.m_strHomePage = m_strHomePage;   
 
633
 
 
634
    if(prefs.DoModal() == IDOK)
 
635
    {
 
636
        // Update our member vars with these new pref values
 
637
        m_iStartupPage = prefs.m_startupPage.m_iStartupPage;
 
638
        m_strHomePage = prefs.m_startupPage.m_strHomePage;
 
639
 
 
640
        // Save these changes to disk now
 
641
        nsresult rv;
 
642
        nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv));
 
643
        if (NS_SUCCEEDED(rv)) 
 
644
        {
 
645
            USES_CONVERSION;
 
646
            prefs->SetIntPref("browser.startup.page", m_iStartupPage);
 
647
            rv = prefs->SetCharPref("browser.startup.homepage", T2CA(m_strHomePage));
 
648
            if (NS_SUCCEEDED(rv))
 
649
                rv = prefs->SavePrefFile(nsnull);
 
650
        }
 
651
        else
 
652
            NS_ASSERTION(PR_FALSE, "Could not get preferences service");
 
653
    }
 
654
}
 
655
 
 
656
BOOL CMfcEmbedApp::InitializeProfiles()
 
657
{
 
658
 
 
659
#ifdef MOZ_PROFILESHARING
 
660
    // If we are using profile sharing, get the sharing setup service
 
661
    nsCOMPtr<nsIProfileSharingSetup> sharingSetup =
 
662
        do_GetService("@mozilla.org/embedcomp/profile-sharing-setup;1");
 
663
    if (sharingSetup)
 
664
    {
 
665
        USES_CONVERSION;
 
666
        CString strRes;
 
667
        strRes.LoadString(IDS_PROFILES_NONSHARED_NAME);
 
668
        nsDependentString nonSharedName(T2W(strRes));
 
669
        sharingSetup->EnableSharing(nonSharedName);
 
670
    }
 
671
#endif
 
672
 
 
673
    nsCOMPtr<nsIObserverService> observerService = 
 
674
             do_GetService("@mozilla.org/observer-service;1");
 
675
    if (!observerService)
 
676
        return FALSE;
 
677
 
 
678
    // Both the profile mgr and standalone nsProfileDirServiceProvider
 
679
    // send this notification.
 
680
    observerService->AddObserver(this, "profile-after-change", PR_TRUE);
 
681
 
 
682
#ifdef USE_PROFILES
 
683
    m_ProfileMgr = new CProfileMgr;
 
684
    if (!m_ProfileMgr)
 
685
        return FALSE;
 
686
 
 
687
    observerService->AddObserver(this, "profile-approve-change", PR_TRUE);
 
688
    observerService->AddObserver(this, "profile-change-teardown", PR_TRUE);
 
689
 
 
690
    m_ProfileMgr->StartUp();
 
691
#else
 
692
    nsresult rv;
 
693
    nsCOMPtr<nsIFile> appDataDir;
 
694
    NS_GetSpecialDirectory(NS_APP_APPLICATION_REGISTRY_DIR,
 
695
                                getter_AddRefs(appDataDir));
 
696
    if (!appDataDir)
 
697
        return FALSE;
 
698
    nsCOMPtr<nsProfileDirServiceProvider> profProvider;
 
699
    NS_NewProfileDirServiceProvider(PR_TRUE, getter_AddRefs(profProvider));
 
700
    if (!profProvider)
 
701
        return FALSE;
 
702
    profProvider->Register();    
 
703
    nsCOMPtr<nsILocalFile> localAppDataDir(do_QueryInterface(appDataDir));
 
704
    rv = profProvider->SetProfileDir(localAppDataDir);
 
705
    if (NS_FAILED(rv))
 
706
        return FALSE;
 
707
    NS_ADDREF(m_ProfileDirServiceProvider = profProvider);
 
708
#endif
 
709
 
 
710
    return TRUE;
 
711
}
 
712
 
 
713
// When the profile switch happens, all open browser windows need to be 
 
714
// closed. 
 
715
// In order for that not to kill off the app, we just make the MFC app's 
 
716
// mainframe be an invisible window which doesn't get closed on profile 
 
717
// switches
 
718
BOOL CMfcEmbedApp::CreateHiddenWindow()
 
719
{
 
720
    CFrameWnd *hiddenWnd = new CFrameWnd;
 
721
    if(!hiddenWnd)
 
722
        return FALSE;
 
723
 
 
724
    RECT bounds = { -10010, -10010, -10000, -10000 };
 
725
    hiddenWnd->Create(NULL, _T("main"), WS_DISABLED, bounds, NULL, NULL, 0, NULL);
 
726
    m_pMainWnd = hiddenWnd;
 
727
 
 
728
    return TRUE;
 
729
}
 
730
 
 
731
nsresult CMfcEmbedApp::InitializePrefs()
 
732
{
 
733
   nsresult rv;
 
734
   nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv));
 
735
   if (NS_SUCCEEDED(rv)) {      
 
736
 
 
737
        // We are using the default prefs from mozilla. If you were
 
738
        // disributing your own, this would be done simply by editing
 
739
        // the default pref files.
 
740
        
 
741
        PRBool inited;
 
742
        rv = prefs->GetBoolPref("mfcbrowser.prefs_inited", &inited);
 
743
        if (NS_FAILED(rv) || !inited)
 
744
        {
 
745
            USES_CONVERSION;
 
746
            m_iStartupPage = 1;
 
747
            m_strHomePage = "http://www.mozilla.org/projects/embedding";
 
748
 
 
749
            prefs->SetIntPref("browser.startup.page", m_iStartupPage);
 
750
            prefs->SetCharPref("browser.startup.homepage", T2CA(m_strHomePage));
 
751
            prefs->SetIntPref("font.size.variable.x-western", 16);
 
752
            prefs->SetIntPref("font.size.fixed.x-western", 13);
 
753
            rv = prefs->SetBoolPref("mfcbrowser.prefs_inited", PR_TRUE);
 
754
            if (NS_SUCCEEDED(rv))
 
755
                rv = prefs->SavePrefFile(nsnull);
 
756
        }
 
757
        else
 
758
        {
 
759
            // The prefs are present, read them in
 
760
 
 
761
            prefs->GetIntPref("browser.startup.page", &m_iStartupPage);
 
762
 
 
763
            nsXPIDLCString str;
 
764
            prefs->GetCharPref("browser.startup.homepage", getter_Copies(str));
 
765
            if (!str.IsEmpty())
 
766
            {
 
767
                USES_CONVERSION;
 
768
                m_strHomePage = A2CT(str.get());
 
769
            }
 
770
            else
 
771
            {
 
772
                m_strHomePage.Empty();
 
773
            }
 
774
        }       
 
775
    }
 
776
    else
 
777
        NS_ASSERTION(PR_FALSE, "Could not get preferences service");
 
778
        
 
779
    return rv;
 
780
}
 
781
 
 
782
 
 
783
/* InitializeWindowCreator creates and hands off an object with a callback
 
784
   to a window creation function. This will be used by Gecko C++ code
 
785
   (never JS) to create new windows when no previous window is handy
 
786
   to begin with. This is done in a few exceptional cases, like PSM code.
 
787
   Failure to set this callback will only disable the ability to create
 
788
   new windows under these circumstances. */
 
789
nsresult CMfcEmbedApp::InitializeWindowCreator()
 
790
{
 
791
  // give an nsIWindowCreator to the WindowWatcher service
 
792
  nsCOMPtr<nsIWindowCreator> windowCreator(NS_STATIC_CAST(nsIWindowCreator *, this));
 
793
  if (windowCreator) {
 
794
    nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
 
795
    if (wwatch) {
 
796
      wwatch->SetWindowCreator(windowCreator);
 
797
      return NS_OK;
 
798
    }
 
799
  }
 
800
  return NS_ERROR_FAILURE;
 
801
}
 
802
 
 
803
// ---------------------------------------------------------------------------
 
804
//  CMfcEmbedApp : nsISupports
 
805
// ---------------------------------------------------------------------------
 
806
 
 
807
NS_IMPL_THREADSAFE_ISUPPORTS3(CMfcEmbedApp, nsIObserver, nsIWindowCreator, nsISupportsWeakReference)
 
808
 
 
809
// ---------------------------------------------------------------------------
 
810
//  CMfcEmbedApp : nsIObserver
 
811
// ---------------------------------------------------------------------------
 
812
 
 
813
// Mainly needed to support "on the fly" profile switching
 
814
 
 
815
NS_IMETHODIMP CMfcEmbedApp::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
 
816
{
 
817
    nsresult rv = NS_OK;
 
818
    
 
819
    if (strcmp(aTopic, "profile-approve-change") == 0)
 
820
    {
 
821
        // Ask the user if they want to
 
822
        int result = MessageBox(NULL,
 
823
            _T("Do you want to close all windows in order to switch the profile?"),
 
824
            _T("Confirm"), MB_YESNO | MB_ICONQUESTION);
 
825
        if (result != IDYES)
 
826
        {
 
827
            nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
 
828
            NS_ENSURE_TRUE(status, NS_ERROR_FAILURE);
 
829
            status->VetoChange();
 
830
        }
 
831
    }
 
832
    else if (strcmp(aTopic, "profile-change-teardown") == 0)
 
833
    {
 
834
        // Close all open windows. Alternatively, we could just call CBrowserWindow::Stop()
 
835
        // on each. Either way, we have to stop all network activity on this phase.
 
836
        
 
837
        POSITION pos = m_FrameWndLst.GetHeadPosition();
 
838
        while( pos != NULL )
 
839
        {
 
840
            CBrowserFrame *pBrowserFrame = (CBrowserFrame *) m_FrameWndLst.GetNext(pos);
 
841
            if(pBrowserFrame)
 
842
            {
 
843
                pBrowserFrame->ShowWindow(false);
 
844
 
 
845
                // Passing in FALSE below so that we do not
 
846
                // kill the main app during a profile switch
 
847
                RemoveFrameFromList(pBrowserFrame, FALSE);
 
848
 
 
849
                pBrowserFrame->DestroyWindow();
 
850
            }
 
851
        }
 
852
    }
 
853
    else if (strcmp(aTopic, "profile-after-change") == 0)
 
854
    {
 
855
        InitializePrefs(); // In case we have just switched to a newly created profile.
 
856
        
 
857
        // Only make a new browser window on a switch. This also gets
 
858
        // called at start up and we already make a window then.
 
859
        if (!wcscmp(someData, NS_LITERAL_STRING("switch").get()))      
 
860
            OnNewBrowser();
 
861
    }
 
862
    return rv;
 
863
}
 
864
 
 
865
// ---------------------------------------------------------------------------
 
866
//  CMfcEmbedApp : nsIWindowCreator
 
867
// ---------------------------------------------------------------------------
 
868
NS_IMETHODIMP CMfcEmbedApp::CreateChromeWindow(nsIWebBrowserChrome *parent,
 
869
                                               PRUint32 chromeFlags,
 
870
                                               nsIWebBrowserChrome **_retval)
 
871
{
 
872
  // XXX we're ignoring the "parent" parameter
 
873
  NS_ENSURE_ARG_POINTER(_retval);
 
874
  *_retval = 0;
 
875
 
 
876
  CBrowserFrame *pBrowserFrame = CreateNewBrowserFrame(chromeFlags);
 
877
  if(pBrowserFrame) {
 
878
    *_retval = NS_STATIC_CAST(nsIWebBrowserChrome *, pBrowserFrame->GetBrowserImpl());
 
879
    NS_ADDREF(*_retval);
 
880
  }
 
881
  return NS_OK;
 
882
}
 
883
 
 
884
// AboutDlg Stuff
 
885
 
 
886
class CAboutDlg : public CDialog
 
887
{
 
888
public:
 
889
    CAboutDlg();
 
890
 
 
891
    enum { IDD = IDD_ABOUTBOX };
 
892
 
 
893
protected:
 
894
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 
895
 
 
896
protected:
 
897
    DECLARE_MESSAGE_MAP()
 
898
};
 
899
 
 
900
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
 
901
{
 
902
}
 
903
 
 
904
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
 
905
{
 
906
    CDialog::DoDataExchange(pDX);
 
907
}
 
908
 
 
909
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 
910
END_MESSAGE_MAP()
 
911
 
 
912
// Show the AboutDlg
 
913
void CMfcEmbedApp::OnAppAbout()
 
914
{
 
915
    CAboutDlg aboutDlg;
 
916
    aboutDlg.DoModal();
 
917
}