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

« back to all changes in this revision

Viewing changes to mozilla/embedding/browser/cocoa/src/CHBrowserView.mm

  • 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: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the NPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the NPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
#import "NSString+Utils.h"
 
39
#import "CHClickListener.h"
 
40
 
 
41
#include "nsCWebBrowser.h"
 
42
#include "nsIBaseWindow.h"
 
43
#include "nsIWebNavigation.h"
 
44
#include "nsComponentManagerUtils.h"
 
45
 
 
46
#include "nsIURI.h"
 
47
#include "nsIDOMWindow.h"
 
48
#include "nsPIDOMWindow.h"
 
49
#include "nsIChromeEventHandler.h"
 
50
#include "nsIDOMEventReceiver.h"
 
51
#include "nsIWidget.h"
 
52
 
 
53
// Printing
 
54
#include "nsIWebBrowserPrint.h"
 
55
//#include "nsIPrintSettings.h"
 
56
 
 
57
// Saving of links/images/docs
 
58
#include "nsIWebBrowserFocus.h"
 
59
#include "nsIDOMNSDocument.h"
 
60
#include "nsIDOMLocation.h"
 
61
#include "nsIWebBrowserPersist.h"
 
62
#include "nsIProperties.h"
 
63
//#include "nsIRequest.h"
 
64
//#include "nsIPrefService.h"
 
65
#include "nsISHistory.h"
 
66
#include "nsIHistoryEntry.h"
 
67
#include "nsISHEntry.h"
 
68
#include "nsNetUtil.h"
 
69
#include "SaveHeaderSniffer.h"
 
70
#include "nsIWebBrowserFind.h"
 
71
 
 
72
#import "CHBrowserView.h"
 
73
 
 
74
#import "CHBrowserService.h"
 
75
#import "CHBrowserListener.h"
 
76
 
 
77
#import "mozView.h"
 
78
 
 
79
typedef unsigned int DragReference;
 
80
#include "nsIDragHelperService.h"
 
81
 
 
82
// Cut/copy/paste
 
83
#include "nsIClipboardCommands.h"
 
84
#include "nsIInterfaceRequestorUtils.h"
 
85
 
 
86
// Undo/redo
 
87
#include "nsICommandManager.h"
 
88
#include "nsICommandParams.h"
 
89
 
 
90
 
 
91
const char kPersistContractID[] = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
 
92
const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
 
93
 
 
94
@implementation CHBrowserView
 
95
 
 
96
- (id)initWithFrame:(NSRect)frame andWindow:(NSWindow*)aWindow
 
97
{
 
98
  mWindow = aWindow;
 
99
  return [self initWithFrame:frame];
 
100
}
 
101
 
 
102
- (id)initWithFrame:(NSRect)frame
 
103
{
 
104
  if ( (self = [super initWithFrame:frame]) )
 
105
  {
 
106
    nsresult rv = CHBrowserService::InitEmbedding();
 
107
    if (NS_FAILED(rv)) {
 
108
// XXX need to throw
 
109
    }
 
110
 
 
111
    _listener = new CHBrowserListener(self);
 
112
    NS_ADDREF(_listener);
 
113
    
 
114
// Create the web browser instance
 
115
    nsCOMPtr<nsIWebBrowser> browser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv);
 
116
    if (NS_FAILED(rv)) {
 
117
// XXX need to throw
 
118
    }
 
119
 
 
120
    _webBrowser = browser;
 
121
    NS_ADDREF(_webBrowser);
 
122
    
 
123
// Set the container nsIWebBrowserChrome
 
124
    _webBrowser->SetContainerWindow(NS_STATIC_CAST(nsIWebBrowserChrome *, _listener));
 
125
    
 
126
// Register as a listener for web progress
 
127
    nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(NS_STATIC_CAST(nsIWebProgressListener*, _listener));
 
128
    _webBrowser->AddWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
 
129
    
 
130
// Hook up the widget hierarchy with us as the parent
 
131
    nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
 
132
    baseWin->InitWindow((NSView*)self, nsnull, 0, 0,
 
133
                        frame.size.width, frame.size.height);
 
134
    baseWin->Create();
 
135
    
 
136
// register the view as a drop site for text, files, and urls. 
 
137
    [self registerForDraggedTypes: [NSArray arrayWithObjects:
 
138
              @"MozURLType", NSStringPboardType, NSURLPboardType, NSFilenamesPboardType, nil]];
 
139
 
 
140
    // hookup the listener for creating our own native menus on <SELECTS>
 
141
    CHClickListener* clickListener = new CHClickListener();
 
142
    if (!clickListener)
 
143
      return nil;
 
144
    
 
145
    nsCOMPtr<nsIDOMWindow> contentWindow = getter_AddRefs([self getContentWindow]);
 
146
    nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(contentWindow));
 
147
    nsCOMPtr<nsIChromeEventHandler> chromeHandler;
 
148
    piWindow->GetChromeEventHandler(getter_AddRefs(chromeHandler));
 
149
    nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(chromeHandler));
 
150
    if ( rec )
 
151
      rec->AddEventListenerByIID(clickListener, NS_GET_IID(nsIDOMMouseListener));
 
152
  }
 
153
  return self;
 
154
}
 
155
 
 
156
- (void)destroyWebBrowser
 
157
{
 
158
  nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
 
159
  if ( baseWin ) {
 
160
    // clean up here rather than in the dtor so that if anyone tries to get our
 
161
    // web browser, it won't get a garbage object that's past its prime. As a result,
 
162
    // this routine MUST be called otherwise we will leak.
 
163
    baseWin->Destroy();
 
164
    NS_RELEASE(_webBrowser);
 
165
  }
 
166
}
 
167
 
 
168
- (void)dealloc 
 
169
{
 
170
  NS_RELEASE(_listener);
 
171
  
 
172
  // it is imperative that |destroyWebBrowser()| be called before we get here, otherwise
 
173
  // we will leak the webBrowser.
 
174
        NS_ASSERTION(!_webBrowser, "BrowserView going away, destroyWebBrowser not called; leaking webBrowser!");
 
175
  
 
176
  CHBrowserService::BrowserClosed();
 
177
  
 
178
#if DEBUG
 
179
  NSLog(@"CHBrowserView died.");
 
180
#endif
 
181
 
 
182
  [super dealloc];
 
183
}
 
184
 
 
185
- (void)setFrame:(NSRect)frameRect 
 
186
{
 
187
  [super setFrame:frameRect];
 
188
  if (_webBrowser) {
 
189
    nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(_webBrowser);
 
190
    window->SetSize((PRInt32)frameRect.size.width, 
 
191
        (PRInt32)frameRect.size.height,
 
192
        PR_TRUE);
 
193
  }
 
194
}
 
195
 
 
196
- (void)addListener:(id <CHBrowserListener>)listener
 
197
{
 
198
  _listener->AddListener(listener);
 
199
}
 
200
 
 
201
- (void)removeListener:(id <CHBrowserListener>)listener
 
202
{
 
203
  _listener->RemoveListener(listener);
 
204
}
 
205
 
 
206
- (void)setContainer:(id <CHBrowserContainer>)container
 
207
{
 
208
  _listener->SetContainer(container);
 
209
}
 
210
 
 
211
- (nsIDOMWindow*)getContentWindow
 
212
{
 
213
  nsIDOMWindow* window = nsnull;
 
214
 
 
215
  if ( _webBrowser )
 
216
    _webBrowser->GetContentDOMWindow(&window);
 
217
 
 
218
  return window;
 
219
}
 
220
 
 
221
- (void)loadURI:(NSString *)urlSpec referrer:(NSString*)referrer flags:(unsigned int)flags
 
222
{
 
223
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
224
  
 
225
  int length = [urlSpec length];
 
226
  PRUnichar* specStr = nsMemory::Alloc((length+1) * sizeof(PRUnichar));
 
227
  [urlSpec getCharacters:specStr];
 
228
  specStr[length] = PRUnichar(0);
 
229
  
 
230
  nsCOMPtr<nsIURI> referrerURI;
 
231
  if ( referrer )
 
232
    NS_NewURI(getter_AddRefs(referrerURI), [referrer UTF8String]);
 
233
 
 
234
  PRUint32 navFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
 
235
  if (flags & NSLoadFlagsDontPutInHistory) {
 
236
    navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_HISTORY;
 
237
  }
 
238
  if (flags & NSLoadFlagsReplaceHistoryEntry) {
 
239
    navFlags |= nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY;
 
240
  }
 
241
  if (flags & NSLoadFlagsBypassCacheAndProxy) {
 
242
    navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | 
 
243
                nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
 
244
  }
 
245
 
 
246
  nsresult rv = nav->LoadURI(specStr, navFlags, referrerURI, nsnull, nsnull);
 
247
  if (NS_FAILED(rv)) {
 
248
    // XXX need to throw
 
249
  }
 
250
 
 
251
  nsMemory::Free(specStr);
 
252
}
 
253
 
 
254
- (void)reload:(unsigned int)flags
 
255
{
 
256
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
257
  if ( !nav )
 
258
    return;
 
259
 
 
260
  PRUint32 navFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
 
261
  if (flags & NSLoadFlagsBypassCacheAndProxy) {
 
262
    navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | 
 
263
                nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
 
264
  }
 
265
  
 
266
  nsresult rv = nav->Reload(navFlags);
 
267
  if (NS_FAILED(rv)) {
 
268
    // XXX need to throw
 
269
  }  
 
270
}
 
271
 
 
272
- (BOOL)canGoBack
 
273
{
 
274
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
275
  if ( !nav )
 
276
    return NO;
 
277
 
 
278
  PRBool can;
 
279
  nav->GetCanGoBack(&can);
 
280
 
 
281
  return can ? YES : NO;
 
282
}
 
283
 
 
284
- (BOOL)canGoForward
 
285
{
 
286
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
287
  if ( !nav )
 
288
    return NO;
 
289
 
 
290
  PRBool can;
 
291
  nav->GetCanGoForward(&can);
 
292
 
 
293
  return can ? YES : NO;
 
294
}
 
295
 
 
296
- (void)goBack
 
297
{
 
298
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
299
  if ( !nav )
 
300
    return;
 
301
 
 
302
  nsresult rv = nav->GoBack();
 
303
  if (NS_FAILED(rv)) {
 
304
    // XXX need to throw
 
305
  }  
 
306
}
 
307
 
 
308
- (void)goForward
 
309
{
 
310
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
311
  if ( !nav )
 
312
    return;
 
313
 
 
314
  nsresult rv = nav->GoForward();
 
315
  if (NS_FAILED(rv)) {
 
316
    // XXX need to throw
 
317
  }  
 
318
}
 
319
 
 
320
- (void)gotoIndex:(int)index
 
321
{
 
322
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
323
  if ( !nav )
 
324
    return;
 
325
 
 
326
  nsresult rv = nav->GotoIndex(index);
 
327
  if (NS_FAILED(rv)) {
 
328
    // XXX need to throw
 
329
  }    
 
330
}
 
331
 
 
332
- (void)stop:(unsigned int)flags
 
333
{
 
334
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
335
  if ( !nav )
 
336
    return;
 
337
 
 
338
  nsresult rv = nav->Stop(flags);
 
339
  if (NS_FAILED(rv)) {
 
340
    // XXX need to throw
 
341
  }    
 
342
}
 
343
 
 
344
// XXXbryner This isn't used anywhere. how is it different from getCurrentURLSpec?
 
345
- (NSString*)getCurrentURI
 
346
{
 
347
  nsCOMPtr<nsIURI> uri;
 
348
  nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 
349
  if ( !nav )
 
350
    return nsnull;
 
351
 
 
352
  nav->GetCurrentURI(getter_AddRefs(uri));
 
353
  if (!uri) {
 
354
    return nsnull;
 
355
  }
 
356
 
 
357
  nsCAutoString spec;
 
358
  uri->GetSpec(spec);
 
359
  
 
360
  const char* cstr = spec.get();
 
361
  NSString* str = [NSString stringWithCString:cstr];
 
362
  
 
363
  return str;
 
364
}
 
365
 
 
366
- (CHBrowserListener*)getCocoaBrowserListener
 
367
{
 
368
  return _listener;
 
369
}
 
370
 
 
371
- (nsIWebBrowser*)getWebBrowser
 
372
{
 
373
  NS_IF_ADDREF(_webBrowser);
 
374
  return _webBrowser;
 
375
}
 
376
 
 
377
- (void)setWebBrowser:(nsIWebBrowser*)browser
 
378
{
 
379
  NS_IF_ADDREF(browser);                                // prevents destroying |browser| if |browser| == |_webBrowser|
 
380
  NS_IF_RELEASE(_webBrowser);
 
381
  _webBrowser = browser;
 
382
 
 
383
  if (_webBrowser) {
 
384
    // Set the container nsIWebBrowserChrome
 
385
    _webBrowser->SetContainerWindow(NS_STATIC_CAST(nsIWebBrowserChrome *, 
 
386
               _listener));
 
387
 
 
388
    NSRect frame = [self frame];
 
389
 
 
390
    // Hook up the widget hierarchy with us as the parent
 
391
    nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
 
392
    baseWin->InitWindow((NSView*)self, nsnull, 0, 0, 
 
393
      frame.size.width, frame.size.height);
 
394
    baseWin->Create();
 
395
  }
 
396
 
 
397
}
 
398
 
 
399
-(void) saveInternal: (nsIURI*)aURI
 
400
        withDocument: (nsIDOMDocument*)aDocument
 
401
        suggestedFilename: (const char*)aFilename
 
402
        bypassCache: (BOOL)aBypassCache
 
403
        filterView: (NSView*)aFilterView
 
404
        filterList: (NSPopUpButton*)aFilterList
 
405
{
 
406
    // Create our web browser persist object.  This is the object that knows
 
407
    // how to actually perform the saving of the page (and of the images
 
408
    // on the page).
 
409
    nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(kPersistContractID));
 
410
    if (!webPersist)
 
411
        return;
 
412
    
 
413
    // Make a temporary file object that we can save to.
 
414
    nsCOMPtr<nsIProperties> dirService(do_GetService(kDirServiceContractID));
 
415
    if (!dirService)
 
416
        return;
 
417
    nsCOMPtr<nsIFile> tmpFile;
 
418
    dirService->Get("TmpD", NS_GET_IID(nsIFile), getter_AddRefs(tmpFile));
 
419
    static short unsigned int tmpRandom = 0;
 
420
    nsAutoString tmpNo; tmpNo.AppendInt(tmpRandom++);
 
421
    nsAutoString saveFile(NS_LITERAL_STRING("-sav"));
 
422
    saveFile += tmpNo;
 
423
    saveFile += NS_LITERAL_STRING("tmp");
 
424
    tmpFile->Append(saveFile); 
 
425
    
 
426
    // Get the post data if we're an HTML doc.
 
427
    nsCOMPtr<nsIInputStream> postData;
 
428
    if (aDocument) {
 
429
      nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(_webBrowser));
 
430
      if (webNav) {
 
431
        nsCOMPtr<nsISHistory> sessionHistory;
 
432
        webNav->GetSessionHistory(getter_AddRefs(sessionHistory));
 
433
        nsCOMPtr<nsIHistoryEntry> entry;
 
434
        PRInt32 sindex;
 
435
        sessionHistory->GetIndex(&sindex);
 
436
        sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry));
 
437
        nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
 
438
        if (shEntry)
 
439
            shEntry->GetPostData(getter_AddRefs(postData));
 
440
      }
 
441
    }
 
442
 
 
443
    // when saving, we first fire off a save with a nsHeaderSniffer as a progress
 
444
    // listener. This allows us to look for the content-disposition header, which
 
445
    // can supply a filename, and maybe has something to do with CGI-generated
 
446
    // content (?)
 
447
    nsCAutoString fileName(aFilename);
 
448
    nsHeaderSniffer* sniffer = new nsHeaderSniffer(webPersist, tmpFile, aURI, 
 
449
                                                   aDocument, postData, fileName, aBypassCache,
 
450
                                                   aFilterView, aFilterList);
 
451
    if (!sniffer)
 
452
        return;
 
453
    webPersist->SetProgressListener(sniffer);  // owned
 
454
    webPersist->SaveURI(aURI, nsnull, nsnull, nsnull, nsnull, tmpFile);
 
455
}
 
456
 
 
457
-(void)printDocument
 
458
{
 
459
  if (!_webBrowser)
 
460
    return;
 
461
  nsCOMPtr<nsIDOMWindow> domWindow;
 
462
  _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 
463
  nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(domWindow));
 
464
  nsCOMPtr<nsIWebBrowserPrint> print;
 
465
  ir->GetInterface(NS_GET_IID(nsIWebBrowserPrint), getter_AddRefs(print));
 
466
  print->Print(nsnull, nsnull);
 
467
}
 
468
 
 
469
- (BOOL)findInPageWithPattern:(NSString*)inText caseSensitive:(BOOL)inCaseSensitive
 
470
    wrap:(BOOL)inWrap backwards:(BOOL)inBackwards
 
471
{
 
472
    if (!_webBrowser)
 
473
      return NO;
 
474
    PRBool found =  PR_FALSE;
 
475
    
 
476
    nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
 
477
    nsCOMPtr<nsIDOMWindow> rootWindow;
 
478
    nsCOMPtr<nsIDOMWindow> focusedWindow;
 
479
    _webBrowser->GetContentDOMWindow(getter_AddRefs(rootWindow));
 
480
    wbf->GetFocusedWindow(getter_AddRefs(focusedWindow));
 
481
    if (!focusedWindow)
 
482
        focusedWindow = rootWindow;
 
483
    nsCOMPtr<nsIWebBrowserFind> webFind(do_GetInterface(_webBrowser));
 
484
    if ( webFind ) {
 
485
      nsCOMPtr<nsIWebBrowserFindInFrames> framesFind(do_QueryInterface(webFind));
 
486
      framesFind->SetRootSearchFrame(rootWindow);
 
487
      framesFind->SetCurrentSearchFrame(focusedWindow);
 
488
      
 
489
      webFind->SetMatchCase(inCaseSensitive ? PR_TRUE : PR_FALSE);
 
490
      webFind->SetWrapFind(inWrap ? PR_TRUE : PR_FALSE);
 
491
      webFind->SetFindBackwards(inBackwards ? PR_TRUE : PR_FALSE);
 
492
    
 
493
      PRUnichar* text = (PRUnichar*)nsMemory::Alloc(([inText length]+1)*sizeof(PRUnichar));
 
494
      if ( text ) {
 
495
        [inText getCharacters:text];
 
496
        text[[inText length]] = 0;
 
497
        webFind->SetSearchString(text);
 
498
        webFind->FindNext(&found);
 
499
        nsMemory::Free(text);
 
500
      }
 
501
    }
 
502
    return found;
 
503
}
 
504
 
 
505
- (void)saveURL: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
 
506
            url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename
 
507
{
 
508
  nsCOMPtr<nsIURI> url;
 
509
  nsresult rv = NS_NewURI(getter_AddRefs(url), [aURLSpec UTF8String]);
 
510
  if (NS_FAILED(rv))
 
511
    return;
 
512
  
 
513
  [self saveInternal: url.get()
 
514
        withDocument: nsnull
 
515
   suggestedFilename: (([aFilename length] > 0) ? [aFilename fileSystemRepresentation] : "")
 
516
         bypassCache: YES
 
517
          filterView: aFilterView
 
518
          filterList: aFilterList];
 
519
}
 
520
 
 
521
-(NSString*)getFocusedURLString
 
522
{
 
523
  if (!_webBrowser)
 
524
    return @"";
 
525
  nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
 
526
  nsCOMPtr<nsIDOMWindow> domWindow;
 
527
  wbf->GetFocusedWindow(getter_AddRefs(domWindow));
 
528
  if (!domWindow)
 
529
    _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 
530
  if (!domWindow)
 
531
    return @"";
 
532
 
 
533
  nsCOMPtr<nsIDOMDocument> domDocument;
 
534
  domWindow->GetDocument(getter_AddRefs(domDocument));
 
535
  if (!domDocument)
 
536
    return @"";
 
537
  nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
 
538
  if (!nsDoc)
 
539
    return @"";
 
540
  nsCOMPtr<nsIDOMLocation> location;
 
541
  nsDoc->GetLocation(getter_AddRefs(location));
 
542
  if (!location)
 
543
    return @"";
 
544
  nsAutoString urlStr;
 
545
  location->GetHref(urlStr);
 
546
  return [NSString stringWith_nsAString: urlStr];
 
547
}
 
548
 
 
549
- (void)saveDocument: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
 
550
{
 
551
    if (!_webBrowser)
 
552
      return;
 
553
    nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
 
554
    nsCOMPtr<nsIDOMWindow> domWindow;
 
555
    wbf->GetFocusedWindow(getter_AddRefs(domWindow));
 
556
    if (!domWindow)
 
557
        _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 
558
    if (!domWindow)
 
559
        return;
 
560
    
 
561
    nsCOMPtr<nsIDOMDocument> domDocument;
 
562
    domWindow->GetDocument(getter_AddRefs(domDocument));
 
563
    if (!domDocument)
 
564
        return;
 
565
    nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
 
566
    if (!nsDoc)
 
567
        return;
 
568
    nsCOMPtr<nsIDOMLocation> location;
 
569
    nsDoc->GetLocation(getter_AddRefs(location));
 
570
    if (!location)
 
571
        return;
 
572
    nsAutoString urlStr;
 
573
    location->GetHref(urlStr);
 
574
#warning fix me
 
575
    nsCAutoString urlCStr; urlCStr.AssignWithConversion(urlStr);
 
576
    nsCOMPtr<nsIURI> url;
 
577
    nsresult rv = NS_NewURI(getter_AddRefs(url), urlCStr.get());
 
578
    if (NS_FAILED(rv))
 
579
        return;
 
580
    
 
581
    [self saveInternal: url.get()
 
582
          withDocument: domDocument
 
583
          suggestedFilename: ""
 
584
          bypassCache: NO
 
585
          filterView: aFilterView
 
586
          filterList: aFilterList];
 
587
}
 
588
 
 
589
-(void)doCommand:(const char*)commandName
 
590
{
 
591
  nsCOMPtr<nsICommandManager> commandMgr(do_GetInterface(_webBrowser));
 
592
  if (commandMgr) {
 
593
    nsresult rv = commandMgr->DoCommand(commandName, nsnull, nsnull);
 
594
#if DEBUG
 
595
      if (NS_FAILED(rv))
 
596
        NSLog(@"DoCommand failed");
 
597
#endif
 
598
  }
 
599
  else {
 
600
#if DEBUG
 
601
    NSLog(@"No command manager");
 
602
#endif
 
603
  }
 
604
}
 
605
 
 
606
-(BOOL)isCommandEnabled:(const char*)commandName
 
607
{
 
608
  PRBool        isEnabled = PR_FALSE;
 
609
  nsCOMPtr<nsICommandManager> commandMgr(do_GetInterface(_webBrowser));
 
610
  if (commandMgr) {
 
611
    nsresult rv = commandMgr->IsCommandEnabled(commandName, nsnull, &isEnabled);
 
612
#if DEBUG
 
613
    if (NS_FAILED(rv))
 
614
      NSLog(@"IsCommandEnabled failed");
 
615
#endif
 
616
  }
 
617
  else {
 
618
#if DEBUG
 
619
    NSLog(@"No command manager");
 
620
#endif
 
621
  }
 
622
  
 
623
  return (isEnabled) ? YES : NO;
 
624
}
 
625
 
 
626
 
 
627
-(IBAction)cut:(id)aSender
 
628
{
 
629
  nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 
630
  if ( clipboard )
 
631
    clipboard->CutSelection();
 
632
}
 
633
 
 
634
-(BOOL)canCut
 
635
{
 
636
  PRBool canCut = PR_FALSE;
 
637
  nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 
638
  if ( clipboard )
 
639
    clipboard->CanCutSelection(&canCut);
 
640
  return canCut;
 
641
}
 
642
 
 
643
-(IBAction)copy:(id)aSender
 
644
{
 
645
  nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 
646
  if ( clipboard )
 
647
    clipboard->CopySelection();
 
648
}
 
649
 
 
650
-(BOOL)canCopy
 
651
{
 
652
  PRBool canCut = PR_FALSE;
 
653
  nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 
654
  if ( clipboard )
 
655
    clipboard->CanCopySelection(&canCut);
 
656
  return canCut;
 
657
}
 
658
 
 
659
-(IBAction)paste:(id)aSender
 
660
{
 
661
  nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 
662
  if ( clipboard )
 
663
    clipboard->Paste();
 
664
}
 
665
 
 
666
-(BOOL)canPaste
 
667
{
 
668
  PRBool canCut = PR_FALSE;
 
669
  nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 
670
  if ( clipboard )
 
671
    clipboard->CanPaste(&canCut);
 
672
  return canCut;
 
673
}
 
674
 
 
675
-(IBAction)delete:(id)aSender
 
676
{
 
677
  [self doCommand: "cmd_delete"];
 
678
}
 
679
 
 
680
-(BOOL)canDelete
 
681
{
 
682
  return [self isCommandEnabled: "cmd_delete"];
 
683
}
 
684
 
 
685
-(IBAction)selectAll:(id)aSender
 
686
{
 
687
  nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 
688
  if ( clipboard )
 
689
    clipboard->SelectAll();
 
690
}
 
691
 
 
692
-(IBAction)undo:(id)aSender
 
693
{
 
694
  [self doCommand: "cmd_undo"];
 
695
}
 
696
 
 
697
-(IBAction)redo:(id)aSender
 
698
{
 
699
  [self doCommand: "cmd_redo"];
 
700
}
 
701
 
 
702
- (BOOL)canUndo
 
703
{
 
704
  return [self isCommandEnabled: "cmd_undo"];
 
705
}
 
706
 
 
707
- (BOOL)canRedo
 
708
{
 
709
  return [self isCommandEnabled: "cmd_redo"];
 
710
}
 
711
 
 
712
-(NSString*)getCurrentURLSpec
 
713
{
 
714
  NSString* empty = @"";
 
715
  if (!_webBrowser)
 
716
    return empty;
 
717
  nsCOMPtr<nsIDOMWindow> domWindow;
 
718
  _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 
719
  if (!domWindow)
 
720
    return empty;
 
721
  
 
722
  nsCOMPtr<nsIDOMDocument> domDocument;
 
723
  domWindow->GetDocument(getter_AddRefs(domDocument));
 
724
  if (!domDocument)
 
725
    return empty;
 
726
 
 
727
  nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
 
728
  if (!nsDoc)
 
729
    return empty;
 
730
 
 
731
  nsCOMPtr<nsIDOMLocation> location;
 
732
  nsDoc->GetLocation(getter_AddRefs(location));
 
733
  if (!location)
 
734
    return empty;
 
735
 
 
736
  nsAutoString urlStr;
 
737
  location->GetHref(urlStr);
 
738
  return [NSString stringWith_nsAString: urlStr];
 
739
}
 
740
 
 
741
- (void)setActive: (BOOL)aIsActive
 
742
{
 
743
  nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
 
744
  if (wbf) {
 
745
    if (aIsActive)
 
746
      wbf->Activate();
 
747
    else
 
748
      wbf->Deactivate();
 
749
  }
 
750
}
 
751
 
 
752
-(NSMenu*)getContextMenu
 
753
{
 
754
  if ([[self superview] conformsToProtocol:@protocol(CHBrowserContainer)])
 
755
  {
 
756
    id<CHBrowserContainer> browserContainer = [self superview];
 
757
        return [browserContainer getContextMenu];
 
758
  }
 
759
  
 
760
  return nil;
 
761
}
 
762
 
 
763
-(NSWindow*)getNativeWindow
 
764
{
 
765
  NSWindow* window = [self window];
 
766
  if (window)
 
767
    return window; // We're visible.  Just hand the window back.
 
768
 
 
769
  // We're invisible.  It's likely that we're in a Cocoa tab view.
 
770
  // First see if we have a cached window.
 
771
  if (mWindow)
 
772
    return mWindow;
 
773
  
 
774
  // Finally, see if our parent responds to the getNativeWindow selector,
 
775
  // and if they do, let them handle it.
 
776
  if ([[self superview] conformsToProtocol:@protocol(CHBrowserContainer)])
 
777
  {
 
778
    id<CHBrowserContainer> browserContainer = [self superview];
 
779
    return [browserContainer getNativeWindow];
 
780
  }
 
781
    
 
782
  return nil;
 
783
}
 
784
 
 
785
 
 
786
//
 
787
// -findEventSink:forPoint:inWindow:
 
788
//
 
789
// Given a point in window coordinates, find the Gecko event sink of the ChildView
 
790
// the point is over. This involves first converting the point to this view's
 
791
// coordinate system and using hitTest: to get the subview. Then we get
 
792
// that view's widget and QI it to an event sink
 
793
//
 
794
- (void) findEventSink:(nsIEventSink**)outSink forPoint:(NSPoint)inPoint inWindow:(NSWindow*)inWind
 
795
{
 
796
  NSPoint localPoint = [self convertPoint:inPoint fromView:[inWind contentView]];
 
797
  NSView<mozView>* hitView = [self hitTest:localPoint];
 
798
  if ( [hitView conformsToProtocol:@protocol(mozView)] ) {
 
799
    nsCOMPtr<nsIEventSink> sink (do_QueryInterface([hitView widget]));
 
800
    *outSink = sink.get();
 
801
    NS_IF_ADDREF(*outSink);
 
802
  }
 
803
}
 
804
 
 
805
#pragma mark -
 
806
 
 
807
- (BOOL)shouldAcceptDrag:(id <NSDraggingInfo>)sender
 
808
{
 
809
  if ([[self superview] conformsToProtocol:@protocol(CHBrowserContainer)])
 
810
  {
 
811
    id<CHBrowserContainer> browserContainer = [self superview];
 
812
    return [browserContainer shouldAcceptDragFromSource:[sender draggingSource]];
 
813
  }
 
814
  return YES;
 
815
}
 
816
 
 
817
- (unsigned int)draggingEntered:(id <NSDraggingInfo>)sender
 
818
{
 
819
  if (![self shouldAcceptDrag:sender])
 
820
    return NSDragOperationNone;
 
821
 
 
822
//  NSLog(@"draggingEntered");  
 
823
  nsCOMPtr<nsIDragHelperService> helper(do_GetService("@mozilla.org/widget/draghelperservice;1"));
 
824
  mDragHelper = helper.get();
 
825
  NS_IF_ADDREF(mDragHelper);
 
826
  NS_ASSERTION ( mDragHelper, "Couldn't get a drag service, we're in big trouble" );
 
827
  
 
828
  if ( mDragHelper ) {
 
829
    mLastTrackedLocation = [sender draggingLocation];
 
830
    mLastTrackedWindow   = [sender draggingDestinationWindow];
 
831
    nsCOMPtr<nsIEventSink> sink;
 
832
    [self findEventSink:getter_AddRefs(sink) forPoint:mLastTrackedLocation inWindow:mLastTrackedWindow];
 
833
    if (sink)
 
834
      mDragHelper->Enter ( [sender draggingSequenceNumber], sink );
 
835
  }
 
836
  
 
837
  return NSDragOperationCopy;
 
838
}
 
839
 
 
840
- (void)draggingExited:(id <NSDraggingInfo>)sender
 
841
{
 
842
//  NSLog(@"draggingExited");
 
843
  if ( mDragHelper ) {
 
844
    nsCOMPtr<nsIEventSink> sink;
 
845
    
 
846
    [self findEventSink:getter_AddRefs(sink)
 
847
            forPoint:mLastTrackedLocation /* [sender draggingLocation] */
 
848
            inWindow:mLastTrackedWindow   /* [sender draggingDestinationWindow] */
 
849
            ];
 
850
    if (sink)
 
851
      mDragHelper->Leave( [sender draggingSequenceNumber], sink );
 
852
    NS_RELEASE(mDragHelper);     
 
853
  }
 
854
}
 
855
 
 
856
- (unsigned int)draggingUpdated:(id <NSDraggingInfo>)sender
 
857
{
 
858
  if (![self shouldAcceptDrag:sender])
 
859
    return NSDragOperationNone;
 
860
 
 
861
//  NSLog(@"draggingUpdated");
 
862
  PRBool dropAllowed = PR_FALSE;
 
863
  if ( mDragHelper ) {
 
864
    mLastTrackedLocation = [sender draggingLocation];
 
865
    mLastTrackedWindow   = [sender draggingDestinationWindow];
 
866
    nsCOMPtr<nsIEventSink> sink;
 
867
    [self findEventSink:getter_AddRefs(sink) forPoint:mLastTrackedLocation inWindow:mLastTrackedWindow];
 
868
    if (sink)
 
869
      mDragHelper->Tracking([sender draggingSequenceNumber], sink, &dropAllowed);
 
870
  }
 
871
  
 
872
  return dropAllowed ? NSDragOperationCopy : NSDragOperationNone;
 
873
}
 
874
 
 
875
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
 
876
{
 
877
  return YES;
 
878
}
 
879
 
 
880
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
 
881
{
 
882
  if (![self shouldAcceptDrag:sender])
 
883
    return NO;
 
884
 
 
885
  PRBool dragAccepted = PR_FALSE;
 
886
    
 
887
  if ( mDragHelper ) {
 
888
    nsCOMPtr<nsIEventSink> sink;
 
889
    [self findEventSink:getter_AddRefs(sink) forPoint:[sender draggingLocation]
 
890
            inWindow:[sender draggingDestinationWindow]];
 
891
    if (sink)
 
892
      mDragHelper->Drop([sender draggingSequenceNumber], sink, &dragAccepted);
 
893
  }
 
894
  
 
895
  return dragAccepted ? YES : NO;
 
896
}
 
897
 
 
898
#pragma mark -
 
899
 
 
900
-(BOOL)validateMenuItem: (NSMenuItem*)aMenuItem
 
901
{
 
902
  // update first responder items based on the selection
 
903
  SEL action = [aMenuItem action];
 
904
  if (action == @selector(cut:))
 
905
    return [self canCut];    
 
906
  else if (action == @selector(copy:))
 
907
    return [self canCopy];
 
908
  else if (action == @selector(paste:))
 
909
    return [self canPaste];
 
910
  else if (action == @selector(delete:))
 
911
    return [self canDelete];
 
912
  else if (action == @selector(undo:))
 
913
    return [self canUndo];
 
914
  else if (action == @selector(redo:))
 
915
    return [self canRedo];
 
916
  else if (action == @selector(selectAll:))
 
917
    return YES;
 
918
  
 
919
  return NO;
 
920
}
 
921
 
 
922
@end