зеркало из https://github.com/mozilla/pjs.git
Landing changes from CHIMERA_M1_0_1_BRANCH. (I know I'm breaking the static build, I'll fix it later). Code depending on other Mozilla changes is #ifdef'd BRANCH_CHANGES_NEED_MERGED.
This commit is contained in:
Родитель
065136c637
Коммит
4b5d102721
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -9,7 +9,7 @@
|
|||
#include "nsIPermission.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsString.h"
|
||||
|
||||
|
||||
// prefs for keychain password autofill
|
||||
static const char* const gUseKeychainPref = "chimera.store_passwords_with_keychain";
|
||||
|
@ -199,7 +199,7 @@ const int kDisableAllCookies = 2;
|
|||
if ( perm ) {
|
||||
nsXPIDLCString host;
|
||||
perm->GetHost(getter_Copies(host));
|
||||
mManager->Remove(nsDependentCString(host), 0); // could this api _be_ any worse? Come on!
|
||||
mManager->Remove(host, 0); // could this api _be_ any worse? Come on!
|
||||
|
||||
mCachedPermissions->RemoveElementAt(row);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
\readonlydoc1{\fonttbl\f0\fswiss\fcharset77 Optima-Bold;\f1\fswiss\fcharset77 Optima-Regular;\f2\fswiss\fcharset77 Helvetica;
|
||||
\f3\fnil\fcharset77 Monaco;}
|
||||
{\colortbl;\red255\green255\blue255;\red4\green16\blue255;}
|
||||
\margl1440\margr1440\vieww13740\viewh16200\viewkind0
|
||||
\margl1440\margr1440\vieww13940\viewh15220\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f0\b\fs48 \cf0 Chimera Read Me\
|
||||
|
@ -71,4 +71,7 @@ To find out more about Chimera, see the project page at:\
|
|||
\
|
||||
\cf2 http://www.mozilla.org/projects/chimera/\cf0 \
|
||||
\
|
||||
This page contains information about how to give feedback on Chimera, has links that allow you to query for known bugs, see what\'d5s going on with current development, and about how to build it yourself from source.}
|
||||
This page contains information about how to give feedback on Chimera, has links that allow you to query for known bugs, see what\'d5s going on with current development, and about how to build it yourself from source.\
|
||||
\
|
||||
There is also a Unix browser project called Chimera, which is unrelated to Chimera for OS X. More information about the Unix/X11 Chimera browser can be found at \cf2 http://www.chimera.org/\cf0 \
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
{\rtf1\mac\ansicpg10000\cocoartf102
|
||||
{\fonttbl\f0\fswiss\fcharset77 Optima-Bold;\f1\fswiss\fcharset77 Optima-Regular;\f2\fswiss\fcharset77 Optima-Italic;
|
||||
\f3\fnil\fcharset77 Monaco;}
|
||||
{\colortbl;\red255\green255\blue255;\red4\green16\blue255;}
|
||||
\margl1440\margr1440\vieww13340\viewh16360\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f0\b\fs48 \cf0 Chimera 0.7 Release Notes\
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f1\b0\fs24 \cf2 http://www.mozilla.org/projects/chimera/\cf0 \
|
||||
\
|
||||
\pard\tx720\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640
|
||||
\cf0 The following changes and improvements have been made since the Chimera 0.6 release.
\
|
||||
\pard\tx360\tx720\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\li720\fi-720\ql\qnatural
|
||||
\cf0 \
|
||||
|
||||
\f0\b Highlights
|
||||
\f1\b0 \
|
||||
\
|
||||
\'a5 New Download Manager, with auto-download and auto-dispatch.\
|
||||
\'a5 Compatible with URL Manager Pro\
|
||||
\'a5 Page Text Encodings menu\
|
||||
\'a5 Global History in the sidebar\
|
||||
\'a5 Send Link menu item, and other new toolbar buttons\
|
||||
\'a5 Dragging of images and links to the desktop, and other applications\
|
||||
\'a5 Support for Shockwave Directory content\
|
||||
\'a5 Uses Rendezvous to show local FTP and web servers\
|
||||
\'a5 Supports Proxy Auto-config\
|
||||
\
|
||||
|
||||
\f0\b Details\
|
||||
|
||||
\f1\b0 \
|
||||
|
||||
\f2\i User Interface
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 Chimera now has a Text Encoding submenu, allowing you to override the character set of a page when it doesn't display correctly.\
|
||||
\'a5 Chimera now supports the Menu Sharing protocol, allowing applications like URL Manager Pro to work.\
|
||||
\'a5 Popup windows no longer do an ugly resize-flash when they appear.\
|
||||
\'a5 If you type something in the URL bar before Chimera finishes loading the first page, it will no longer get replaced by the page URL.\
|
||||
\'a5 Global history is now visible in the sidebar (and is much faster than before).\
|
||||
\'a5 Redesigned content-generated dialogs (like cookie and JavaScript dialogs) to autosize. JS dialogs are identified by a \'d4[JavaScript Application]\'d5 label to avoid spoofing attacks now.\
|
||||
\
|
||||
|
||||
\f2\i Menus and Toolbars
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 New, brighter toolbar icons.\
|
||||
\'a5 Added a \'d2Send Link\'d3 command to the File menu (with an optional toolbar button), which opens a mail message with the URL of the current page in your favorite mail application.\
|
||||
\'a5 Added additional optional toolbar buttons for New Tab, Close Tab, Search etc.\
|
||||
\'a5 Added some new items to the context menus, relating to frames, and copying images.\
|
||||
\'a5 Added support for copying images to the clipboard, and dragging images and links to the desktop, and to other applications.\
|
||||
\'a5 Fixed an issue that would cause the wrong window to be used for loading a bookmark, or URL sometimes.\
|
||||
\'a5 The \'d2small icons\'d3 toolbar mode is shorter now to save screen space.\
|
||||
\
|
||||
|
||||
\f2\i Downloading
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 Downloads are now shown in a Download manager, reducing the number of open windows.\
|
||||
\'a5 If you quit while downloads are in progress, Chimera will warn you now.\
|
||||
\'a5 Downloads now start automatically, saving into your Downloads folder, without asking you where to save the file. Option-click a link if you want to specify a different location at which save the file.\
|
||||
\'a5 Added a preference (in the Downloads tab of the Navigation pane) to automatically dispatch downloaded files to helper applications. For security reasons, this defaults to being off.\
|
||||
\
|
||||
|
||||
\f2\i Plugins
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 Shockwave Director content now loads in Chimera.\
|
||||
\'a5 The Default plugin (which displays when you're missing the plugin for some content) correctly remembers which MIME type you've seen before now.\
|
||||
\'a5 Context menus for plugins now display correctly, RealPlayer video displays more reliably, and plugins are less likely to draw incorrectly when being scrolled.\
|
||||
\'a5 The QuickTime plugin now correctly handles more MIME types now.\
|
||||
\'a5 Fixed various MRJ (Java) plugin issues (but not, as yet, the problem of typing and dragging in applets).\
|
||||
\
|
||||
|
||||
\f2\i Web Page display
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 The default resolution was set to 96dpi, to better match other Mac browsers. You may have to adjust your preferred font sizes to compensate.\
|
||||
\'a5 The User-Agent string now contains \'d3Mach-O\'d3 and \'d2Chimera\'d3 to allow web authors to more accurately identify the browser.\
|
||||
\'a5 Framesets loaded in background tabs show correctly now\
|
||||
\'a5 Typing performance in textareas was somewhat improved.\
|
||||
\'a5 Tabbing to a text field now selects its content.\
|
||||
\'a5 If JavaScript on a page calls
|
||||
\f3\fs18 window.close()
|
||||
\f1\fs24 , we now close just the tab for that page, if there are multiple tabs.\
|
||||
\'a5 Form controls no longer draw in \'d3bold\'d3\
|
||||
\'a5 Pages loading in background tabs now show errors if the load fails, as they should.\
|
||||
\'a5 Chimera now respects the \'d2autocomplete=off\'d3 attribute on web forms, for sites that don't want username/password filling for security reasons.\
|
||||
\'a5 Fixed an issue with the sizing of form controls when zooming.\
|
||||
\'a5 Fixed some "smearing" display problems with absolutely-positioned elements.\
|
||||
\'a5 If you need to see JavaScript errors, you can set a hidden pref ("chimera.log_js_to_console") to have Chimera dump them to the console.\
|
||||
\
|
||||
|
||||
\f2\i Bookmarks
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 Command-clicking a toolbar link, or a bookmark in the sidebar will load it in a new tab now.\
|
||||
\'a5 You can put a bookmark folder in the Dock menu now (do a Get Info on a bookmark folder in Chimera). Mac OS X 10.2 only.\
|
||||
\'a5 It's now possible to convert a bookmarks tab group to a normal folder, and vice versa (via a checkbox in the bookmark Get Info panel).\
|
||||
\'a5 You can import Chimera-format bookmarks.xml files.\
|
||||
\'a5 It's now possible to export bookmarks to an HTML file now (via an item on the application menu)\
|
||||
\'a5 Site icons (\'d2favicons\'d3) are shown on the bookmarks toolbar now.\
|
||||
\
|
||||
|
||||
\f2\i Networking
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 Chimera will now pick up changes made to the system proxy settings (e.g. when you change Locations in the Network System Preferences) without having to be restarted.\
|
||||
\'a5 Chimera will only show \'d2Connection Refused\'d3 and \'d2Unknown host\'d3 errors for the main page now, rather than images and iframe contents. This helps those using proxy techniques for image blocking.\
|
||||
\
|
||||
|
||||
\f2\i Other Changes
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 The Print dialog now has a \'d2Web Browser\'d3 panel that allows you to control the printing of background colors and images, among other options.\
|
||||
\'a5 Chimera now supports the Services menu in web content.\
|
||||
\'a5 You can get the URL of the front window via AppleEvents now.\
|
||||
\'a5 Holding down the Shift key while using the scrollwheel scrolls sideways now.\
|
||||
\'a5 Fixed an issue with QuickDraw that caused a number of random crashes.\
|
||||
\'a5 Chimera will now run if your home directory is on a network volume.\
|
||||
\'a5 Some memory leaks were fixed.\
|
||||
\'a5 Added the ability to set the preferred minimum font size, in the Advanced panel of the Appearance font prefs.\
|
||||
\'a5 Fixed an issue where Chimera could use a lot of CPU when waking from sleep.\
|
||||
\'a5 Chimera is more compatible with the \'d2Metallizer\'d3 haxie now.\
|
||||
\
|
||||
|
||||
\f2\i Known issues
|
||||
\f1\i0 \
|
||||
\
|
||||
\'a5 Shockwave Director content displays at the wrong location in the window, if hardware rendering is enabled.\
|
||||
\'a5 Typing and dragging in Java applets does not work correctly.\
|
||||
\'a5 The Windows Media Player plugin is not compatible with Chimera.\
|
||||
\'a5 If you try to open Chimera's AppleScript dictionary, say from Script Editor, you\'d5ll get an error. To work around this, open the application package, and remove the \'d2Localized.rsrc\'d3 file in Contents/Resources/English.lproj. This will, however, prevent Shockwave Director content from loading so we recommend you do this on a copy of the application.\
|
||||
\'a5 Issues remain when typing in non-Roman languages; sometimes hitting the Delete key can cause Chimera to go Back, rather than deleting text.\
|
||||
\
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
|
||||
<!-- Contains mappings of character encodings (lowercase) to menu item tags in the Text Encoding menu. -->
|
||||
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>iso-8859-1</key>
|
||||
<integer>10</integer>
|
||||
<key>x-mac-roman</key>
|
||||
<integer>11</integer>
|
||||
|
||||
<key>iso-2022-jp</key>
|
||||
<integer>12</integer>
|
||||
<key>shift_jis</key>
|
||||
<integer>13</integer>
|
||||
<key>euc-jp</key>
|
||||
<integer>14</integer>
|
||||
|
||||
<key>big5</key>
|
||||
<integer>15</integer>
|
||||
<key>big5-hkscs</key>
|
||||
<integer>16</integer>
|
||||
|
||||
<key>iso-2022-kr</key>
|
||||
<integer>17</integer>
|
||||
<key>x-johab</key>
|
||||
<integer>18</integer>
|
||||
<key>x-windows-949</key>
|
||||
<integer>19</integer>
|
||||
|
||||
<key>iso-8859-6</key>
|
||||
<integer>20</integer>
|
||||
<key>windows-1256</key>
|
||||
<integer>21</integer>
|
||||
<key>iso-8859-8</key>
|
||||
<integer>22</integer>
|
||||
<key>windows-1255</key>
|
||||
<integer>23</integer>
|
||||
|
||||
<key>iso-8859-7</key>
|
||||
<integer>24</integer>
|
||||
<key>windows-1253</key>
|
||||
<integer>25</integer>
|
||||
|
||||
<key>iso-8859-5</key>
|
||||
<integer>26</integer>
|
||||
<key>x-mac-cyrillic</key>
|
||||
<integer>27</integer>
|
||||
<key>koi8-r</key>
|
||||
<integer>28</integer>
|
||||
<key>windows-1251</key>
|
||||
<integer>29</integer>
|
||||
|
||||
<key>tis-620</key>
|
||||
<integer>30</integer>
|
||||
|
||||
<key>gb2312</key>
|
||||
<integer>31</integer>
|
||||
<key>x-gbk</key>
|
||||
<integer>32</integer>
|
||||
<key>hz-gb-2312</key>
|
||||
<integer>33</integer>
|
||||
|
||||
<key>iso-8859-2</key>
|
||||
<integer>34</integer>
|
||||
<key>windows-1250</key>
|
||||
<integer>35</integer>
|
||||
<key>iso-8859-4</key>
|
||||
<integer>36</integer>
|
||||
|
||||
<key>windows-1258</key>
|
||||
<integer>37</integer>
|
||||
|
||||
<key>iso-8859-9</key>
|
||||
<integer>38</integer>
|
||||
<key>windows-1254</key>
|
||||
<integer>39</integer>
|
||||
|
||||
<key>windows-1257</key>
|
||||
<integer>40</integer>
|
||||
|
||||
<key>utf-8</key>
|
||||
<integer>41</integer>
|
||||
</dict>
|
||||
</plist>
|
|
@ -28,7 +28,7 @@
|
|||
<string>140 644 198 144 0 0 1152 848 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<string>291.0</string>
|
||||
<key>IBGroupedObjects</key>
|
||||
<dict>
|
||||
<key>7</key>
|
||||
|
|
Двоичные данные
camino/resources/localized/English.lproj/BrowserWindow.nib/objects.nib
сгенерированный
Двоичные данные
camino/resources/localized/English.lproj/BrowserWindow.nib/objects.nib
сгенерированный
Двоичный файл не отображается.
Двоичные данные
camino/resources/localized/English.lproj/Localizable.strings
Двоичные данные
camino/resources/localized/English.lproj/Localizable.strings
Двоичный файл не отображается.
|
@ -41,6 +41,7 @@
|
|||
pageSetup = id;
|
||||
previousTab = id;
|
||||
printPage = id;
|
||||
reloadWithCharset = id;
|
||||
savePage = id;
|
||||
sendURL = id;
|
||||
showAboutBox = id;
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>105 33 482 372 0 0 1600 1002 </string>
|
||||
<string>37 174 482 240 0 0 1152 848 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>644 623 277 90 0 0 1600 1002 </string>
|
||||
<key>29</key>
|
||||
<string>11 957 446 44 0 0 1600 1002 </string>
|
||||
<string>103 790 446 44 0 0 1152 848 </string>
|
||||
<key>494</key>
|
||||
<string>117 597 185 48 0 0 1280 1002 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<string>291.0</string>
|
||||
<key>IBGroupedObjects</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
|
|
Двоичный файл не отображается.
|
@ -86,15 +86,15 @@ nsDownloadListenerConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult
|
|||
|
||||
static const nsModuleComponentInfo gAppComponents[] = {
|
||||
{
|
||||
"Security Dialogs",
|
||||
"PSM Security Warnings",
|
||||
NS_SECURITYDIALOGS_CID,
|
||||
NS_BADCERTLISTENER_CONTRACTID,
|
||||
NS_SECURITYWARNINGDIALOGS_CONTRACTID,
|
||||
SecurityDialogsConstructor
|
||||
},
|
||||
{
|
||||
"Security Dialogs",
|
||||
"Bad Cert Handler",
|
||||
NS_SECURITYDIALOGS_CID,
|
||||
NS_SECURITYWARNINGDIALOGS_CONTRACTID,
|
||||
NS_BADCERTLISTENER_CONTRACTID,
|
||||
SecurityDialogsConstructor
|
||||
},
|
||||
{
|
||||
|
|
|
@ -89,6 +89,8 @@
|
|||
|
||||
SharedMenusObj* mSharedMenusObj;
|
||||
NetworkServices* mNetworkServices;
|
||||
|
||||
NSMutableDictionary* mCharsets;
|
||||
}
|
||||
|
||||
// File menu actions.
|
||||
|
@ -127,6 +129,7 @@
|
|||
-(IBAction) smallerTextSize:(id)aSender;
|
||||
-(IBAction) viewSource:(id)aSender;
|
||||
-(IBAction) manageSidebar: (id)aSender;
|
||||
-(IBAction) reloadWithCharset:(id)aSender;
|
||||
|
||||
// Bookmarks menu actions.
|
||||
-(IBAction) importBookmarks:(id)aSender;
|
||||
|
|
|
@ -150,6 +150,8 @@ const int kReuseWindowOnAE = 2;
|
|||
|
||||
-(void)dealloc
|
||||
{
|
||||
[mCharsets release];
|
||||
|
||||
// Terminate shared menus
|
||||
[mSharedMenusObj release];
|
||||
|
||||
|
@ -256,6 +258,10 @@ const int kReuseWindowOnAE = 2;
|
|||
while ((itemIndex = [mGoMenu indexOfItemWithTag:kRendezvousRelatedItemTag]) != -1)
|
||||
[mGoMenu removeItemAtIndex:itemIndex];
|
||||
}
|
||||
|
||||
// load up the charset dictionary with keys and menu titles.
|
||||
NSString* charsetPath = [NSBundle pathForResource:@"Charset" ofType:@"dict" inDirectory:[[NSBundle mainBundle] bundlePath]];
|
||||
mCharsets = [[NSDictionary dictionaryWithContentsOfFile:charsetPath] retain];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
|
@ -305,6 +311,9 @@ const int kReuseWindowOnAE = 2;
|
|||
|
||||
- (void)setupStartpage
|
||||
{
|
||||
// only do this if no url was specified in the command-line
|
||||
if (mStartURL) return;
|
||||
|
||||
// for non-nightly builds, show a special start page
|
||||
PreferenceManager* prefManager = [PreferenceManager sharedInstance];
|
||||
|
||||
|
@ -535,6 +544,18 @@ const int kReuseWindowOnAE = 2;
|
|||
[browserController reload: aSender];
|
||||
}
|
||||
|
||||
-(IBAction) reloadWithCharset:(id)aSender
|
||||
{
|
||||
// Figure out which charset to tell gecko to load based on the sender's tag. There
|
||||
// is guaranteed to only be 1 key that matches this tag, so we just take the first one.
|
||||
BrowserWindowController* browserController = [self getMainWindowBrowserController];
|
||||
if (browserController) {
|
||||
NSArray* charsetList = [mCharsets allKeysForObject:[NSNumber numberWithInt:[aSender tag]]];
|
||||
NS_ASSERTION([charsetList count] == 1, "OOPS, multiply defined charsets in plist");
|
||||
[browserController reloadWithNewCharset:[charsetList objectAtIndex:0]];
|
||||
}
|
||||
}
|
||||
|
||||
-(IBAction) doStop:(id)aSender
|
||||
{
|
||||
BrowserWindowController* browserController = [self getMainWindowBrowserController];
|
||||
|
@ -918,11 +939,34 @@ const int kReuseWindowOnAE = 2;
|
|||
{
|
||||
BrowserWindowController* browserController = [self getMainWindowBrowserController];
|
||||
|
||||
// Handle the encoding menu first, since there are many of those items. They're
|
||||
// identifyable because they have a specific tag.
|
||||
const int kEncodingMenuTag = 10;
|
||||
if ( [aMenuItem tag] >= kEncodingMenuTag ) {
|
||||
if ( browserController ) {
|
||||
NSString* charset = [browserController currentCharset];
|
||||
#if DEBUG_CHARSET
|
||||
NSLog(@"charset is %@", charset);
|
||||
#endif
|
||||
// given the document's charset, check if it maps to the same int as the
|
||||
// current item's key. If yes, we select this item because it's our charset.
|
||||
// Note that this relies on the key in the nib mapping to the right integer
|
||||
// in the plist.
|
||||
NSNumber* tag = [mCharsets objectForKey:[charset lowercaseString]];
|
||||
if ( tag && [[NSNumber numberWithInt:[aMenuItem tag]] isEqualToNumber:tag] )
|
||||
[aMenuItem setState:NSOnState];
|
||||
else
|
||||
[aMenuItem setState:NSOffState];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
// disable items that aren't relevant if there's no main browser window open
|
||||
SEL action = [aMenuItem action];
|
||||
|
||||
//NSLog(@"MainController validateMenuItem for %@ (%s)", [aMenuItem title], action);
|
||||
|
||||
|
||||
if (action == @selector(printPage:) ||
|
||||
/* ... many more items go here ... */
|
||||
/* action == @selector(goHome:) || */ // always enabled
|
||||
|
@ -1103,17 +1147,16 @@ const int kReuseWindowOnAE = 2;
|
|||
|
||||
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApp hasVisibleWindows:(BOOL)flag
|
||||
{
|
||||
// If AppKit knows what to do, let it.
|
||||
if (flag)
|
||||
return YES;
|
||||
|
||||
// If window available, wake it up. |mainWindow| should always be null.
|
||||
NSWindow* mainWindow = [mApplication mainWindow];
|
||||
if (!mainWindow)
|
||||
// ignore |hasVisibleWindows| because we always want to show a browser window when
|
||||
// the user clicks on the app icon, even if, say, prefs or the d/l window are open.
|
||||
// If there is no browser, create one. If there is one, bring it to the front and
|
||||
// unminimize it if it's down in the dock.
|
||||
NSWindow* frontBrowser = [self getFrontmostBrowserWindow];
|
||||
if ( !frontBrowser )
|
||||
[self newWindow:self];
|
||||
else { // Don't think this will ever happen, but just in case
|
||||
if ([[mainWindow windowController]respondsToSelector:@selector(showWindow:)])
|
||||
[[mainWindow windowController] showWindow:self];
|
||||
else {
|
||||
if ([[frontBrowser windowController] respondsToSelector:@selector(showWindow:)])
|
||||
[[frontBrowser windowController] showWindow:self];
|
||||
else
|
||||
[self newWindow:self];
|
||||
}
|
||||
|
|
|
@ -47,9 +47,20 @@ NSGETMODULE(_name) (nsIComponentManager* aCompMgr, \
|
|||
}
|
||||
|
||||
// NSGetModule entry points
|
||||
DECL_NSGETMODULE(UcharUtil)
|
||||
DECL_NSGETMODULE(nsUConvModule)
|
||||
DECL_NSGETMODULE(nsI18nModule)
|
||||
DECL_NSGETMODULE(nsUCvJAModule)
|
||||
DECL_NSGETMODULE(nsUCvCnModule)
|
||||
DECL_NSGETMODULE(nsUCvLatinModule)
|
||||
DECL_NSGETMODULE(nsUCvTWModule)
|
||||
DECL_NSGETMODULE(nsUCvTW2Module)
|
||||
DECL_NSGETMODULE(nsUCvKoModule)
|
||||
DECL_NSGETMODULE(nsLocaleModule)
|
||||
DECL_NSGETMODULE(nsStringBundleModule)
|
||||
DECL_NSGETMODULE(nsLWBrkModule)
|
||||
DECL_NSGETMODULE(nsCharDetModule)
|
||||
DECL_NSGETMODULE(xpconnect)
|
||||
DECL_NSGETMODULE(cacheservice)
|
||||
DECL_NSGETMODULE(necko_core_and_primary_protocols)
|
||||
DECL_NSGETMODULE(necko_secondary_protocols)
|
||||
DECL_NSGETMODULE(nsURILoaderModule)
|
||||
|
@ -60,9 +71,14 @@ DECL_NSGETMODULE(nsChromeModule)
|
|||
DECL_NSGETMODULE(nsRDFModule)
|
||||
DECL_NSGETMODULE(nsParserModule)
|
||||
DECL_NSGETMODULE(nsGfxMacModule)
|
||||
DECL_NSGETMODULE(nsGfx2Module)
|
||||
DECL_NSGETMODULE(nsImageLib2Module)
|
||||
DECL_NSGETMODULE(nsPNGDecoderModule)
|
||||
DECL_NSGETMODULE(nsGIFModule2)
|
||||
DECL_NSGETMODULE(nsJPEGDecoderModule)
|
||||
DECL_NSGETMODULE(nsPluginModule)
|
||||
DECL_NSGETMODULE(javascript__protocol)
|
||||
DECL_NSGETMODULE(JS_component_loader)
|
||||
DECL_NSGETMODULE(DOM_components)
|
||||
DECL_NSGETMODULE(nsViewModule)
|
||||
DECL_NSGETMODULE(nsWidgetMacModule)
|
||||
|
@ -74,6 +90,7 @@ DECL_NSGETMODULE(embedcomponents)
|
|||
DECL_NSGETMODULE(Browser_Embedding_Module)
|
||||
DECL_NSGETMODULE(nsEditorModule)
|
||||
DECL_NSGETMODULE(nsTransactionManagerModule)
|
||||
DECL_NSGETMODULE(nsTextServicesModule)
|
||||
DECL_NSGETMODULE(nsProfileModule)
|
||||
DECL_NSGETMODULE(Session_History_Module)
|
||||
DECL_NSGETMODULE(application)
|
||||
|
@ -89,9 +106,20 @@ DECL_NSGETMODULE(NSS)
|
|||
*/
|
||||
static nsStaticModuleInfo gStaticModuleInfo[] = {
|
||||
#define MODULE(_name) { (#_name), NSGETMODULE(_name) }
|
||||
MODULE(UcharUtil),
|
||||
MODULE(nsUConvModule),
|
||||
MODULE(nsI18nModule),
|
||||
MODULE(nsUCvJAModule),
|
||||
MODULE(nsUCvCnModule),
|
||||
MODULE(nsUCvLatinModule),
|
||||
MODULE(nsUCvTWModule),
|
||||
MODULE(nsUCvTW2Module),
|
||||
MODULE(nsUCvKoModule),
|
||||
MODULE(nsLocaleModule),
|
||||
MODULE(nsStringBundleModule),
|
||||
MODULE(nsLWBrkModule),
|
||||
MODULE(nsCharDetModule),
|
||||
MODULE(xpconnect),
|
||||
MODULE(cacheservice),
|
||||
MODULE(necko_core_and_primary_protocols),
|
||||
MODULE(necko_secondary_protocols),
|
||||
MODULE(nsURILoaderModule),
|
||||
|
@ -102,9 +130,14 @@ MODULE(nsChromeModule),
|
|||
MODULE(nsRDFModule),
|
||||
MODULE(nsParserModule),
|
||||
MODULE(nsGfxMacModule),
|
||||
MODULE(nsGfx2Module),
|
||||
MODULE(nsImageLib2Module),
|
||||
MODULE(nsPNGDecoderModule),
|
||||
MODULE(nsGIFModule2),
|
||||
MODULE(nsJPEGDecoderModule),
|
||||
MODULE(nsPluginModule),
|
||||
MODULE(javascript__protocol),
|
||||
MODULE(JS_component_loader),
|
||||
MODULE(DOM_components),
|
||||
MODULE(nsViewModule),
|
||||
MODULE(nsWidgetMacModule),
|
||||
|
@ -116,6 +149,7 @@ MODULE(embedcomponents),
|
|||
MODULE(Browser_Embedding_Module),
|
||||
MODULE(nsEditorModule),
|
||||
MODULE(nsTransactionManagerModule),
|
||||
MODULE(nsTextServicesModule),
|
||||
MODULE(nsProfileModule),
|
||||
MODULE(Session_History_Module),
|
||||
MODULE(application),
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef BookmarksExport_h__
|
||||
#define BookmarksExport_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIDOMElement;
|
||||
|
||||
class BookmarksExport
|
||||
{
|
||||
public:
|
||||
|
||||
BookmarksExport(nsIDOMDocument* inBookmarksDoc, const char* inLinebreakStr = "\n");
|
||||
~BookmarksExport();
|
||||
|
||||
// at some point we could use subclassing to support different export formats
|
||||
nsresult ExportBookmarksToHTML(const nsAString& inFilePath);
|
||||
|
||||
protected:
|
||||
|
||||
nsresult SetupOutputStream(const nsAString& inFilePath);
|
||||
void CloseOutputStream();
|
||||
|
||||
// return false on failure (mWriteStatus set)
|
||||
bool WriteChildren(nsIDOMElement* inElement, PRInt32 inDepth);
|
||||
bool WriteItem(nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot = PR_FALSE);
|
||||
|
||||
void WritePrologue();
|
||||
void WriteString(const char*inString, PRInt32 inLen);
|
||||
void WriteLinebreak();
|
||||
|
||||
protected:
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> mBookmarksDocument;
|
||||
nsCOMPtr<nsIOutputStream> mOutputStream;
|
||||
const char* mLinebreakStr;
|
||||
nsresult mWriteStatus;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BookmarksExport_h__
|
|
@ -47,11 +47,12 @@
|
|||
#include "nsILocalFile.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
/*
|
||||
Netscape HTML bookmarks format is:
|
||||
|
|
|
@ -658,11 +658,10 @@ BookmarksService::SaveBookmarksToFile(const nsAString& inFileName)
|
|||
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), bookmarksTempFile);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRUint32 bytesWritten = 0;
|
||||
|
||||
if (writeDocType)
|
||||
{
|
||||
const char* const kDocTypeString = "<!DOCTYPE bookmarks SYSTEM \"http://www.mozilla.org/DTDs/ChimeraBookmarks.dtd\">\n";
|
||||
PRUint32 bytesWritten = 0;
|
||||
rv = outputStream->Write(kDocTypeString, strlen(kDocTypeString), &bytesWritten);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
|
|
@ -81,13 +81,14 @@
|
|||
- (void) closePopup;
|
||||
- (void) resizePopup;
|
||||
- (BOOL) isOpen;
|
||||
- (BOOL) userHasTyped;
|
||||
|
||||
- (void) onRowClicked:(NSNotification *)aNote;
|
||||
- (void) onBlur:(NSNotification *)aNote;
|
||||
- (void) onResize:(NSNotification *)aNote;
|
||||
- (void) onUndoOrRedo:(NSNotification *)aNote;
|
||||
|
||||
- (void) setStringUndoably:(NSString*)aString fromLocation:(unsigned int)aLocation;
|
||||
- (void) setURI:(NSString*)aURI;
|
||||
- (id) fieldEditor;
|
||||
|
||||
@end
|
||||
|
|
|
@ -54,7 +54,6 @@ class AutoCompleteListener : public nsIAutoCompleteListener
|
|||
public:
|
||||
AutoCompleteListener(AutoCompleteTextField* aTextField)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mTextField = aTextField;
|
||||
}
|
||||
|
||||
|
@ -79,6 +78,7 @@ NS_IMPL_ISUPPORTS1(AutoCompleteListener, nsIAutoCompleteListener)
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
@interface AutoCompleteTextField(Private)
|
||||
- (void)cleanup;
|
||||
- (void) setStringUndoably:(NSString*)aString fromLocation:(unsigned int)aLocation;
|
||||
@end
|
||||
|
||||
@implementation AutoCompleteTextField
|
||||
|
@ -372,6 +372,18 @@ NS_IMPL_ISUPPORTS1(AutoCompleteListener, nsIAutoCompleteListener)
|
|||
return [mPopupWin isVisible];
|
||||
}
|
||||
|
||||
//
|
||||
// -userHasTyped
|
||||
//
|
||||
// Returns whether the user has typed anything into the url bar since the last
|
||||
// time the url was set (by loading a page). We know this is the case by looking
|
||||
// at if there is a search string.
|
||||
//
|
||||
- (BOOL) userHasTyped
|
||||
{
|
||||
return ( mSearchString != nil );
|
||||
}
|
||||
|
||||
// url completion ////////////////////////////
|
||||
|
||||
- (void) completeDefaultResult
|
||||
|
@ -447,6 +459,25 @@ NS_IMPL_ISUPPORTS1(AutoCompleteListener, nsIAutoCompleteListener)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// -setURI
|
||||
//
|
||||
// the public way to change the url string so that it does the right thing for handling
|
||||
// autocomplete and completions in progress
|
||||
//
|
||||
- (void) setURI:(NSString*)aURI
|
||||
{
|
||||
// if the urlbar has focus (actually if its field editor has focus), we
|
||||
// need to use one of its routines to update the autocomplete status or
|
||||
// we could find ourselves with stale results and the popup still open. If
|
||||
// it doesn't have focus, we can bypass all that and just use normal routines.
|
||||
if ( [[self window] firstResponder] == [self fieldEditor] )
|
||||
[self setStringUndoably:aURI fromLocation:0]; // updates autocomplete correctly
|
||||
else
|
||||
[self setStringValue:aURI];
|
||||
}
|
||||
|
||||
- (void) setStringUndoably:(NSString *)aString fromLocation:(unsigned int)aLocation
|
||||
{
|
||||
NSTextView *fieldEditor = [self fieldEditor];
|
||||
|
@ -554,16 +585,23 @@ NS_IMPL_ISUPPORTS1(AutoCompleteListener, nsIAutoCompleteListener)
|
|||
- (void)controlTextDidChange:(NSNotification *)aNote
|
||||
{
|
||||
NSTextView *fieldEditor = [[aNote userInfo] objectForKey:@"NSFieldEditor"];
|
||||
|
||||
// we are here either because the user is typing or they are selecting
|
||||
// an item in the autocomplete popup. When they are typing, the location of
|
||||
// the selection will be non-zero (wherever the insertion point is). When
|
||||
// they autocomplete, the length and the location will both be zero.
|
||||
// We use this info in the following way: if they are typing or backspacing,
|
||||
// restart the search and no longer use the selection in the popup.
|
||||
NSRange range = [fieldEditor selectedRange];
|
||||
// make sure we're typing at the end of the string
|
||||
if (range.location == [[fieldEditor string] length]) {
|
||||
NSString* currentText = [fieldEditor string];
|
||||
if ([currentText length] && range.location) {
|
||||
// when we ask for a NSTextView string, Cocoa returns
|
||||
// a pointer to the view's backing store. So, the value
|
||||
// of the string continually changes as we edit the text view.
|
||||
// Since we'll edit the text view as we add in autocomplete results,
|
||||
// we've got to make a copy of the string as it currently stands
|
||||
// to know what we were searching for in the first place.
|
||||
NSString *searchString = [[fieldEditor string] copyWithZone:nil];
|
||||
NSString *searchString = [currentText copyWithZone:nil];
|
||||
[self startSearch:searchString complete:!mBackspaced];
|
||||
[searchString release];
|
||||
}
|
||||
|
@ -575,7 +613,7 @@ NS_IMPL_ISUPPORTS1(AutoCompleteListener, nsIAutoCompleteListener)
|
|||
|
||||
- (void)controlTextDidEndEditing:(NSNotification *)aNote
|
||||
{
|
||||
[self closePopup];
|
||||
[self clearResults];
|
||||
[[[[aNote userInfo] objectForKey:@"NSFieldEditor"] undoManager] removeAllActions];
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,12 @@
|
|||
|
||||
- (void)removeTabViewItem:(NSTabViewItem *)tabViewItem
|
||||
{
|
||||
// the normal behavior of the tab widget is to select the tab to the left
|
||||
// of the tab being removed. Users, however, want the tab to the right to
|
||||
// be selected. This also matches how mozilla works. Select the right tab
|
||||
// first so we don't take the hit of displaying the left tab before we switch.
|
||||
if ( [self selectedTabViewItem] == tabViewItem )
|
||||
[self selectNextTabViewItem:self];
|
||||
[super removeTabViewItem:tabViewItem];
|
||||
[self showOrHideTabsAsAppropriate];
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ typedef enum
|
|||
@class PageProxyIcon;
|
||||
@class BrowserContentView;
|
||||
@class BrowserTabViewItem;
|
||||
@class AutoCompleteTextField;
|
||||
|
||||
@interface BrowserWindowController : NSWindowController<Find>
|
||||
{
|
||||
|
@ -101,7 +102,7 @@ typedef enum
|
|||
IBOutlet NSTabView* mSidebarTabView;
|
||||
IBOutlet NSTabView* mSidebarSourceTabView;
|
||||
IBOutlet NSView* mLocationToolbarView;
|
||||
IBOutlet NSTextField* mURLBar;
|
||||
IBOutlet AutoCompleteTextField* mURLBar;
|
||||
IBOutlet NSTextField* mStatus;
|
||||
IBOutlet NSProgressIndicator* mProgress; // STRONG reference
|
||||
IBOutlet NSImageView* mLock;
|
||||
|
@ -258,6 +259,9 @@ typedef enum
|
|||
- (IBAction)stop:(id)aSender;
|
||||
- (IBAction)home:(id)aSender;
|
||||
|
||||
- (IBAction)reloadWithNewCharset:(NSString*)charset;
|
||||
- (NSString*)currentCharset;
|
||||
|
||||
- (IBAction)frameToNewWindow:(id)sender;
|
||||
- (IBAction)frameToNewTab:(id)sender;
|
||||
- (IBAction)frameToThisWindow:(id)sender;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#import "BrowserTabView.h"
|
||||
#import "UserDefaults.h"
|
||||
#import "PageProxyIcon.h"
|
||||
#import "AutoCompleteTextField.h"
|
||||
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
@ -1316,16 +1317,9 @@ static NSArray* sToolbarDefaults = nil;
|
|||
- (void)updateLocationFields:(NSString *)locationString
|
||||
{
|
||||
if ( [locationString isEqual:@"about:blank"] )
|
||||
locationString = @"";
|
||||
locationString = @""; // return;
|
||||
|
||||
// if the urlbar has focus (actually if its field editor has focus), we
|
||||
// need to use one of its routines to update the autocomplete status or
|
||||
// we could find ourselves with stale results and the popup still open. If
|
||||
// it doesn't have focus, we can bypass all that and just use normal routines.
|
||||
if ( [[self window] firstResponder] == [mURLBar fieldEditor] )
|
||||
[mURLBar setStringUndoably:locationString fromLocation:0]; // updates autocomplete correctly
|
||||
else
|
||||
[mURLBar setStringValue:locationString];
|
||||
[mURLBar setURI:locationString];
|
||||
[mLocationSheetURLField setStringValue:locationString];
|
||||
|
||||
// don't call [window display] here, no matter how much you might want
|
||||
|
@ -1619,10 +1613,13 @@ static NSArray* sToolbarDefaults = nil;
|
|||
|
||||
[newTab setLabel: NSLocalizedString(@"TabLoading", @"")];
|
||||
|
||||
[newView loadURI:aURLSpec referrer:aReferrer flags:NSLoadFlagsNone activate:!aLoadInBG];
|
||||
|
||||
// unless we're told to load this tab in the bg, select the tab
|
||||
// before we load so that it's the primary and will push the url into
|
||||
// the url bar immediately rather than waiting for the server.
|
||||
if (!aLoadInBG)
|
||||
[mTabBrowser selectTabViewItem: newTab];
|
||||
|
||||
[newView loadURI:aURLSpec referrer:aReferrer flags:NSLoadFlagsNone activate:!aLoadInBG];
|
||||
}
|
||||
|
||||
- (void)openTabGroup:(NSArray*)urlArray replaceExistingTabs:(BOOL)replaceExisting
|
||||
|
@ -1815,8 +1812,11 @@ static NSArray* sToolbarDefaults = nil;
|
|||
{
|
||||
menuPrototype = mImageMenu;
|
||||
}
|
||||
else if ((mContextMenuFlags & nsIContextMenuListener::CONTEXT_DOCUMENT) != 0)
|
||||
else if (!mContextMenuFlags || (mContextMenuFlags & nsIContextMenuListener::CONTEXT_DOCUMENT) != 0)
|
||||
{
|
||||
// if there aren't any flags or we're in the background of a page,
|
||||
// show the document menu. This prevents us from failing to find a case
|
||||
// and not showing the context menu.
|
||||
menuPrototype = mPageMenu;
|
||||
[mBackItem setEnabled: [[mBrowserView getBrowserView] canGoBack]];
|
||||
[mForwardItem setEnabled: [[mBrowserView getBrowserView] canGoForward]];
|
||||
|
@ -2056,7 +2056,7 @@ static NSArray* sToolbarDefaults = nil;
|
|||
BOOL oldResponderIsGecko = [self isResponderGeckoView:oldResponder];
|
||||
BOOL newResponderIsGecko = [self isResponderGeckoView:newResponder];
|
||||
|
||||
if (oldResponderIsGecko != newResponderIsGecko)
|
||||
if (oldResponderIsGecko != newResponderIsGecko && [[self window] isKeyWindow])
|
||||
[[mBrowserView getBrowserView] setActive:newResponderIsGecko];
|
||||
}
|
||||
|
||||
|
@ -2088,6 +2088,18 @@ static NSArray* sToolbarDefaults = nil;
|
|||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)reloadWithNewCharset:(NSString*)charset
|
||||
{
|
||||
[mBrowserView reloadWithNewCharset:charset];
|
||||
}
|
||||
|
||||
- (NSString*)currentCharset
|
||||
{
|
||||
return [mBrowserView currentCharset];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
|
|
@ -40,10 +40,11 @@
|
|||
|
||||
@class BrowserWindowController;
|
||||
@class ToolTip;
|
||||
@class AutoCompleteTextField;
|
||||
|
||||
@interface BrowserWrapper : NSView <CHBrowserListener, CHBrowserContainer>
|
||||
{
|
||||
NSTextField* mUrlbar;
|
||||
AutoCompleteTextField* mUrlbar;
|
||||
NSTextField* mStatus;
|
||||
BrowserWindowController* mWindowController;
|
||||
NSTabViewItem* mTabItem;
|
||||
|
@ -98,6 +99,9 @@
|
|||
- (void)setTab: (NSTabViewItem*)tab;
|
||||
- (NSTabViewItem*) tab;
|
||||
|
||||
- (IBAction)reloadWithNewCharset:(NSString*)charset;
|
||||
- (NSString*)currentCharset;
|
||||
|
||||
- (NSWindow*)getNativeWindow;
|
||||
- (NSMenu*)getContextMenu;
|
||||
- (void)setIsBookmarksImport:(BOOL)aIsImport;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#import "ToolTip.h"
|
||||
#import "PageProxyIcon.h"
|
||||
#import "KeychainService.h"
|
||||
#import "AutoCompleteTextField.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
@ -64,8 +65,6 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "CHBrowserService.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
|
||||
#include <QuickDraw.h>
|
||||
|
||||
|
@ -241,7 +240,7 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
|||
// update the window's title.
|
||||
[self setTabTitle:mTabTitle windowTitle:mTitle];
|
||||
|
||||
if ([[self window] isKeyWindow])
|
||||
if ([[self window] isKeyWindow] && ![mUrlbar userHasTyped])
|
||||
[mBrowserView setActive: YES];
|
||||
|
||||
nsCOMPtr<nsIIOService> ioService(do_GetService(ioServiceContractID));
|
||||
|
@ -257,9 +256,12 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
|||
name:kOfflineNotificationName
|
||||
object:nil];
|
||||
|
||||
// Update the URL bar.
|
||||
[mWindowController updateLocationFields:[self getCurrentURLSpec]];
|
||||
[mWindowController updateSiteIcons:mSiteIconImage];
|
||||
// Update the URL bar, but only if the user hasn't put something of their
|
||||
// own in there.
|
||||
if (![mUrlbar userHasTyped]) {
|
||||
[mWindowController updateLocationFields:[self getCurrentURLSpec]];
|
||||
[mWindowController updateSiteIcons:mSiteIconImage];
|
||||
}
|
||||
|
||||
if (mWindowController && !mListenersAttached)
|
||||
{
|
||||
|
@ -309,6 +311,11 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
|||
|
||||
- (void)loadURI:(NSString *)urlSpec referrer:(NSString*)referrer flags:(unsigned int)flags activate:(BOOL)activate
|
||||
{
|
||||
// blast it into the urlbar immediately so that we know what we're
|
||||
// trying to load, even if it doesn't work
|
||||
if (mIsPrimary)
|
||||
[mWindowController updateLocationFields:urlSpec];
|
||||
|
||||
mActivateOnLoad = activate;
|
||||
[mBrowserView loadURI:urlSpec referrer:referrer flags:flags];
|
||||
}
|
||||
|
@ -343,25 +350,14 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
|||
{
|
||||
if (mActivateOnLoad) {
|
||||
// if we're the front/key window, focus the content area. If we're not,
|
||||
// tell the focus controller that the content area should be focused when
|
||||
// we do finally become the key window
|
||||
if ( [NSApp keyWindow] == [mBrowserView window] )
|
||||
[mBrowserView setActive:YES];
|
||||
else {
|
||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||
nsCOMPtr<nsIWebBrowser> webBrowser = getter_AddRefs([mBrowserView getWebBrowser]);
|
||||
if ( webBrowser ) {
|
||||
webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
|
||||
if ( domWindow ) {
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow ( do_QueryInterface(domWindow) );
|
||||
nsCOMPtr<nsIFocusController> controller;
|
||||
piWindow->GetRootFocusController(getter_AddRefs(controller));
|
||||
if ( controller ) {
|
||||
nsCOMPtr<nsIDOMWindowInternal> windowInt ( do_QueryInterface(domWindow) );
|
||||
controller->SetFocusedWindow(windowInt);
|
||||
}
|
||||
}
|
||||
}
|
||||
// set gecko as the first responder so that it will be activated when
|
||||
// the window is focused. If the user is typing in the urlBar, however,
|
||||
// don't mess with the focus at all.
|
||||
if ( ![mUrlbar userHasTyped] ) {
|
||||
if ( [[mBrowserView window] isKeyWindow] )
|
||||
[mBrowserView setActive:YES];
|
||||
else
|
||||
[[mBrowserView window] makeFirstResponder:mBrowserView];
|
||||
}
|
||||
mActivateOnLoad = NO;
|
||||
}
|
||||
|
@ -445,7 +441,8 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
|||
if (!siteIconLoadInitiated)
|
||||
[self updateSiteIconImage:nil withURI:faviconURI];
|
||||
|
||||
if (mIsPrimary)
|
||||
// if the user has started typing something, don't destroy it
|
||||
if (mIsPrimary && ![mUrlbar userHasTyped])
|
||||
[mWindowController updateLocationFields:urlSpec];
|
||||
}
|
||||
|
||||
|
@ -848,4 +845,16 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
|||
return [[[self getBrowserView] getCurrentURI] isEqualToString:@"about:blank"];
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)reloadWithNewCharset:(NSString*)charset
|
||||
{
|
||||
[[self getBrowserView] reloadWithNewCharset:charset];
|
||||
}
|
||||
|
||||
- (NSString*)currentCharset
|
||||
{
|
||||
return [[self getBrowserView] currentCharset];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIPromptService.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
class CocoaPromptService : public nsIPromptService
|
||||
|
|
|
@ -271,7 +271,7 @@ int KeychainPrefChangedCallback(const char* inPref, void* unused)
|
|||
//
|
||||
attr.tag = kAccountKCItemAttr;
|
||||
attr.data = (char*)[username UTF8String];
|
||||
attr.length = strlen(attr.data);
|
||||
attr.length = strlen(NS_REINTERPRET_CAST(const char*, attr.data));
|
||||
status = KCSetAttribute(inItemRef, &attr);
|
||||
if(status != noErr)
|
||||
NSLog(@"Couldn't update keychain item account");
|
||||
|
@ -522,7 +522,6 @@ NS_IMPL_ISUPPORTS2(KeychainPrompt,
|
|||
|
||||
KeychainPrompt::KeychainPrompt()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
KeychainPrompt::~KeychainPrompt()
|
||||
|
@ -532,14 +531,15 @@ KeychainPrompt::~KeychainPrompt()
|
|||
|
||||
|
||||
//
|
||||
// TODO: add support for ftp username/password. The given realm for
|
||||
// an ftp server has the form ftp://<username>@<server>/<path>, see
|
||||
// netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp.
|
||||
// TODO: add support for ftp username/password.
|
||||
//
|
||||
// Get server name and port from the realm ("hostname:port (realm)",
|
||||
// see nsHttpChannel.cpp). we can't use CFURL routines or nsIURI
|
||||
// routines because they require a protocol, and we don't have one.
|
||||
//
|
||||
// The given realm for an ftp server has the form ftp://<username>@<server>/<path>, see
|
||||
// netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp).
|
||||
//
|
||||
void
|
||||
KeychainPrompt::ExtractHostAndPort(const PRUnichar* inRealm, NSString** outHost, PRInt32* outPort)
|
||||
{
|
||||
|
@ -548,20 +548,40 @@ KeychainPrompt::ExtractHostAndPort(const PRUnichar* inRealm, NSString** outHost,
|
|||
*outHost = @"";
|
||||
*outPort = kAnyPort;
|
||||
|
||||
// strip off the "(realm)" part
|
||||
NSString* realmStr = [NSString stringWithPRUnichars:inRealm];
|
||||
NSRange firstParen = [realmStr rangeOfString:@"("];
|
||||
if ( firstParen.location == NSNotFound )
|
||||
firstParen.location = [realmStr length];
|
||||
realmStr = [realmStr substringToIndex:firstParen.location-1];
|
||||
|
||||
// separate the host and the port
|
||||
NSRange endOfHost = [realmStr rangeOfString:@":"];
|
||||
if ( endOfHost.location == NSNotFound )
|
||||
*outHost = realmStr;
|
||||
|
||||
// first check for an ftp url and pull out the server from the realm
|
||||
if ( [realmStr rangeOfString:@"ftp://"].location != NSNotFound ) {
|
||||
// cut out ftp://
|
||||
realmStr = [realmStr substringFromIndex:strlen("ftp://")];
|
||||
|
||||
// cut out any of the path
|
||||
NSRange pathDelimeter = [realmStr rangeOfString:@"/"];
|
||||
if ( pathDelimeter.location != NSNotFound )
|
||||
realmStr = [realmStr substringToIndex:pathDelimeter.location-1];
|
||||
|
||||
// now we're left with "username@server" with username being optional
|
||||
NSRange usernameMarker = [realmStr rangeOfString:@"@"];
|
||||
if ( usernameMarker.location != NSNotFound )
|
||||
*outHost = [realmStr substringFromIndex:usernameMarker.location+1];
|
||||
else
|
||||
*outHost = realmStr;
|
||||
}
|
||||
else {
|
||||
*outHost = [realmStr substringToIndex:endOfHost.location];
|
||||
*outPort = [[realmStr substringFromIndex:endOfHost.location+1] intValue];
|
||||
// we're an http url, strip off the "(realm)" part
|
||||
NSRange firstParen = [realmStr rangeOfString:@"("];
|
||||
if ( firstParen.location == NSNotFound )
|
||||
firstParen.location = [realmStr length];
|
||||
realmStr = [realmStr substringToIndex:firstParen.location-1];
|
||||
|
||||
// separate the host and the port
|
||||
NSRange endOfHost = [realmStr rangeOfString:@":"];
|
||||
if ( endOfHost.location == NSNotFound )
|
||||
*outHost = realmStr;
|
||||
else {
|
||||
*outHost = [realmStr substringToIndex:endOfHost.location];
|
||||
*outPort = [[realmStr substringFromIndex:endOfHost.location+1] intValue];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,7 +732,6 @@ NS_IMPL_ISUPPORTS2(KeychainFormSubmitObserver,
|
|||
|
||||
KeychainFormSubmitObserver::KeychainFormSubmitObserver()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
//NSLog(@"Keychain form submit observer created.");
|
||||
}
|
||||
|
||||
|
@ -755,7 +774,9 @@ KeychainFormSubmitObserver::Notify(nsIContent* node, nsIDOMWindowInternal* windo
|
|||
passwordElement->GetValue(pword);
|
||||
NSString* username = [NSString stringWith_nsAString:uname];
|
||||
NSString* password = [NSString stringWith_nsAString:pword];
|
||||
|
||||
if ( ![username length] || ![password length] ) // bail if either is empty
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
node->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
|
@ -950,8 +971,16 @@ KeychainFormSubmitObserver::CheckChangeDataYN(nsIDOMWindowInternal* window)
|
|||
[username assignTo_nsAString:user];
|
||||
[password assignTo_nsAString:pwd];
|
||||
|
||||
rv = usernameElement->SetValue(user);
|
||||
rv = passwordElement->SetValue(pwd);
|
||||
// if the server specifies a value attribute (bug 169760), only autofill
|
||||
// the password if what we have in keychain matches what the server supplies,
|
||||
// otherwise don't. Don't bother checking the password field for a value; i can't
|
||||
// imagine the server ever prefilling a password
|
||||
nsAutoString userValue;
|
||||
usernameElement->GetAttribute(NS_LITERAL_STRING("value"), userValue);
|
||||
if (!userValue.Length() || userValue.Equals(user)) {
|
||||
rv = usernameElement->SetValue(user);
|
||||
rv = passwordElement->SetValue(pwd);
|
||||
}
|
||||
}
|
||||
|
||||
// We found the sign-in form so return now. This means we don't
|
||||
|
@ -1015,6 +1044,13 @@ FindUsernamePasswordFields(nsIDOMHTMLFormElement* inFormElement, nsIDOMHTMLInput
|
|||
return NS_ERROR_FAILURE;
|
||||
*outUsername = *outPassword = nsnull;
|
||||
|
||||
// pages can specify that they don't want autofill by setting a
|
||||
// "autocomplete=off" attribute on the form.
|
||||
nsAutoString autocomplete;
|
||||
inFormElement->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
|
||||
if ( autocomplete.EqualsIgnoreCase("off") )
|
||||
return NS_OK;
|
||||
|
||||
//
|
||||
// Search the form the password field and the preceding text field
|
||||
// We are only interested in signon forms, so we require
|
||||
|
@ -1056,6 +1092,9 @@ FindUsernamePasswordFields(nsIDOMHTMLFormElement* inFormElement, nsIDOMHTMLInput
|
|||
|
||||
bool isText = (type.IsEmpty() || type.Equals(NS_LITERAL_STRING("text"), nsCaseInsensitiveStringComparator()));
|
||||
bool isPassword = type.Equals(NS_LITERAL_STRING("password"), nsCaseInsensitiveStringComparator());
|
||||
inputElement->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
|
||||
if ( autocomplete.EqualsIgnoreCase("off") )
|
||||
isPassword = false;
|
||||
|
||||
if(!isText && !isPassword)
|
||||
continue;
|
||||
|
|
|
@ -195,6 +195,7 @@ nsresult RemoteURILoadManager::RequestURILoad(const nsAString& inURI, id<RemoteL
|
|||
|
||||
nsLoadFlags loadFlags = (allowNetworking) ? nsIRequest::LOAD_NORMAL : nsIRequest::LOAD_FROM_CACHE;
|
||||
loadFlags |= nsIRequest::LOAD_BACKGROUND; // don't show progress or cookie dialogs
|
||||
|
||||
if (!allowNetworking)
|
||||
loadFlags |= nsICachingChannel::LOAD_ONLY_FROM_CACHE;
|
||||
|
||||
|
@ -204,7 +205,7 @@ nsresult RemoteURILoadManager::RequestURILoad(const nsAString& inURI, id<RemoteL
|
|||
rv = NS_NewChannel(getter_AddRefs(channel), uri, nsnull, mLoadGroup,
|
||||
nsnull, loadFlags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
nsCOMPtr<nsIStreamLoader> streamLoader;
|
||||
rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), channel, this, loaderContext) ; // , mLoadGroup, nsnull, loadFlags);
|
||||
if (NS_FAILED(rv))
|
||||
|
|
|
@ -52,12 +52,12 @@ public:
|
|||
virtual ~SecurityDialogs();
|
||||
|
||||
NS_DECL_ISUPPORTS;
|
||||
NS_DECL_NSIBADCERTLISTENER
|
||||
NS_DECL_NSISECURITYWARNINGDIALOGS
|
||||
NS_DECL_NSIBADCERTLISTENER;
|
||||
NS_DECL_NSISECURITYWARNINGDIALOGS;
|
||||
|
||||
private:
|
||||
nsresult EnsureSecurityStringBundle();
|
||||
|
||||
|
||||
nsresult AlertDialog(nsIInterfaceRequestor* ctx, const char* prefName,
|
||||
const PRUnichar* messageName,
|
||||
const PRUnichar* showAgainName);
|
||||
|
|
|
@ -57,12 +57,11 @@ SecurityDialogs::~SecurityDialogs()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(SecurityDialogs, nsIBadCertListener, nsISecurityWarningDialogs)
|
||||
NS_IMPL_ISUPPORTS2(SecurityDialogs, nsIBadCertListener, nsISecurityWarningDialogs);
|
||||
|
||||
// nsIBadCertListener implementation
|
||||
/* boolean confirmUnknownIssuer (in nsIInterfaceRequestor socketInfo,
|
||||
in nsIX509Cert cert,
|
||||
out short certAddType); */
|
||||
in nsIX509Cert cert, out addType); */
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmUnknownIssuer(nsIInterfaceRequestor *socketInfo,
|
||||
nsIX509Cert *cert, PRInt16 *outAddType,
|
||||
|
@ -148,9 +147,11 @@ SecurityDialogs::NotifyCrlNextupdate(nsIInterfaceRequestor *socketInfo,
|
|||
#define MIXEDCONTENT_PREF "security.warn_viewing_mixed"
|
||||
#define INSECURE_SUBMIT_PREF "security.warn_submit_insecure"
|
||||
|
||||
// XXXbryner should we make these real confirmation dialogs?
|
||||
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmEnteringSecure(nsIInterfaceRequestor *ctx,
|
||||
PRBool *canceled)
|
||||
PRBool *_retval)
|
||||
{
|
||||
// I don't think any user cares they're entering a secure site.
|
||||
#if 0
|
||||
|
@ -159,15 +160,15 @@ SecurityDialogs::ConfirmEnteringSecure(nsIInterfaceRequestor *ctx,
|
|||
NS_LITERAL_STRING("EnterSecureShowAgain").get());
|
||||
#endif
|
||||
|
||||
*canceled = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmEnteringWeak(nsIInterfaceRequestor *ctx,
|
||||
PRBool *canceled)
|
||||
PRBool *_retval)
|
||||
{
|
||||
*canceled = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return AlertDialog(ctx, WEAK_SITE_PREF,
|
||||
NS_LITERAL_STRING("WeakSecureMessage").get(),
|
||||
NS_LITERAL_STRING("WeakSecureShowAgain").get());
|
||||
|
@ -175,9 +176,9 @@ SecurityDialogs::ConfirmEnteringWeak(nsIInterfaceRequestor *ctx,
|
|||
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmLeavingSecure(nsIInterfaceRequestor *ctx,
|
||||
PRBool *canceled)
|
||||
PRBool *_retval)
|
||||
{
|
||||
*canceled = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return AlertDialog(ctx, LEAVE_SITE_PREF,
|
||||
NS_LITERAL_STRING("LeaveSecureMessage").get(),
|
||||
NS_LITERAL_STRING("LeaveSecureShowAgain").get());
|
||||
|
@ -185,9 +186,9 @@ SecurityDialogs::ConfirmLeavingSecure(nsIInterfaceRequestor *ctx,
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmMixedMode(nsIInterfaceRequestor *ctx, PRBool *canceled)
|
||||
SecurityDialogs::ConfirmMixedMode(nsIInterfaceRequestor *ctx, PRBool *_retval)
|
||||
{
|
||||
*canceled = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return AlertDialog(ctx, MIXEDCONTENT_PREF,
|
||||
NS_LITERAL_STRING("MixedContentMessage").get(),
|
||||
NS_LITERAL_STRING("MixedContentShowAgain").get());
|
||||
|
|
|
@ -39,44 +39,13 @@
|
|||
|
||||
@interface nsAlertController : NSObject
|
||||
{
|
||||
IBOutlet id alertCheckPanel;
|
||||
IBOutlet id alertCheckPanelCheck;
|
||||
IBOutlet id alertCheckPanelText;
|
||||
IBOutlet id alertPanel;
|
||||
IBOutlet id alertPanelText;
|
||||
IBOutlet id confirmCheckPanel;
|
||||
IBOutlet id confirmCheckPanelCheck;
|
||||
IBOutlet id confirmCheckPanelText;
|
||||
IBOutlet id confirmCheckPanelButton1;
|
||||
IBOutlet id confirmCheckPanelButton2;
|
||||
IBOutlet id confirmPanel;
|
||||
IBOutlet id confirmPanelText;
|
||||
IBOutlet id confirmPanelButton1;
|
||||
IBOutlet id confirmPanelButton2;
|
||||
IBOutlet id promptPanel;
|
||||
IBOutlet id promptPanelCheck;
|
||||
IBOutlet id promptPanelText;
|
||||
IBOutlet id promptPanelInput;
|
||||
IBOutlet id passwordPanel;
|
||||
IBOutlet id passwordPanelCheck;
|
||||
IBOutlet id passwordPanelText;
|
||||
IBOutlet id passwordPanelInput;
|
||||
IBOutlet id postToInsecureFromSecurePanel;
|
||||
IBOutlet id securityMismatchPanel;
|
||||
IBOutlet id expiredCertPanel;
|
||||
IBOutlet id securityUnknownPanel;
|
||||
IBOutlet id usernamePanel;
|
||||
IBOutlet id usernamePanelCheck;
|
||||
IBOutlet id usernamePanelText;
|
||||
IBOutlet id usernamePanelPassword;
|
||||
IBOutlet id usernamePanelUserName;
|
||||
IBOutlet id owner;
|
||||
// all dialogs are now created on the fly and sized to fit
|
||||
}
|
||||
|
||||
- (IBAction)hitButton1:(id)sender;
|
||||
- (IBAction)hitButton2:(id)sender;
|
||||
- (IBAction)hitButton3:(id)sender;
|
||||
|
||||
- (void)awakeFromNib;
|
||||
- (void)alert:(NSWindow*)parent title:(NSString*)title text:(NSString*)text;
|
||||
- (void)alertCheck:(NSWindow*)parent title:(NSString*)title text:(NSString*)text checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue;
|
||||
|
||||
|
|
|
@ -42,6 +42,79 @@
|
|||
|
||||
enum { kOKButton = 0, kCancelButton = 1, kOtherButton = 2 };
|
||||
|
||||
const int kMinDialogWidth = 500;
|
||||
const int kMaxDialogHeight = 400;
|
||||
const int kMinDialogHeight = 130;
|
||||
const int kIconSize = 64;
|
||||
const int kWindowBorder = 20;
|
||||
const int kIconMargin = 16; // space between the icon and text content
|
||||
const int kButtonMinWidth = 82;
|
||||
const int kButtonMaxWidth = 200;
|
||||
const int kButtonHeight = 32;
|
||||
const int kButtonRightMargin = 14; // space between right edge of button and window
|
||||
const int kButtonBottomMargin = 12; // space between bottom edge of button and window
|
||||
const int kGeneralViewSpace = 9; // space between one view and another (vertically)
|
||||
const int kViewButtonSpace = 16; // space between the bottom view and the buttons
|
||||
const int kMaxFieldHeight = 100;
|
||||
const int kCheckBoxWidth = 20;
|
||||
const int kCheckBoxHeight = 18;
|
||||
const int kTextFieldHeight = 19;
|
||||
const int kStaticTextFieldHeight = 14; // height of non-editable non-bordered text fields
|
||||
const int kFieldLabelSpacer = 4; // space between a static label and an editabe text field (horizontal)
|
||||
const int kOtherAltButtonSpace = 25; // minimum space between the 'other' and 'alternate' buttons
|
||||
const int kButtonEndCapWidth = 14;
|
||||
const int kLabelCheckboxAdjustment = 2; // # pixels the label must be pushed down to line up with checkbox
|
||||
|
||||
|
||||
//
|
||||
// QDCoordsView
|
||||
//
|
||||
// A view that uses the QD coordinate space (top left is (0,0))
|
||||
//
|
||||
|
||||
@interface QDCoordsView : NSView
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation QDCoordsView
|
||||
|
||||
- (BOOL) isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface nsAlertController (nsAlertControllerPrivateMethods)
|
||||
|
||||
- (NSPanel*)getAlertPanelWithTitle:(NSString*)title
|
||||
message:(NSString*)message
|
||||
defaultButton:(NSString*)defaultLabel
|
||||
altButton:(NSString*)altLabel
|
||||
otherButton:(NSString*)otherLabel
|
||||
extraView:(NSView*)extraView
|
||||
lastResponder:(NSView*)lastResponder;
|
||||
|
||||
- (NSButton*)makeButtonWithTitle:(NSString*)title;
|
||||
|
||||
- (float)getContentWidthWithDefaultButton:(NSString*)defStr alternateButton:(NSString*)altStr otherButton:(NSString*)otherStr;
|
||||
- (NSTextField*)getTitleView:(NSString*)title withWidth:(float)width;
|
||||
- (NSTextField*)getLabelView:(NSString*)title withWidth:(float)width;
|
||||
- (NSView*)getLoginField:(NSTextField**)field withWidth:(float)width;
|
||||
- (NSView*)getPasswordField:(NSSecureTextField**)field withWidth:(float)width;
|
||||
- (int)getLoginTextLabelSize;
|
||||
- (NSView*)getMessageView:(NSString*)message withWidth:(float)width maxHeight:(float)maxHeight smallFont:(BOOL)useSmallFont;
|
||||
- (NSView*)getCheckboxView:(NSButton**)checkBox withLabel:(NSString*)label andWidth:(float)width;
|
||||
|
||||
-(void)tester:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation nsAlertController
|
||||
|
||||
- (IBAction)hitButton1:(id)sender
|
||||
|
@ -59,239 +132,283 @@ enum { kOKButton = 0, kCancelButton = 1, kOtherButton = 2 };
|
|||
[NSApp stopModalWithCode:kOtherButton];
|
||||
}
|
||||
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
CHBrowserService::SetAlertController(self);
|
||||
}
|
||||
|
||||
- (void)alert:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
{
|
||||
[alertPanelText setStringValue:text];
|
||||
[alertPanel setTitle:title];
|
||||
|
||||
[NSApp runModalForWindow:alertPanel relativeToWindow:parent];
|
||||
|
||||
[alertPanel close];
|
||||
{
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: NSLocalizedString(@"OKButtonText", @"") altButton: nil otherButton: nil extraView: nil lastResponder:nil];
|
||||
[NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
}
|
||||
|
||||
- (void)alertCheck:(NSWindow*)parent title:(NSString*)title text:(NSString*)text checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue
|
||||
{
|
||||
[alertCheckPanelText setStringValue:text];
|
||||
[alertCheckPanel setTitle:title];
|
||||
// set up check box view
|
||||
NSButton* checkBox = nil;
|
||||
float width = [self getContentWidthWithDefaultButton: NSLocalizedString(@"OKButtonText", @"") alternateButton: nil otherButton: nil];
|
||||
NSView* checkboxView = [self getCheckboxView: &checkBox withLabel: checkMsg andWidth: width];
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[alertCheckPanelCheck setState:state];
|
||||
[alertCheckPanelCheck setTitle:checkMsg];
|
||||
[checkBox setState:state];
|
||||
|
||||
// get panel and display it
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: NSLocalizedString(@"OKButtonText", @"") altButton: nil otherButton: nil extraView: checkboxView lastResponder: checkBox];
|
||||
[panel setInitialFirstResponder: checkBox];
|
||||
|
||||
[NSApp runModalForWindow:alertCheckPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([alertCheckPanelCheck state] == NSOnState);
|
||||
[alertCheckPanel close];
|
||||
[NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
*checkValue = ([checkBox state] == NSOnState);
|
||||
[panel close];
|
||||
}
|
||||
|
||||
- (BOOL)confirm:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
{
|
||||
[confirmPanelText setStringValue:text];
|
||||
[confirmPanel setTitle:title];
|
||||
|
||||
int result = [NSApp runModalForWindow:confirmPanel relativeToWindow:parent];
|
||||
|
||||
[confirmPanel close];
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: NSLocalizedString(@"OKButtonText", @"") altButton: NSLocalizedString(@"CancelButtonText", @"") otherButton: nil extraView: nil lastResponder: nil];
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (BOOL)confirmCheck:(NSWindow*)parent title:(NSString*)title text:(NSString*)text checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue
|
||||
{
|
||||
[confirmCheckPanelText setStringValue:text];
|
||||
[confirmCheckPanel setTitle:title];
|
||||
// get button titles
|
||||
NSString* okButton = NSLocalizedString(@"OKButtonText", @"");
|
||||
NSString* cancelButton = NSLocalizedString(@"CancelButtonText", @"");
|
||||
|
||||
// set up check box view
|
||||
NSButton* checkBox = nil;
|
||||
float width = [self getContentWidthWithDefaultButton: okButton alternateButton: cancelButton otherButton: nil];
|
||||
NSView* checkboxView = [self getCheckboxView: &checkBox withLabel: checkMsg andWidth: width];
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[confirmCheckPanelCheck setState:state];
|
||||
[confirmCheckPanelCheck setTitle:checkMsg];
|
||||
[checkBox setState:state];
|
||||
|
||||
// get panel and display it
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: okButton altButton: cancelButton otherButton: nil extraView: checkboxView lastResponder: checkBox];
|
||||
[panel setInitialFirstResponder: checkBox];
|
||||
|
||||
int result = [NSApp runModalForWindow:confirmCheckPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([confirmCheckPanelCheck state] == NSOnState);
|
||||
[confirmCheckPanel close];
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
*checkValue = ([checkBox state] == NSOnState);
|
||||
[panel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (int)confirmEx:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
button1:(NSString*)btn1 button2:(NSString*)btn2 button3:(NSString*)btn3
|
||||
- (int)confirmEx:(NSWindow*)parent title:(NSString*)title text:(NSString*)text button1:(NSString*)btn1 button2:(NSString*)btn2 button3:(NSString*)btn3
|
||||
{
|
||||
[confirmPanelText setStringValue:text];
|
||||
[confirmPanel setTitle:title];
|
||||
|
||||
[confirmPanelButton1 setTitle:btn1];
|
||||
[confirmPanelButton2 setTitle:btn2];
|
||||
|
||||
int result = [NSApp runModalForWindow:confirmPanel relativeToWindow:parent];
|
||||
|
||||
[confirmPanel close];
|
||||
|
||||
return result;
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: btn1 altButton: btn2 otherButton: btn3 extraView: nil lastResponder: nil];
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
return result;
|
||||
}
|
||||
|
||||
- (int)confirmCheckEx:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
button1:(NSString*)btn1 button2:(NSString*)btn2 button3:(NSString*)btn3
|
||||
checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue
|
||||
- (int)confirmCheckEx:(NSWindow*)parent title:(NSString*)title text:(NSString*)text button1:(NSString*)btn1 button2:(NSString*)btn2 button3:(NSString*)btn3 checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue
|
||||
{
|
||||
[confirmCheckPanelText setStringValue:text];
|
||||
[confirmCheckPanel setTitle:title];
|
||||
// set up check box view
|
||||
NSButton* checkBox = nil;
|
||||
float width = [self getContentWidthWithDefaultButton: btn1 alternateButton: btn2 otherButton: btn3];
|
||||
NSView* checkboxView = [self getCheckboxView: &checkBox withLabel: checkMsg andWidth: width];
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[confirmCheckPanelCheck setState:state];
|
||||
[confirmCheckPanelCheck setTitle:checkMsg];
|
||||
|
||||
[confirmCheckPanelButton1 setTitle:btn1];
|
||||
[confirmCheckPanelButton2 setTitle:btn2];
|
||||
[checkBox setState:state];
|
||||
|
||||
int result = [NSApp runModalForWindow:confirmCheckPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([confirmCheckPanelCheck state] == NSOnState);
|
||||
[confirmCheckPanel close];
|
||||
// get panel and display it
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: btn1 altButton: btn2 otherButton: btn3 extraView: checkboxView lastResponder: checkBox];
|
||||
[panel setInitialFirstResponder: checkBox];
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
*checkValue = ([checkBox state] == NSOnState);
|
||||
[panel close];
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)prompt:(NSWindow*)parent title:(NSString*)title text:(NSString*)text promptText:(NSMutableString*)promptText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck
|
||||
{
|
||||
[promptPanelText setStringValue:text];
|
||||
[promptPanel setTitle:title];
|
||||
NSString* okButton = NSLocalizedString(@"OKButtonText", @"");
|
||||
NSString* cancelButton = NSLocalizedString(@"CancelButtonText", @"");
|
||||
float width = [self getContentWidthWithDefaultButton: okButton alternateButton: cancelButton otherButton: nil];
|
||||
NSView* extraView = [[[NSView alloc] initWithFrame: NSMakeRect(0, 0, width, kTextFieldHeight)] autorelease];;
|
||||
|
||||
// set up input field
|
||||
NSTextField* field = [[[NSTextField alloc] initWithFrame: NSMakeRect(0, 0, width, kTextFieldHeight)] autorelease];
|
||||
[[field cell] setControlSize: NSSmallControlSize];
|
||||
[field setStringValue: promptText];
|
||||
[field selectText: nil];
|
||||
[field setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];
|
||||
[field setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin];
|
||||
[extraView addSubview: field];
|
||||
[extraView setNextKeyView: field];
|
||||
|
||||
// set up check box view, and combine the checkbox and field into the entire extra view
|
||||
NSButton* checkBox = nil;
|
||||
if (doCheck) {
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[promptPanelCheck setState:state];
|
||||
[promptPanelCheck setTransparent:NO];
|
||||
NSView* checkboxView = [self getCheckboxView: &checkBox withLabel: checkMsg andWidth: width];
|
||||
[checkBox setState:state];
|
||||
[checkboxView setFrameOrigin: NSMakePoint(0, 0)];
|
||||
[extraView setFrameSize: NSMakeSize(width, kTextFieldHeight + kGeneralViewSpace + NSHeight([checkboxView frame]))];
|
||||
[extraView addSubview: checkboxView];
|
||||
[field setNextKeyView: checkBox];
|
||||
}
|
||||
else {
|
||||
[promptPanelCheck setTransparent:YES];
|
||||
}
|
||||
[promptPanelCheck setTitle:checkMsg];
|
||||
[promptPanelInput setStringValue:promptText];
|
||||
|
||||
// get panel and display it
|
||||
NSView* lastResponder = (doCheck ? (NSView*)checkBox : (NSView*)field);
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: okButton altButton: cancelButton otherButton: nil extraView: extraView lastResponder:lastResponder];
|
||||
[panel setInitialFirstResponder: field];
|
||||
|
||||
int result = [NSApp runModalForWindow:promptPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([promptPanelCheck state] == NSOnState);
|
||||
|
||||
NSString* value = [promptPanelInput stringValue];
|
||||
PRUint32 length = [promptText length];
|
||||
if (length) {
|
||||
NSRange all;
|
||||
all.location = 0;
|
||||
all.length = [promptText length];
|
||||
[promptText deleteCharactersInRange:all];
|
||||
}
|
||||
[promptText appendString:value];
|
||||
|
||||
[promptPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
|
||||
[promptText setString: [field stringValue]];
|
||||
|
||||
if (doCheck)
|
||||
*checkValue = ([checkBox state] == NSOnState);
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)promptUserNameAndPassword:(NSWindow*)parent title:(NSString*)title text:(NSString*)text userNameText:(NSMutableString*)userNameText passwordText:(NSMutableString*)passwordText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck
|
||||
{
|
||||
[usernamePanelText setStringValue:text];
|
||||
[usernamePanel setTitle:title];
|
||||
NSString* okButton = NSLocalizedString(@"OKButtonText", @"");
|
||||
NSString* cancelButton = NSLocalizedString(@"CancelButtonText", @"");
|
||||
float width = [self getContentWidthWithDefaultButton: okButton alternateButton: cancelButton otherButton: nil];
|
||||
NSView* extraView = [[[NSView alloc] initWithFrame: NSMakeRect(0, 0, width, 2*kTextFieldHeight + kGeneralViewSpace)] autorelease];
|
||||
|
||||
// set up username field
|
||||
NSTextField* userField = nil;
|
||||
NSView* userView = [self getLoginField: &userField withWidth: width];
|
||||
[userView setAutoresizingMask: NSViewMinYMargin];
|
||||
[userView setFrameOrigin: NSMakePoint(0, kTextFieldHeight + kGeneralViewSpace)];
|
||||
[userField setStringValue: userNameText];
|
||||
[extraView addSubview: userView];
|
||||
[extraView setNextKeyView: userField];
|
||||
|
||||
// set up password field
|
||||
NSSecureTextField* passField = nil;
|
||||
NSView* passView = [self getPasswordField: &passField withWidth: width];
|
||||
[passView setAutoresizingMask: NSViewMinYMargin];
|
||||
[passView setFrameOrigin: NSMakePoint(0, 0)];
|
||||
[passField setStringValue: passwordText];
|
||||
[extraView addSubview: passView];
|
||||
[userField setNextKeyView: passField];
|
||||
|
||||
// set up check box view, and combine the checkbox and field into the entire extra view
|
||||
NSButton* checkBox = nil;
|
||||
if (doCheck) {
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[usernamePanelCheck setState:state];
|
||||
[usernamePanelCheck setTransparent:NO];
|
||||
NSView* checkboxView = [self getCheckboxView: &checkBox withLabel: checkMsg andWidth: width];
|
||||
[checkBox setState:state];
|
||||
[checkboxView setFrameOrigin: NSMakePoint(0, 0)];
|
||||
[extraView setFrameSize: NSMakeSize(width, 2*kTextFieldHeight + 2*kGeneralViewSpace + NSHeight([checkboxView frame]))];
|
||||
[extraView addSubview: checkboxView];
|
||||
[passField setNextKeyView: checkBox];
|
||||
}
|
||||
else {
|
||||
[usernamePanelCheck setTransparent:YES];
|
||||
}
|
||||
[usernamePanelCheck setTitle:checkMsg];
|
||||
[usernamePanelPassword setStringValue:passwordText];
|
||||
[usernamePanelUserName setStringValue:userNameText];
|
||||
|
||||
// get panel and display it
|
||||
NSView* lastResponder = (doCheck ? (NSView*)checkBox : (NSView*)passField);
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: okButton altButton: cancelButton otherButton: nil extraView: extraView lastResponder:lastResponder];
|
||||
[panel setInitialFirstResponder: userField];
|
||||
|
||||
int result = [NSApp runModalForWindow:usernamePanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([usernamePanelCheck state] == NSOnState);
|
||||
|
||||
NSString* value = [usernamePanelUserName stringValue];
|
||||
PRUint32 length = [userNameText length];
|
||||
if (length) {
|
||||
NSRange all;
|
||||
all.location = 0;
|
||||
all.length = [userNameText length];
|
||||
[userNameText deleteCharactersInRange:all];
|
||||
}
|
||||
[userNameText appendString:value];
|
||||
|
||||
value = [usernamePanelPassword stringValue];
|
||||
length = [passwordText length];
|
||||
if (length) {
|
||||
NSRange all;
|
||||
all.location = 0;
|
||||
all.length = [passwordText length];
|
||||
[passwordText deleteCharactersInRange:all];
|
||||
}
|
||||
[passwordText appendString:value];
|
||||
|
||||
[usernamePanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
|
||||
[userNameText setString: [userField stringValue]];
|
||||
[passwordText setString: [passField stringValue]];
|
||||
|
||||
if (doCheck)
|
||||
*checkValue = ([checkBox state] == NSOnState);
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (BOOL)promptPassword:(NSWindow*)parent title:(NSString*)title text:(NSString*)text passwordText:(NSMutableString*)passwordText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck
|
||||
- (BOOL)promptPassword:(NSWindow*)parent title:(NSString*)title text:(NSString*)text passwordText:(NSMutableString*)passwordText
|
||||
checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck
|
||||
{
|
||||
[passwordPanelText setStringValue:text];
|
||||
[passwordPanel setTitle:title];
|
||||
NSString* okButton = NSLocalizedString(@"OKButtonText", @"");
|
||||
NSString* cancelButton = NSLocalizedString(@"CancelButtonText", @"");
|
||||
float width = [self getContentWidthWithDefaultButton: okButton alternateButton: cancelButton otherButton: nil];
|
||||
NSView* extraView = [[[NSView alloc] initWithFrame: NSMakeRect(0, 0, width, kTextFieldHeight)] autorelease];;
|
||||
|
||||
// set up input field
|
||||
NSSecureTextField* passField = nil;
|
||||
NSView* passView = [self getPasswordField: &passField withWidth: width];
|
||||
[passView setAutoresizingMask: NSViewMinYMargin];
|
||||
[passView setFrameOrigin: NSMakePoint(0, 0)];
|
||||
[passField setStringValue: passwordText];
|
||||
[extraView addSubview: passView];
|
||||
[extraView setNextKeyView: passField];
|
||||
|
||||
// set up check box view, and combine the checkbox and field into the entire extra view
|
||||
NSButton* checkBox = nil;
|
||||
if (doCheck) {
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[passwordPanelCheck setState:state];
|
||||
[passwordPanelCheck setTransparent:NO];
|
||||
NSView* checkboxView = [self getCheckboxView: &checkBox withLabel: checkMsg andWidth: width];
|
||||
[checkBox setState:state];
|
||||
[checkboxView setFrameOrigin: NSMakePoint(0, 0)];
|
||||
[extraView setFrameSize: NSMakeSize(width, kTextFieldHeight + kGeneralViewSpace + NSHeight([checkboxView frame]))];
|
||||
[extraView addSubview: checkboxView];
|
||||
[passField setNextKeyView: checkBox];
|
||||
}
|
||||
else {
|
||||
[passwordPanelCheck setTransparent:YES];
|
||||
}
|
||||
[passwordPanelCheck setTitle:checkMsg];
|
||||
[passwordPanelInput setStringValue:passwordText];
|
||||
|
||||
// get panel and display it
|
||||
NSView* lastResponder = (doCheck ? (NSView*)checkBox : (NSView*)passField);
|
||||
NSPanel* panel = [self getAlertPanelWithTitle: title message: text defaultButton: okButton altButton: cancelButton otherButton: nil extraView: extraView lastResponder:lastResponder];
|
||||
[panel setInitialFirstResponder: passField];
|
||||
|
||||
int result = [NSApp runModalForWindow:passwordPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([passwordPanelCheck state] == NSOnState);
|
||||
|
||||
NSString* value = [passwordPanelInput stringValue];
|
||||
PRUint32 length = [passwordText length];
|
||||
if (length) {
|
||||
NSRange all;
|
||||
all.location = 0;
|
||||
all.length = [passwordText length];
|
||||
[passwordText deleteCharactersInRange:all];
|
||||
}
|
||||
[passwordText appendString:value];
|
||||
|
||||
[passwordPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
|
||||
[passwordText setString: [passField stringValue]];
|
||||
|
||||
if (doCheck)
|
||||
*checkValue = ([checkBox state] == NSOnState);
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)postToInsecureFromSecure:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:postToInsecureFromSecurePanel relativeToWindow:parent];
|
||||
[postToInsecureFromSecurePanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
NSString* title = NSLocalizedString(@"Security Warning", @"");
|
||||
NSString* message = NSLocalizedString(@"Post To Insecure", @"");
|
||||
NSString* continueButton = NSLocalizedString(@"ContinueButton", @"");
|
||||
NSString* stopButton = NSLocalizedString(@"StopButton", @"");
|
||||
|
||||
id panel = NSGetAlertPanel(title, message, continueButton, stopButton, nil);
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
NSReleaseAlertPanel(panel);
|
||||
|
||||
return (result == NSAlertDefaultReturn);
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)badCert:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:securityMismatchPanel relativeToWindow:parent];
|
||||
[securityMismatchPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
NSString* title = NSLocalizedString(@"Security Warning", @"");
|
||||
NSString* message = NSLocalizedString(@"Security Mismatch", @"");
|
||||
NSString* continueButton = NSLocalizedString(@"ContinueButton", @"");
|
||||
NSString* stopButton = NSLocalizedString(@"StopButton", @"");
|
||||
|
||||
id panel = NSGetAlertPanel(title, message, continueButton, stopButton, nil);
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
NSReleaseAlertPanel(panel);
|
||||
|
||||
return (result == NSAlertDefaultReturn);
|
||||
}
|
||||
|
||||
- (BOOL)expiredCert:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:expiredCertPanel relativeToWindow:parent];
|
||||
[expiredCertPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
NSString* title = NSLocalizedString(@"Security Warning", @"");
|
||||
NSString* message = NSLocalizedString(@"Expired Certification", @"");
|
||||
NSString* continueButton = NSLocalizedString(@"ContinueButton", @"");
|
||||
NSString* stopButton = NSLocalizedString(@"StopButton", @"");
|
||||
|
||||
id panel = NSGetAlertPanel(title, message, continueButton, stopButton, nil);
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
NSReleaseAlertPanel(panel);
|
||||
|
||||
return (result == NSAlertDefaultReturn);
|
||||
}
|
||||
|
||||
|
||||
|
@ -299,10 +416,413 @@ enum { kOKButton = 0, kCancelButton = 1, kOtherButton = 2 };
|
|||
{
|
||||
// this dialog is a little backward, with "Stop" returning 0, and the default returning
|
||||
// 1. That's just how nsIBadCertListener defines its constants. *shrug*
|
||||
int result = [NSApp runModalForWindow:securityUnknownPanel relativeToWindow:parent];
|
||||
[securityUnknownPanel close];
|
||||
NSString* title = NSLocalizedString(@"Security Warning", @"");
|
||||
NSString* message = NSLocalizedString(@"Unknown Certification", @"");
|
||||
NSString* alwaysAcceptButton = NSLocalizedString(@"Accept Always", @"");
|
||||
NSString* oneAcceptButton = NSLocalizedString(@"Accept Once", @"");
|
||||
NSString* stopButton = NSLocalizedString(@"StopButton", @"");
|
||||
|
||||
id panel = NSGetAlertPanel(title, message, oneAcceptButton, stopButton, alwaysAcceptButton);
|
||||
|
||||
return result;
|
||||
int result = [NSApp runModalForWindow: panel relativeToWindow:parent];
|
||||
[panel close];
|
||||
NSReleaseAlertPanel(panel);
|
||||
|
||||
int returnValue;
|
||||
if (result == NSAlertDefaultReturn)
|
||||
returnValue = 1;
|
||||
else if (result == NSAlertOtherReturn)
|
||||
returnValue = 2;
|
||||
else
|
||||
returnValue = 0;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
// implementation of private methods
|
||||
|
||||
// The content width is determined by how much space is needed to display all 3 buttons,
|
||||
// since every other view in the dialog can wrap if necessary
|
||||
- (float)getContentWidthWithDefaultButton:(NSString*)defStr alternateButton:(NSString*)altStr otherButton:(NSString*)otherStr
|
||||
{
|
||||
NSButton* defButton = [self makeButtonWithTitle: defStr];
|
||||
NSButton* altButton = [self makeButtonWithTitle: altStr];
|
||||
NSButton* otherButton = [self makeButtonWithTitle: otherStr];
|
||||
|
||||
float defWidth = NSWidth([defButton frame]);
|
||||
float altWidth = (altButton) ? NSWidth([altButton frame]) : 0;
|
||||
float otherWidth = (otherButton) ? NSWidth([otherButton frame]) : 0;
|
||||
|
||||
float minContentWidth = kMinDialogWidth - 2*kWindowBorder - kIconMargin - kIconSize;
|
||||
float buttonWidth = defWidth + altWidth + otherWidth + kOtherAltButtonSpace;
|
||||
|
||||
// return the larger of the two
|
||||
return (minContentWidth > buttonWidth) ? minContentWidth : buttonWidth;
|
||||
}
|
||||
|
||||
- (NSPanel*)getAlertPanelWithTitle:(NSString*)title message:(NSString*)message
|
||||
defaultButton:(NSString*)defaultLabel altButton:(NSString*)altLabel
|
||||
otherButton:(NSString*)otherLabel extraView:(NSView*)extraView lastResponder:(NSView*)lastResponder
|
||||
{
|
||||
NSRect rect = NSMakeRect(0, 0, kMinDialogWidth, kMaxDialogHeight);
|
||||
NSPanel* panel = [[[NSPanel alloc] initWithContentRect: rect styleMask: NSTitledWindowMask backing: NSBackingStoreBuffered defer: YES] autorelease];
|
||||
NSImageView* imageView = [[[NSImageView alloc] initWithFrame: NSMakeRect(kWindowBorder, kMaxDialogHeight - kWindowBorder - kIconSize, kIconSize, kIconSize)] autorelease];
|
||||
|
||||
// app icon
|
||||
|
||||
[imageView setImage: [NSImage imageNamed: @"NSApplicationIcon"]];
|
||||
[imageView setImageFrameStyle: NSImageFrameNone];
|
||||
[imageView setImageScaling: NSScaleProportionally];
|
||||
[imageView setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin];
|
||||
[[panel contentView] addSubview: imageView];
|
||||
|
||||
// create buttons
|
||||
|
||||
NSButton* defButton = [self makeButtonWithTitle: defaultLabel];
|
||||
[defButton setAction: @selector(hitButton1:)];
|
||||
[defButton setAutoresizingMask: NSViewMinXMargin | NSViewMaxYMargin];
|
||||
[defButton setKeyEquivalent: @"\r"]; // return
|
||||
[[panel contentView] addSubview: defButton];
|
||||
[panel setDefaultButtonCell: [defButton cell]];
|
||||
|
||||
NSView* firstKeyView = (extraView ? extraView : defButton);
|
||||
|
||||
NSButton* altButton = nil;
|
||||
if (altLabel) {
|
||||
altButton = [self makeButtonWithTitle: altLabel];
|
||||
[altButton setAction: @selector(hitButton2:)];
|
||||
[altButton setAutoresizingMask: NSViewMinXMargin | NSViewMaxYMargin];
|
||||
[altButton setKeyEquivalent: @"\e"]; // escape
|
||||
[[panel contentView] addSubview: altButton];
|
||||
[defButton setNextKeyView: altButton];
|
||||
}
|
||||
|
||||
NSButton* otherButton = nil;
|
||||
if (otherLabel) {
|
||||
otherButton = [self makeButtonWithTitle: otherLabel];
|
||||
[otherButton setAction: @selector(hitButton3:)];
|
||||
[otherButton setAutoresizingMask: NSViewMaxXMargin | NSViewMaxYMargin];
|
||||
[[panel contentView] addSubview: otherButton];
|
||||
[otherButton setNextKeyView: firstKeyView];
|
||||
if (altButton)
|
||||
[altButton setNextKeyView: otherButton];
|
||||
else
|
||||
[defButton setNextKeyView: otherButton];
|
||||
} else {
|
||||
if (altButton)
|
||||
[altButton setNextKeyView: firstKeyView];
|
||||
else
|
||||
[defButton setNextKeyView: firstKeyView];
|
||||
}
|
||||
|
||||
// position buttons
|
||||
|
||||
float defWidth = NSWidth([defButton frame]);
|
||||
float altWidth = (altButton) ? NSWidth([altButton frame]) : 0;
|
||||
|
||||
[defButton setFrameOrigin: NSMakePoint(NSWidth([panel frame]) - defWidth - kButtonRightMargin, kButtonBottomMargin)];
|
||||
[altButton setFrameOrigin: NSMakePoint(NSMinX([defButton frame]) - altWidth, kButtonBottomMargin)];
|
||||
[otherButton setFrameOrigin: NSMakePoint(kIconSize + kWindowBorder + kIconMargin, kButtonBottomMargin)];
|
||||
|
||||
// set the window width
|
||||
// contentWidth is the width of the area with text, buttons, etc
|
||||
// windowWidth is the total window width (contentWidth + margins + icon)
|
||||
|
||||
float contentWidth = [self getContentWidthWithDefaultButton: defaultLabel alternateButton: altLabel otherButton: otherLabel];
|
||||
float windowWidth = kIconSize + kIconMargin + 2*kWindowBorder + contentWidth;
|
||||
if (windowWidth < kMinDialogWidth)
|
||||
windowWidth = kMinDialogWidth;
|
||||
|
||||
// get the height of all elements, and set the window height
|
||||
|
||||
NSTextField* titleField = [self getTitleView: title withWidth: contentWidth];
|
||||
|
||||
float titleHeight = [title length] ? NSHeight([titleField frame]) : 0;
|
||||
float extraViewHeight = (extraView) ? NSHeight([extraView frame]) : 0;
|
||||
float totalHeight = kWindowBorder + titleHeight + kGeneralViewSpace + kViewButtonSpace + kButtonHeight + kButtonBottomMargin;
|
||||
if (extraViewHeight > 0)
|
||||
totalHeight += extraViewHeight + kGeneralViewSpace;
|
||||
|
||||
float maxMessageHeight = kMaxDialogHeight - totalHeight;
|
||||
NSView* messageView = [self getMessageView: message withWidth: contentWidth maxHeight: maxMessageHeight smallFont:[title length]];
|
||||
float messageHeight = NSHeight([messageView frame]);
|
||||
totalHeight += messageHeight;
|
||||
|
||||
if (totalHeight < kMinDialogHeight)
|
||||
totalHeight = kMinDialogHeight;
|
||||
|
||||
[panel setContentSize: NSMakeSize(windowWidth, totalHeight)];
|
||||
|
||||
// position the title
|
||||
|
||||
float contentLeftEdge = kWindowBorder + kIconSize + kIconMargin;
|
||||
NSRect titleRect = NSMakeRect(contentLeftEdge, totalHeight - titleHeight - kWindowBorder, contentWidth, titleHeight);
|
||||
[titleField setFrame: titleRect];
|
||||
if ( [title length] )
|
||||
[[panel contentView] addSubview: titleField];
|
||||
|
||||
// position the message
|
||||
|
||||
NSRect messageRect = NSMakeRect(contentLeftEdge, NSMinY([titleField frame]) - kGeneralViewSpace - messageHeight, contentWidth, messageHeight);
|
||||
[messageView setFrame: messageRect];
|
||||
[[panel contentView] addSubview: messageView];
|
||||
|
||||
// position the extra view
|
||||
|
||||
NSRect extraRect = NSMakeRect(contentLeftEdge, NSMinY([messageView frame]) - kGeneralViewSpace - extraViewHeight, contentWidth, extraViewHeight);
|
||||
[extraView setFrame: extraRect];
|
||||
[[panel contentView] addSubview: extraView];
|
||||
|
||||
// If a lastResponder was passed in (the last item in the tab order inside
|
||||
// extraView), hook it up to cycle to defButton. If not, assume there is
|
||||
// nothing focusable inside extraView and hook up defButton as the first
|
||||
// responder.
|
||||
|
||||
if (lastResponder)
|
||||
[lastResponder setNextKeyView: defButton];
|
||||
else
|
||||
[panel setInitialFirstResponder: defButton];
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
- (NSButton*)makeButtonWithTitle:(NSString*)title
|
||||
{
|
||||
if (title == nil)
|
||||
return nil;
|
||||
|
||||
NSButton* button = [[[NSButton alloc] initWithFrame: NSMakeRect(0, 0, kButtonMinWidth, kButtonHeight)] autorelease];
|
||||
|
||||
[button setTitle: title];
|
||||
[button setFont: [NSFont systemFontOfSize: [NSFont systemFontSize]]];
|
||||
[button setBordered: YES];
|
||||
[button setButtonType: NSMomentaryPushButton];
|
||||
[button setBezelStyle: NSRoundedBezelStyle];
|
||||
[button setTarget: self];
|
||||
[button sizeToFit];
|
||||
|
||||
NSRect buttonFrame = [button frame];
|
||||
|
||||
// sizeToFit doesn't leave large enough endcaps (it goes to the bare minimum size)
|
||||
buttonFrame.size.width += 2*kButtonEndCapWidth;
|
||||
|
||||
// make sure the button is within our allowed size range
|
||||
if (NSWidth(buttonFrame) < kButtonMinWidth)
|
||||
buttonFrame.size.width = kButtonMinWidth;
|
||||
else if (NSWidth(buttonFrame) > kButtonMaxWidth)
|
||||
buttonFrame.size.width = kButtonMaxWidth;
|
||||
|
||||
[button setFrame: buttonFrame];
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
- (NSTextField*)getTitleView:(NSString*)title withWidth:(float)width
|
||||
{
|
||||
NSTextView* textView = [[[NSTextView alloc] initWithFrame: NSMakeRect(0, 0, width, 100)] autorelease];
|
||||
[textView setString: title];
|
||||
[textView setMinSize: NSMakeSize(width, 0.0)];
|
||||
[textView setMaxSize: NSMakeSize(width, kMaxFieldHeight)];
|
||||
[textView setVerticallyResizable: YES];
|
||||
[textView setHorizontallyResizable: NO];
|
||||
[textView setFont: [NSFont boldSystemFontOfSize: [NSFont systemFontSize]]];
|
||||
[textView sizeToFit];
|
||||
NSSize textSize = NSMakeSize( ceil( NSWidth([textView frame]) ), ceil( NSHeight([textView frame]) ) );
|
||||
|
||||
NSTextField* field = [[[NSTextField alloc] initWithFrame: NSMakeRect(0, 0, textSize.width, textSize.height)] autorelease];
|
||||
[field setStringValue: title];
|
||||
[field setFont: [NSFont boldSystemFontOfSize: [NSFont systemFontSize]]];
|
||||
[field setEditable: NO];
|
||||
[field setSelectable: NO];
|
||||
[field setBezeled: NO];
|
||||
[field setBordered: NO];
|
||||
[field setDrawsBackground: NO];
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
- (NSTextField*)getLabelView:(NSString*)title withWidth:(float)width
|
||||
{
|
||||
NSTextView* textView = [[[NSTextView alloc] initWithFrame: NSMakeRect(0, 0, width, 100)] autorelease];
|
||||
[textView setString: title];
|
||||
[textView setMinSize: NSMakeSize(width, 0.0)];
|
||||
[textView setMaxSize: NSMakeSize(width, kMaxFieldHeight)];
|
||||
[textView setVerticallyResizable: YES];
|
||||
[textView setHorizontallyResizable: NO];
|
||||
[textView setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];
|
||||
[textView sizeToFit];
|
||||
NSSize textSize = NSMakeSize(ceil(NSWidth([textView frame])), ceil(NSHeight([textView frame])) + 5);
|
||||
|
||||
NSTextField* field = [[[NSTextField alloc] initWithFrame: NSMakeRect(0, 0, textSize.width, textSize.height)] autorelease];
|
||||
[field setStringValue: title];
|
||||
[field setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];
|
||||
[field setEditable: NO];
|
||||
[field setSelectable: NO];
|
||||
[field setBezeled: NO];
|
||||
[field setBordered: NO];
|
||||
[field setDrawsBackground: NO];
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
- (NSView*)getMessageView:(NSString*)message withWidth:(float)width maxHeight:(float)maxHeight smallFont:(BOOL)useSmallFont
|
||||
{
|
||||
NSTextView* textView = [[[NSTextView alloc] initWithFrame: NSMakeRect(0, 0, width, 100)] autorelease];
|
||||
[textView setString: message];
|
||||
[textView setMinSize: NSMakeSize(width, 0.0)];
|
||||
[textView setVerticallyResizable: YES];
|
||||
[textView setHorizontallyResizable: NO];
|
||||
float displayFontSize = useSmallFont ? [NSFont smallSystemFontSize] : [NSFont systemFontSize];
|
||||
[textView setFont: [NSFont systemFontOfSize:displayFontSize]];
|
||||
[textView sizeToFit];
|
||||
NSSize textSize = NSMakeSize(ceil(NSWidth([textView frame])), ceil(NSHeight([textView frame])) + 5);
|
||||
|
||||
// if the text is small enough to fit, then display it
|
||||
|
||||
if (textSize.height <= maxHeight) {
|
||||
NSTextField* field = [[[NSTextField alloc] initWithFrame: NSMakeRect(0, 0, textSize.width, textSize.height)] autorelease];
|
||||
[field setStringValue: message];
|
||||
[field setFont: [NSFont systemFontOfSize: displayFontSize]];
|
||||
[field setEditable: NO];
|
||||
[field setSelectable: YES];
|
||||
[field setBezeled: NO];
|
||||
[field setBordered: NO];
|
||||
[field setDrawsBackground: NO];
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
// if not, create scrollers
|
||||
|
||||
NSScrollView* scrollView = [[[NSScrollView alloc] initWithFrame: NSMakeRect(0, 0, width, maxHeight)] autorelease];
|
||||
[scrollView setDocumentView: textView];
|
||||
[scrollView setDrawsBackground: NO];
|
||||
[scrollView setBorderType: NSBezelBorder];
|
||||
[scrollView setHasHorizontalScroller: NO];
|
||||
[scrollView setHasVerticalScroller: YES];
|
||||
|
||||
[textView setSelectable: YES];
|
||||
[textView setEditable: NO];
|
||||
[textView setDrawsBackground: NO];
|
||||
[textView setFrameSize: [scrollView contentSize]];
|
||||
|
||||
return scrollView;
|
||||
}
|
||||
|
||||
- (NSView*)getCheckboxView:(NSButton**)checkBoxPtr withLabel:(NSString*)label andWidth:(float)width
|
||||
{
|
||||
NSTextField* textField = [self getLabelView: label withWidth: width - kCheckBoxWidth];
|
||||
float height = NSHeight([textField frame]);
|
||||
|
||||
// one line of text isn't as tall as the checkbox. make the view taller, or the checkbox will get clipped
|
||||
if (height < kCheckBoxHeight)
|
||||
height = kCheckBoxHeight;
|
||||
|
||||
// use a flipped view so we can more easily align everything at the top/left.
|
||||
NSView* view = [[[QDCoordsView alloc] initWithFrame: NSMakeRect(0, 0, width, height)] autorelease];
|
||||
|
||||
[view addSubview: textField];
|
||||
[view setNextKeyView: textField];
|
||||
[textField setFrameOrigin: NSMakePoint(kCheckBoxWidth, kLabelCheckboxAdjustment)];
|
||||
|
||||
NSButton* checkBox = [[[NSButton alloc] initWithFrame: NSMakeRect(0, 0, kCheckBoxWidth, kCheckBoxHeight)] autorelease];
|
||||
*checkBoxPtr = checkBox;
|
||||
[checkBox setButtonType: NSSwitchButton];
|
||||
[[checkBox cell] setControlSize: NSSmallControlSize];
|
||||
[view addSubview: checkBox];
|
||||
[textField setNextKeyView: checkBox];
|
||||
|
||||
// overlay the label with a transparent button that will push the checkbox
|
||||
// when clicked on
|
||||
NSButton* labelOverlay = [[[NSButton alloc] initWithFrame:[textField frame]] autorelease];
|
||||
[labelOverlay setTransparent:YES];
|
||||
[labelOverlay setTarget:[checkBox cell]];
|
||||
[labelOverlay setAction:@selector(performClick:)];
|
||||
[view addSubview:labelOverlay positioned:NSWindowAbove relativeTo:checkBox];
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
- (NSView*)getLoginField:(NSTextField**)fieldPtr withWidth:(float)width
|
||||
{
|
||||
int labelSize = [self getLoginTextLabelSize];
|
||||
int fieldLeftEdge = labelSize + kFieldLabelSpacer;
|
||||
|
||||
NSView* view = [[[NSView alloc] initWithFrame: NSMakeRect(0, 0, width, kTextFieldHeight)] autorelease];
|
||||
NSTextField* label = [[[NSTextField alloc] initWithFrame: NSMakeRect(0, 3, labelSize, kStaticTextFieldHeight)] autorelease];
|
||||
[[label cell] setControlSize: NSSmallControlSize];
|
||||
[label setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];
|
||||
[label setStringValue: NSLocalizedString(@"Username Label", @"")];
|
||||
[label setEditable: NO];
|
||||
[label setSelectable: NO];
|
||||
[label setBordered: NO];
|
||||
[label setDrawsBackground: NO];
|
||||
[label setAlignment: NSRightTextAlignment];
|
||||
[view addSubview: label];
|
||||
|
||||
NSTextField* field = [[[NSTextField alloc] initWithFrame: NSMakeRect(fieldLeftEdge, 0, width - fieldLeftEdge, kTextFieldHeight)] autorelease];
|
||||
[[field cell] setControlSize: NSSmallControlSize];
|
||||
[field setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];
|
||||
[view addSubview: field];
|
||||
[view setNextKeyView: field];
|
||||
*fieldPtr = field;
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
- (NSView*)getPasswordField:(NSSecureTextField**)fieldPtr withWidth:(float)width
|
||||
{
|
||||
int labelSize = [self getLoginTextLabelSize];
|
||||
int fieldLeftEdge = labelSize + kFieldLabelSpacer;
|
||||
|
||||
NSView* view = [[[NSView alloc] initWithFrame: NSMakeRect(0, 0, width, kTextFieldHeight)] autorelease];
|
||||
NSTextField* label = [[[NSTextField alloc] initWithFrame: NSMakeRect(0, 3, labelSize, kStaticTextFieldHeight)] autorelease];
|
||||
[[label cell] setControlSize: NSSmallControlSize];
|
||||
[label setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];
|
||||
[label setStringValue: NSLocalizedString(@"Password Label", @"")];
|
||||
[label setEditable: NO];
|
||||
[label setSelectable: NO];
|
||||
[label setBordered: NO];
|
||||
[label setDrawsBackground: NO];
|
||||
[label setAlignment: NSRightTextAlignment];
|
||||
[view addSubview: label];
|
||||
|
||||
NSSecureTextField* field = [[[NSSecureTextField alloc] initWithFrame: NSMakeRect(fieldLeftEdge, 0, width - fieldLeftEdge, kTextFieldHeight)] autorelease];
|
||||
[[field cell] setControlSize: NSSmallControlSize];
|
||||
[field setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];
|
||||
[view addSubview: field];
|
||||
[view setNextKeyView: field];
|
||||
*fieldPtr = field;
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
- (int)getLoginTextLabelSize
|
||||
{
|
||||
NSTextField* label = [[[NSTextField alloc] initWithFrame: NSMakeRect(0, 0, 200, kStaticTextFieldHeight)] autorelease];
|
||||
[[label cell] setControlSize: NSSmallControlSize];
|
||||
[label setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]];
|
||||
[label setEditable: NO];
|
||||
[label setSelectable: NO];
|
||||
[label setBordered: NO];
|
||||
[label setDrawsBackground: NO];
|
||||
[label setAlignment: NSRightTextAlignment];
|
||||
|
||||
[label setStringValue: NSLocalizedString(@"Username Label", @"")];
|
||||
[label sizeToFit];
|
||||
float userSize = NSWidth([label frame]);
|
||||
|
||||
[label setStringValue: NSLocalizedString(@"Password Label", @"")];
|
||||
[label sizeToFit];
|
||||
float passSize = NSWidth([label frame]);
|
||||
|
||||
float largest = (userSize > passSize) ? userSize : passSize;
|
||||
return (int)ceil(largest) + 6;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -346,7 +346,8 @@ static id gSharedProgressController = nil;
|
|||
{
|
||||
ProgressViewController *newController = [[ProgressViewController alloc] init];
|
||||
[newController setProgressWindowController:self];
|
||||
[mProgressViewControllers addObject:newController];
|
||||
//[mProgressViewControllers addObject:newController];
|
||||
[mProgressViewControllers insertObject:newController atIndex:0]; // new downoads at the top
|
||||
|
||||
return newController;
|
||||
}
|
||||
|
|
|
@ -256,13 +256,9 @@ static NSString *ProgressViewsShouldResize = @"ProgressViewsShouldResize";
|
|||
if (mDownloader) // we should always have one
|
||||
mDownloader->CancelDownload();
|
||||
|
||||
// clean up downloaded file. - do it here or in CancelDownload?
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
if ([fileManager isDeletableFileAtPath:mDestPath])
|
||||
{
|
||||
// if we delete it, fantastic. if not, oh well. better to move to trash instead?
|
||||
[fileManager removeFileAtPath:mDestPath handler:nil];
|
||||
}
|
||||
// note that we never want to delete downloaded files here,
|
||||
// because the file does not have its final path yet.
|
||||
// Necko will delete the evil temp file.
|
||||
}
|
||||
|
||||
- (IBAction)close:(id)sender
|
||||
|
|
|
@ -347,7 +347,7 @@ nsresult nsHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsString&
|
|||
{ // Tell web persist we want no decoding on this data
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION;
|
||||
webPersist->SetPersistFlags(flags);
|
||||
rv = webPersist->SaveURI(sourceURI, mPostData, destFile);
|
||||
rv = webPersist->SaveURI(sourceURI, nsnull, nsnull, mPostData, nsnull, destFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -71,7 +71,7 @@ NS_IMPL_ISUPPORTS_INHERITED3(nsDownloadListener, CHDownloader, nsIDownload, nsIW
|
|||
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName,
|
||||
nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
|
||||
nsIMIMEInfo* aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
|
||||
{
|
||||
CreateDownloadDisplay(); // call the base class to make the download UI
|
||||
|
||||
|
@ -269,7 +269,12 @@ NS_IMETHODIMP nsDownloadListener::Notify(nsITimer *timer)
|
|||
// changed it
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mDownloadDisplay setDestinationPath: [NSString stringWith_nsAString:pathStr]];
|
||||
NSString* destPath = [NSString stringWith_nsAString:pathStr];
|
||||
[mDownloadDisplay setDestinationPath:destPath];
|
||||
|
||||
// update the Finder immediately.
|
||||
if ( NS_SUCCEEDED(mDownloadStatus) )
|
||||
[[NSWorkspace sharedWorkspace] noteFileSystemChanged:destPath];
|
||||
|
||||
// cancelling should give us a failure status
|
||||
[mDownloadDisplay onEndDownload:(NS_SUCCEEDED(mDownloadStatus) && !mUserCanceled)];
|
||||
|
@ -364,7 +369,7 @@ nsDownloadListener::DownloadDone(nsresult aStatus)
|
|||
mEndRefreshTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (mEndRefreshTimer)
|
||||
{
|
||||
nsresult rv = mEndRefreshTimer->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT); // defaults to 1-shot, normal priority
|
||||
nsresult rv = mEndRefreshTimer->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT);
|
||||
if (NS_FAILED(rv))
|
||||
mEndRefreshTimer = NULL;
|
||||
}
|
||||
|
|
|
@ -222,15 +222,6 @@ CHBrowserListener::SetChromeFlags(PRUint32 aChromeFlags)
|
|||
NS_IMETHODIMP
|
||||
CHBrowserListener::DestroyBrowserWindow()
|
||||
{
|
||||
#if 0
|
||||
// XXX Could send this up to the container, but for now,
|
||||
// we just destroy the enclosing window.
|
||||
NSWindow* window = [mView window];
|
||||
|
||||
if (window) {
|
||||
[window close];
|
||||
}
|
||||
#endif
|
||||
// tell the container we want to close the window and let it do the
|
||||
// right thing.
|
||||
[mContainer closeBrowserWindow];
|
||||
|
@ -261,7 +252,7 @@ CHBrowserListener::ShowAsModal()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
NSWindow* window = [mView getNativeWindow];
|
||||
|
||||
if (!window) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -309,6 +300,8 @@ CHBrowserListener::SetDimensions(PRUint32 flags, PRInt32 x, PRInt32 y, PRInt32 c
|
|||
if (!mView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// use -window here and not -getNativeWindow because we don't want to allow bg tabs
|
||||
// (which aren't in the window hierarchy) to resize the window.
|
||||
NSWindow* window = [mView window];
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -363,7 +356,7 @@ CHBrowserListener::GetDimensions(PRUint32 flags, PRInt32 *x, PRInt32 *y, PRInt
|
|||
if (!mView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
NSWindow* window = [mView getNativeWindow];
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -403,6 +396,7 @@ CHBrowserListener::GetDimensions(PRUint32 flags, PRInt32 *x, PRInt32 *y, PRInt
|
|||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetFocus()
|
||||
{
|
||||
// don't use -getNativeWindow here so tabs in the bg can't take focus
|
||||
NSWindow* window = [mView window];
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -433,7 +427,7 @@ CHBrowserListener::GetVisibility(PRBool *aVisibility)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
NSWindow* window = [mView getNativeWindow];
|
||||
if (!window) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -446,6 +440,8 @@ CHBrowserListener::GetVisibility(PRBool *aVisibility)
|
|||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetVisibility(PRBool aVisibility)
|
||||
{
|
||||
// use -window instead of -getNativeWindow to prevent bg tabs from being able to
|
||||
// change the visibility
|
||||
NSWindow* window = [mView window];
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -512,7 +508,7 @@ CHBrowserListener::GetSiteWindow(void * *aSiteWindow)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
NSWindow* window = [mView getNativeWindow];
|
||||
if (!window) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -162,8 +162,7 @@ nsAlertController*
|
|||
CHBrowserService::GetAlertController()
|
||||
{
|
||||
if (!sController) {
|
||||
NSBundle* bundle = [NSBundle bundleForClass:[CHBrowserView class]];
|
||||
[bundle loadNibFile:@NS_ALERT_NIB_NAME externalNameTable:nsnull withZone:[NSApp zone]];
|
||||
sController = [[nsAlertController alloc] init];
|
||||
}
|
||||
return sController;
|
||||
}
|
||||
|
|
|
@ -215,6 +215,9 @@ enum {
|
|||
// point is over.
|
||||
- (void) findEventSink:(nsIEventSink**)outSink forPoint:(NSPoint)inPoint inWindow:(NSWindow*)inWind;
|
||||
|
||||
- (IBAction)reloadWithNewCharset:(NSString*)charset;
|
||||
- (NSString*)currentCharset;
|
||||
|
||||
@end
|
||||
|
||||
#endif // __nsCocoaBrowserView_h__
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsIWebNavigation.h"
|
||||
#include "nsIWebBrowserSetup.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIDocCharset.h"
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
@ -109,7 +110,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
|||
- (nsIContentViewer*)getContentViewer; // addrefs return value
|
||||
- (float)getTextZoom;
|
||||
- (void)incrementTextZoom:(float)increment min:(float)min max:(float)max;
|
||||
|
||||
- (nsIDocShell*)getDocShell; // addrefs return value
|
||||
@end
|
||||
|
||||
@implementation CHBrowserView
|
||||
|
@ -480,7 +481,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
|||
if (!sniffer)
|
||||
return;
|
||||
webPersist->SetProgressListener(sniffer); // owned
|
||||
webPersist->SaveURI(aURI, nsnull, tmpFile);
|
||||
webPersist->SaveURI(aURI, nsnull, nsnull, nsnull, nsnull, tmpFile);
|
||||
}
|
||||
|
||||
-(void)printDocument
|
||||
|
@ -678,8 +679,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
|||
PRBool isEnabled = PR_FALSE;
|
||||
nsCOMPtr<nsICommandManager> commandMgr(do_GetInterface(_webBrowser));
|
||||
if (commandMgr) {
|
||||
nsresult rv = commandMgr->IsCommandEnabled(commandName, nsnull,
|
||||
&isEnabled);
|
||||
nsresult rv = commandMgr->IsCommandEnabled(commandName, nsnull, &isEnabled);
|
||||
#if DEBUG
|
||||
if (NS_FAILED(rv))
|
||||
NSLog(@"IsCommandEnabled failed");
|
||||
|
@ -916,7 +916,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
|||
}
|
||||
|
||||
|
||||
- (nsIContentViewer*)getContentViewer // addrefs return value
|
||||
- (nsIDocShell*)getDocShell
|
||||
{
|
||||
if (!_webBrowser)
|
||||
return NULL;
|
||||
|
@ -925,11 +925,14 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
|||
nsCOMPtr<nsIScriptGlobalObject> global(do_QueryInterface(domWindow));
|
||||
if (!global)
|
||||
return NULL;
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
global->GetDocShell(getter_AddRefs(docShell));
|
||||
if (!docShell)
|
||||
return NULL;
|
||||
|
||||
nsIDocShell* docShell = NULL;
|
||||
global->GetDocShell(&docShell); // addrefs
|
||||
return docShell;
|
||||
}
|
||||
|
||||
- (nsIContentViewer*)getContentViewer // addrefs return value
|
||||
{
|
||||
nsCOMPtr<nsIDocShell> docShell = dont_AddRef([self getDocShell]);
|
||||
nsIContentViewer* cv = NULL;
|
||||
docShell->GetContentViewer(&cv); // addrefs
|
||||
return cv;
|
||||
|
@ -1126,10 +1129,10 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
|||
nsCOMPtr<nsICommandParams> params = do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID);
|
||||
if (!params) return NO;
|
||||
|
||||
params->SetStringValue("format", NS_LITERAL_STRING("text/plain"));
|
||||
params->SetStringValue("format", NS_LITERAL_STRING("text/plain"));
|
||||
params->SetBooleanValue("selection_only", PR_TRUE);
|
||||
|
||||
nsresult rv = cmdManager->DoCommand("cmd_getContents", params, nsnull);
|
||||
nsresult rv = cmdManager->DoCommand("cmd_GetContents", params, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return NO;
|
||||
|
||||
|
@ -1166,4 +1169,52 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
|||
return (BOOL)NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
- (IBAction)reloadWithNewCharset:(NSString*)inCharset
|
||||
{
|
||||
// set charset on document then reload the page (hopefully not hitting the network)
|
||||
nsCOMPtr<nsIDocShell> docShell = dont_AddRef([self getDocShell]);
|
||||
nsCOMPtr<nsIDocCharset> charset ( do_QueryInterface(docShell) );
|
||||
if ( charset ) {
|
||||
nsAutoString charsetStr;
|
||||
[inCharset assignTo_nsAString:charsetStr];
|
||||
charset->SetCharset(charsetStr.get());
|
||||
[self reload:nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString*)currentCharset
|
||||
{
|
||||
#if 0
|
||||
nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
|
||||
if ( wbf ) {
|
||||
nsCOMPtr<nsIDOMWindow> focusedWindow;
|
||||
wbf->GetFocusedWindow(getter_AddRefs(focusedWindow));
|
||||
if ( focusedWindow ) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
focusedWindow->GetDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc ( do_QueryInterface(domDoc) );
|
||||
if ( doc ) {
|
||||
nsAutoString charset;
|
||||
doc->GetDocumentCharacterSet(charset);
|
||||
return [NSString stringWith_nsAString:charset];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> wind;
|
||||
_webBrowser->GetContentDOMWindow(getter_AddRefs(wind));
|
||||
if ( wind ) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
wind->GetDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc ( do_QueryInterface(domDoc) );
|
||||
if ( doc ) {
|
||||
nsAutoString charset;
|
||||
doc->GetDocumentCharacterSet(charset);
|
||||
return [NSString stringWith_nsAString:charset];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -65,15 +65,16 @@
|
|||
|
||||
-(void)keyDown:(NSEvent*)aEvent
|
||||
{
|
||||
const unichar kForwardDeleteChar = 0xf728; // couldn't find this in any cocoa header
|
||||
|
||||
// check each char in the event array. it should be just 1 char, but
|
||||
// just in case we use a loop.
|
||||
int len = [[aEvent characters] length];
|
||||
for ( int i = 0; i < len; ++i ) {
|
||||
unichar c = [[aEvent characters] characterAtIndex:i];
|
||||
|
||||
// Check for a certain set of special keys.
|
||||
|
||||
if (c == NSDeleteCharacter || c == NSBackspaceCharacter) {
|
||||
// Check for a certain set of special keys.
|
||||
if (c == NSDeleteCharacter || c == NSBackspaceCharacter || c == kForwardDeleteChar) {
|
||||
// delete the bookmark
|
||||
if (mDeleteAction)
|
||||
[NSApp sendAction: mDeleteAction to: [self target] from: self];
|
||||
|
|
|
@ -55,7 +55,7 @@ class nsIRDFService;
|
|||
// cached values are valid
|
||||
BOOL mExpandable;
|
||||
int mNumChildren;
|
||||
NSArray* mChildNodes;
|
||||
NSArray* mChildNodes; // array of |RDFOutlineViewItem|'s
|
||||
}
|
||||
|
||||
- (nsIRDFResource*)resource; // addRefs the result
|
||||
|
|
|
@ -150,6 +150,7 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
|||
@interface HistoryDataSource(Private)
|
||||
|
||||
- (void)cleanupHistory;
|
||||
- (void)removeItemFromHistory:(id)inItem withService:(nsIBrowserHistory*)inHistService;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -398,15 +399,27 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
|||
|
||||
nsCOMPtr<nsIBrowserHistory> history = do_GetService("@mozilla.org/browser/global-history;1");
|
||||
if ( history ) {
|
||||
// Even though it looks like relying on row numbers as we delete will get us in trouble
|
||||
// and out of sync, until we actually invalidate the table, the rows keep their prior values.
|
||||
// If children are selected as well as the parent, we'll just end up trying to remove the
|
||||
// host string from history which will silently fail. It's extra work, but harmless.
|
||||
history->StartBatchUpdate();
|
||||
NSEnumerator* rowEnum = [mOutlineView selectedRowEnumerator];
|
||||
for ( NSNumber* currIndex = [rowEnum nextObject]; currIndex; currIndex = [rowEnum nextObject]) {
|
||||
index = [currIndex intValue];
|
||||
RDFOutlineViewItem* item = [mOutlineView itemAtRow: index];
|
||||
if (![mOutlineView isExpandable: item]) {
|
||||
NSString* urlString = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:item];
|
||||
history->RemovePage([urlString UTF8String]);
|
||||
if ([mOutlineView isExpandable: item]) {
|
||||
// delete a folder by iterating over each of its children and deleting them. There
|
||||
// should be a better way, but the history api's don't really support them. Expand
|
||||
// the folder before we delete it otherwise we don't get any child nodes to delete.
|
||||
[mOutlineView expandItem:item];
|
||||
NSEnumerator* childEnum = [item->mChildNodes objectEnumerator];
|
||||
RDFOutlineViewItem* currChild = nil;
|
||||
while ( (currChild = [childEnum nextObject]) )
|
||||
[self removeItemFromHistory:currChild withService:history];
|
||||
}
|
||||
else
|
||||
[self removeItemFromHistory:item withService:history];
|
||||
}
|
||||
history->EndBatchUpdate();
|
||||
if ( clearSelectionWhenDone )
|
||||
|
@ -417,6 +430,13 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
|||
}
|
||||
}
|
||||
|
||||
-(void)removeItemFromHistory:(id)inItem withService:(nsIBrowserHistory*)inHistService;
|
||||
{
|
||||
NSString* urlString = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:inItem];
|
||||
inHistService->RemovePage([urlString UTF8String]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// outlineView:tooltipForString
|
||||
//
|
||||
|
|
|
@ -263,9 +263,11 @@ static BOOL gMadePrefManager;
|
|||
}
|
||||
return NO;
|
||||
}
|
||||
#ifdef BRANCH_CHANGES_NEED_MERGED
|
||||
else if (rv == NS_ERROR_PROFILE_SETLOCK_FAILED) {
|
||||
NSLog(@"SetCurrentProfile returned NS_ERROR_PROFILE_SETLOCK_FAILED");
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
mPrefs = prefs;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,296 +0,0 @@
|
|||
#import "PrivacyPane.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManagerUtils.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsCCookieManager.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIPermission.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsString.h"
|
||||
|
||||
// prefs for keychain password autofill
|
||||
static const char* const gUseKeychainPref = "chimera.store_passwords_with_keychain";
|
||||
static const char* const gAutoFillEnabledPref = "chimera.keychain_passwords_autofill";
|
||||
|
||||
const int kPromptForCookiesTag = 99;
|
||||
const int kEnableAllCookies = 0;
|
||||
const int kDisableAllCookies = 2;
|
||||
|
||||
@implementation OrgMozillaChimeraPreferencePrivacy
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
NS_IF_RELEASE(mManager);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
//
|
||||
// mapCookiePrefToCheckbox:
|
||||
//
|
||||
// Takes an int from the mozilla cookie pref and turns it into a BOOL
|
||||
// that can be used by our "enable cookies" checkbox.
|
||||
//
|
||||
-(BOOL)mapCookiePrefToCheckbox:(int)inCookiePref
|
||||
{
|
||||
BOOL retval = YES;
|
||||
if ( inCookiePref == kDisableAllCookies )
|
||||
retval = NO;
|
||||
return retval;
|
||||
}
|
||||
|
||||
//
|
||||
// mapCookieCheckboxToPref:
|
||||
//
|
||||
// Takes a BOOL from a checkbox and maps it to the mozilla pref values
|
||||
//
|
||||
-(int)mapCookieCheckboxToPref:(BOOL)inCheckboxValue
|
||||
{
|
||||
PRInt32 retval = kDisableAllCookies;
|
||||
if ( inCheckboxValue )
|
||||
retval = kEnableAllCookies;
|
||||
return retval;
|
||||
}
|
||||
|
||||
- (void)mainViewDidLoad
|
||||
{
|
||||
if ( !mPrefService )
|
||||
return;
|
||||
|
||||
// Hookup cookie prefs. The "ask about" and "cookie sites" buttons need to
|
||||
// be disabled when cookies aren't enabled because they aren't applicable.
|
||||
PRInt32 acceptCookies = kEnableAllCookies;
|
||||
mPrefService->GetIntPref("network.cookie.cookieBehavior", &acceptCookies);
|
||||
BOOL cookiesEnabled = [self mapCookiePrefToCheckbox:acceptCookies];
|
||||
[mCookiesEnabled setState:cookiesEnabled];
|
||||
if ( !cookiesEnabled ) {
|
||||
[mAskAboutCookies setEnabled:NO];
|
||||
[mEditSitesButton setEnabled:NO];
|
||||
[mEditSitesText setTextColor:[NSColor lightGrayColor]];
|
||||
}
|
||||
PRBool warnAboutCookies = PR_TRUE;
|
||||
mPrefService->GetBoolPref("network.cookie.warnAboutCookies", &warnAboutCookies);
|
||||
if ( warnAboutCookies )
|
||||
[mAskAboutCookies setState:YES];
|
||||
|
||||
// store permission manager service and cache the enumerator.
|
||||
nsCOMPtr<nsIPermissionManager> pm ( do_GetService(NS_PERMISSIONMANAGER_CONTRACTID) );
|
||||
mManager = pm.get();
|
||||
NS_IF_ADDREF(mManager);
|
||||
|
||||
// Keychain checkboxes
|
||||
|
||||
PRBool storePasswords = PR_TRUE;
|
||||
mPrefService->GetBoolPref(gUseKeychainPref, &storePasswords);
|
||||
[mStorePasswords setState:(storePasswords ? NSOnState : NSOffState)];
|
||||
[mAutoFillPasswords setEnabled:storePasswords ? YES : NO];
|
||||
|
||||
PRBool autoFillPasswords = PR_TRUE;
|
||||
mPrefService->GetBoolPref(gAutoFillEnabledPref, &autoFillPasswords);
|
||||
[mAutoFillPasswords setState:(autoFillPasswords ? NSOnState : NSOffState)];
|
||||
}
|
||||
|
||||
//
|
||||
// clearCookies:
|
||||
//
|
||||
// Clear all the user's cookies.
|
||||
//
|
||||
-(IBAction) clearCookies:(id)aSender
|
||||
{
|
||||
nsCOMPtr<nsICookieManager> cookieMonster ( do_GetService(NS_COOKIEMANAGER_CONTRACTID) );
|
||||
if ( cookieMonster )
|
||||
cookieMonster->RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// clickEnableCookies:
|
||||
//
|
||||
// Set cookie prefs and updates the enabled/disabled states of the
|
||||
// "ask" and "edit sites" buttons.
|
||||
//
|
||||
-(IBAction) clickEnableCookies:(id)sender
|
||||
{
|
||||
if ( !mPrefService )
|
||||
return;
|
||||
|
||||
// set the pref
|
||||
BOOL enabled = [mCookiesEnabled state];
|
||||
[self setPref:"network.cookie.cookieBehavior" toInt:[self mapCookieCheckboxToPref:enabled]];
|
||||
|
||||
// update the buttons
|
||||
[mAskAboutCookies setEnabled:enabled];
|
||||
[mEditSitesButton setEnabled:enabled];
|
||||
[mEditSitesText setTextColor:(enabled ? [NSColor blackColor] : [NSColor lightGrayColor])];
|
||||
}
|
||||
|
||||
|
||||
-(IBAction) clickAskAboutCookies:(id)sender
|
||||
{
|
||||
[self setPref:"network.cookie.warnAboutCookies" toBoolean:[sender state]];
|
||||
}
|
||||
|
||||
|
||||
-(IBAction) editCookieSites:(id)aSender
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> permEnum;
|
||||
if ( mManager )
|
||||
mManager->GetEnumerator(getter_AddRefs(permEnum));
|
||||
|
||||
// build parallel permission list for speed with a lot of blocked sites
|
||||
NS_NewISupportsArray(&mCachedPermissions); // ADDREFs
|
||||
if ( mCachedPermissions && permEnum ) {
|
||||
PRBool hasMoreElements = PR_FALSE;
|
||||
permEnum->HasMoreElements(&hasMoreElements);
|
||||
while ( hasMoreElements ) {
|
||||
nsCOMPtr<nsISupports> curr;
|
||||
permEnum->GetNext(getter_AddRefs(curr));
|
||||
mCachedPermissions->AppendElement(curr);
|
||||
|
||||
permEnum->HasMoreElements(&hasMoreElements);
|
||||
}
|
||||
}
|
||||
|
||||
[NSApp beginSheet:mCookieSitePanel
|
||||
modalForWindow:[mCookiesEnabled window] // any old window accessor
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(editCookieSitesSheetDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:NULL];
|
||||
|
||||
// ensure a row is selected (cocoa doesn't do this for us, but will keep
|
||||
// us from unselecting a row once one is set; go figure).
|
||||
[mSiteTable selectRow:0 byExtendingSelection:NO];
|
||||
|
||||
// we shouldn't need to do this, but the scrollbar won't enable unless we
|
||||
// force the table to reload its data. Oddly it gets the number of rows correct,
|
||||
// it just forgets to tell the scrollbar. *shrug*
|
||||
[mSiteTable reloadData];
|
||||
}
|
||||
|
||||
-(IBAction) editCookieSitesDone:(id)aSender
|
||||
{
|
||||
// save stuff
|
||||
|
||||
[mCookieSitePanel orderOut:self];
|
||||
[NSApp endSheet:mCookieSitePanel];
|
||||
|
||||
NS_IF_RELEASE(mCachedPermissions);
|
||||
}
|
||||
|
||||
- (void)editCookieSitesSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
-(IBAction) removeCookieSite:(id)aSender
|
||||
{
|
||||
if ( mCachedPermissions && mManager ) {
|
||||
// remove from parallel array and cookie permissions list
|
||||
int row = [mSiteTable selectedRow];
|
||||
|
||||
// remove from permission manager (which is done by host, not by row), then
|
||||
// remove it from our parallel array (which is done by row). Since we keep a
|
||||
// parallel array, removing multiple items by row is very difficult since after
|
||||
// deleting, the array is out of sync with the next cocoa row we're told to remove. Punt!
|
||||
nsCOMPtr<nsISupports> rowItem = dont_AddRef(mCachedPermissions->ElementAt(row));
|
||||
nsCOMPtr<nsIPermission> perm ( do_QueryInterface(rowItem) );
|
||||
if ( perm ) {
|
||||
nsXPIDLCString host;
|
||||
perm->GetHost(getter_Copies(host));
|
||||
mManager->Remove(nsDependentCString(host), 0); // could this api _be_ any worse? Come on!
|
||||
|
||||
mCachedPermissions->RemoveElementAt(row);
|
||||
}
|
||||
[mSiteTable reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// NSTableDataSource protocol methods
|
||||
//
|
||||
|
||||
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
|
||||
{
|
||||
PRUint32 numRows = 0;
|
||||
if ( mCachedPermissions )
|
||||
mCachedPermissions->Count(&numRows);
|
||||
|
||||
return (int) numRows;
|
||||
}
|
||||
|
||||
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
|
||||
{
|
||||
NSString* retVal = nil;
|
||||
if ( mCachedPermissions ) {
|
||||
nsCOMPtr<nsISupports> rowItem = dont_AddRef(mCachedPermissions->ElementAt(rowIndex));
|
||||
nsCOMPtr<nsIPermission> perm ( do_QueryInterface(rowItem) );
|
||||
if ( perm ) {
|
||||
if ( [[aTableColumn identifier] isEqualToString:@"Website"] ) {
|
||||
// website url column
|
||||
nsXPIDLCString host;
|
||||
perm->GetHost(getter_Copies(host));
|
||||
retVal = [NSString stringWithCString:host];
|
||||
}
|
||||
else {
|
||||
// allow/deny column
|
||||
PRBool capability = PR_FALSE; // false = deny, true = accept;
|
||||
perm->GetCapability(&capability);
|
||||
if ( capability )
|
||||
retVal = [self getLocalizedString:@"Allow"];
|
||||
else
|
||||
retVal = [self getLocalizedString:@"Deny"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// clickStorePasswords
|
||||
//
|
||||
-(IBAction) clickStorePasswords:(id)sender
|
||||
{
|
||||
if ( !mPrefService )
|
||||
return;
|
||||
if([mStorePasswords state] == NSOnState)
|
||||
{
|
||||
mPrefService->SetBoolPref("chimera.store_passwords_with_keychain", PR_TRUE);
|
||||
[mAutoFillPasswords setEnabled:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
mPrefService->SetBoolPref("chimera.store_passwords_with_keychain", PR_FALSE);
|
||||
[mAutoFillPasswords setEnabled:NO];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// clickAutoFillPasswords
|
||||
//
|
||||
// Set pref if autofill is enabled
|
||||
//
|
||||
-(IBAction) clickAutoFillPasswords:(id)sender
|
||||
{
|
||||
if ( !mPrefService )
|
||||
return;
|
||||
mPrefService->SetBoolPref("chimera.keychain_passwords_autofill",
|
||||
[mAutoFillPasswords state] == NSOnState ? PR_TRUE : PR_FALSE);
|
||||
}
|
||||
|
||||
-(IBAction) launchKeychainAccess:(id)sender
|
||||
{
|
||||
FSRef fsRef;
|
||||
CFURLRef urlRef;
|
||||
OSErr err = ::LSGetApplicationForInfo('APPL', 'kcmr', NULL, kLSRolesAll, &fsRef, &urlRef);
|
||||
if ( !err ) {
|
||||
CFStringRef fileSystemURL = ::CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
|
||||
[[NSWorkspace sharedWorkspace] launchApplication:(NSString*)fileSystemURL];
|
||||
CFRelease(fileSystemURL);
|
||||
}
|
||||
}
|
||||
@end
|
|
@ -1,74 +0,0 @@
|
|||
{\rtf1\mac\ansicpg10000\cocoartf102
|
||||
\readonlydoc1{\fonttbl\f0\fswiss\fcharset77 Optima-Bold;\f1\fswiss\fcharset77 Optima-Regular;\f2\fswiss\fcharset77 Helvetica;
|
||||
\f3\fnil\fcharset77 Monaco;}
|
||||
{\colortbl;\red255\green255\blue255;\red4\green16\blue255;}
|
||||
\margl1440\margr1440\vieww13740\viewh16200\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f0\b\fs48 \cf0 Chimera Read Me\
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f1\b0\fs24 \cf2 http://www.mozilla.org/projects/chimera/\cf0 \
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f2 \cf0 \
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f1 \cf0 Thank you for downloading Chimera! Please take a moment to read this information to find out about what\'d5s new in Chimera, and to learn about known issues.\
|
||||
\
|
||||
Chimera is still under development. It is stable enough to use day-to-day, but you may still encounter bugs. You should always keep backup copies of important data that you use with Chimera (e.g. your bookmarks file). \
|
||||
\
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f0\b\fs36 \cf0 Installation
|
||||
\f1\b0\fs24 \
|
||||
\
|
||||
To install Chimera, simply drag the Navigator icon onto your hard disk. We recommend that you copy it to the Applications folder. You can then Eject the disk image. If you like, you can drag Navigator to your dock to have it easily accessible at all times. You might also wish to select Navigator as your default browser in the Internet system preferences pane (under the Web tab). Note that although the project is called \'d2Chimera\'d3, the name of the application is \'d2Navigator\'d3.\
|
||||
\
|
||||
After installation, you may want to import bookmarks from another browser. Run Navigator, choose \'d3Manage Bookmarks\'d3 from the Bookmarks menu, and choose \'d2Import Bookmarks\'d3 from the submenu. In the resulting file dialog, choose the bookmarks file you wish to import, and click Open. The bookmarks will be imported.\
|
||||
\
|
||||
|
||||
\f0\b\fs36 Where information is kept on disk
|
||||
\f1\b0\fs24 \
|
||||
\
|
||||
When you first run Chimera, it makes a folder in
|
||||
\f3\fs20 ~/Library/Application Support/
|
||||
\f1\fs24 (where
|
||||
\f3\fs20 ~
|
||||
\f1\fs24 is your Home directory) called \'d2Chimera\'d3. A folder down inside this folder contains your \'d3profile\'d3 information (bookmarks, cookies, cache etc). One of the containing folders has an odd-looking \'d2salted\'d3 name for security reasons.\
|
||||
\
|
||||
There are two files in your profile that you might need to know about. First,
|
||||
\f3\fs20 bookmarks.xml
|
||||
\f1\fs24 contains your bookmarks. You might want to regularly make copies of this file if you run nightly builds.
|
||||
\f3\fs20 prefs.js
|
||||
\f1\fs24 contains most of the application preferences. Not all preferences are exposed in the preferences window yet, so you might see advice to \'d2edit your prefs file\'d3. To do that, drag prefs.js onto your favorite editor, make whatever changes are necessary, and save. Make sure the file gets saved in plain text format.\
|
||||
\
|
||||
|
||||
\f0\b\fs36 Uninstall
|
||||
\f1\b0\fs24 \
|
||||
\
|
||||
To get rid of all the files related to Chimera, do the following:\
|
||||
\
|
||||
1. Drag the Navigator icon to the trash\
|
||||
2. Drag the
|
||||
\f3\fs20 ~/Library/Application Support/Chimera
|
||||
\f1\fs24 folder to the trash\
|
||||
\
|
||||
|
||||
\f0\b\fs36 Changes, and known issues, in this version\
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f1\b0\fs24 \cf0 \
|
||||
See the accompanying \'d2Release Notes\'d3 file for information about what has changed in this version of Chimera, and a list of the known issues.\
|
||||
\
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f0\b\fs36 \cf0 More information, and feedback\
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
|
||||
\f1\b0\fs24 \cf0 \
|
||||
To find out more about Chimera, see the project page at:\
|
||||
\
|
||||
\cf2 http://www.mozilla.org/projects/chimera/\cf0 \
|
||||
\
|
||||
This page contains information about how to give feedback on Chimera, has links that allow you to query for known bugs, see what\'d5s going on with current development, and about how to build it yourself from source.}
|
|
@ -1,47 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>65 36 653 383 0 0 1152 848 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>124</key>
|
||||
<string>107 563 170 144 0 0 1600 1002 </string>
|
||||
<key>160</key>
|
||||
<string>496 172 195 666 0 0 1152 848 </string>
|
||||
<key>28</key>
|
||||
<string>478 352 195 457 0 0 1152 848 </string>
|
||||
<key>297</key>
|
||||
<string>107 466 213 294 0 0 1600 1002 </string>
|
||||
<key>314</key>
|
||||
<string>72 544 213 150 0 0 1600 1002 </string>
|
||||
<key>336</key>
|
||||
<string>486 756 213 180 0 0 1600 1002 </string>
|
||||
<key>365</key>
|
||||
<string>31 719 93 162 0 0 1600 1002 </string>
|
||||
<key>463</key>
|
||||
<string>349 487 213 246 0 0 1600 1002 </string>
|
||||
<key>56</key>
|
||||
<string>450 634 343 68 0 0 1280 1002 </string>
|
||||
<key>654</key>
|
||||
<string>140 644 198 144 0 0 1152 848 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<key>IBGroupedObjects</key>
|
||||
<dict>
|
||||
<key>7</key>
|
||||
<array>
|
||||
<string>641</string>
|
||||
<string>640</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>IBLastGroupID</key>
|
||||
<string>8</string>
|
||||
<key>IBLockedObjects</key>
|
||||
<array/>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
Двоичные данные
chimera/resources/localized/English.lproj/BrowserWindow.nib/objects.nib
сгенерированный
Двоичные данные
chimera/resources/localized/English.lproj/BrowserWindow.nib/objects.nib
сгенерированный
Двоичный файл не отображается.
Двоичные данные
chimera/resources/localized/English.lproj/Localizable.strings
Двоичные данные
chimera/resources/localized/English.lproj/Localizable.strings
Двоичный файл не отображается.
|
@ -1,87 +0,0 @@
|
|||
{
|
||||
IBClasses = (
|
||||
{
|
||||
CLASS = BrowserToolbarController;
|
||||
LANGUAGE = ObjC;
|
||||
SUPERCLASS = ToolbarController;
|
||||
},
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{CLASS = GoMenu; LANGUAGE = ObjC; SUPERCLASS = NSMenu; },
|
||||
{
|
||||
ACTIONS = {
|
||||
aboutServers = id;
|
||||
addBookmark = id;
|
||||
addFolder = id;
|
||||
addSeparator = id;
|
||||
biggerTextSize = id;
|
||||
closeTab = id;
|
||||
connectToServer = id;
|
||||
displayPreferencesWindow = id;
|
||||
doReload = id;
|
||||
doSearch = id;
|
||||
doStop = id;
|
||||
downloadsWindow = id;
|
||||
exportBookmarks = id;
|
||||
feedbackLink = id;
|
||||
findAgain = id;
|
||||
findInPage = id;
|
||||
getInfo = id;
|
||||
goBack = id;
|
||||
goForward = id;
|
||||
goHome = id;
|
||||
importBookmarks = id;
|
||||
infoLink = id;
|
||||
manageSidebar = id;
|
||||
newTab = id;
|
||||
newWindow = id;
|
||||
nextTab = id;
|
||||
openFile = id;
|
||||
openLocation = id;
|
||||
openMenuBookmark = id;
|
||||
pageSetup = id;
|
||||
previousTab = id;
|
||||
printPage = id;
|
||||
savePage = id;
|
||||
sendURL = id;
|
||||
showAboutBox = id;
|
||||
smallerTextSize = id;
|
||||
toggleBookmarksToolbar = id;
|
||||
toggleOfflineMode = id;
|
||||
toggleSidebar = id;
|
||||
viewSource = id;
|
||||
};
|
||||
CLASS = MainController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mAddBookmarkMenuItem = NSMenuItem;
|
||||
mApplication = NSApplication;
|
||||
mBookmarksMenu = NSMenu;
|
||||
mBookmarksToolbarMenuItem = NSMenuItem;
|
||||
mCloseTabMenuItem = NSMenuItem;
|
||||
mCloseWindowMenuItem = NSMenuItem;
|
||||
mCreateBookmarksFolderMenuItem = NSMenuItem;
|
||||
mCreateBookmarksSeparatorMenuItem = NSMenuItem;
|
||||
mDockMenu = NSMenu;
|
||||
mFilterView = NSView;
|
||||
mGoMenu = NSMenu;
|
||||
mServersSubmenu = NSMenu;
|
||||
mToggleSidebarMenuItem = NSMenuItem;
|
||||
};
|
||||
SUPERCLASS = NSObject;
|
||||
},
|
||||
{
|
||||
ACTIONS = {load = id; };
|
||||
CLASS = MyBrowserView;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {progress = id; progressSuper = id; status = id; urlbar = id; };
|
||||
SUPERCLASS = NSView;
|
||||
},
|
||||
{
|
||||
CLASS = ToolbarController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {mBrowserView = id; mWindow = id; };
|
||||
SUPERCLASS = NSObject;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>105 33 482 372 0 0 1600 1002 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>644 623 277 90 0 0 1600 1002 </string>
|
||||
<key>29</key>
|
||||
<string>11 957 446 44 0 0 1600 1002 </string>
|
||||
<key>494</key>
|
||||
<string>117 597 185 48 0 0 1280 1002 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<key>IBGroupedObjects</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<array>
|
||||
<string>0</string>
|
||||
<string>0</string>
|
||||
<string>0</string>
|
||||
</array>
|
||||
<key>1</key>
|
||||
<array>
|
||||
<string>0</string>
|
||||
<string>0</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>IBLastGroupID</key>
|
||||
<string>2</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>29</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
Двоичный файл не отображается.
|
@ -86,15 +86,15 @@ nsDownloadListenerConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult
|
|||
|
||||
static const nsModuleComponentInfo gAppComponents[] = {
|
||||
{
|
||||
"Security Dialogs",
|
||||
"PSM Security Warnings",
|
||||
NS_SECURITYDIALOGS_CID,
|
||||
NS_BADCERTLISTENER_CONTRACTID,
|
||||
NS_SECURITYWARNINGDIALOGS_CONTRACTID,
|
||||
SecurityDialogsConstructor
|
||||
},
|
||||
{
|
||||
"Security Dialogs",
|
||||
"Bad Cert Handler",
|
||||
NS_SECURITYDIALOGS_CID,
|
||||
NS_SECURITYWARNINGDIALOGS_CONTRACTID,
|
||||
NS_BADCERTLISTENER_CONTRACTID,
|
||||
SecurityDialogsConstructor
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,177 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "BrowserWindowController.h"
|
||||
#import "MVPreferencesController.h"
|
||||
#import "SplashScreenWindow.h"
|
||||
#import "FindDlgController.h"
|
||||
#import "PreferenceManager.h"
|
||||
#import "SharedMenusObj.h"
|
||||
#import "NetworkServices.h"
|
||||
|
||||
@class BookmarksMenu;
|
||||
@class KeychainService;
|
||||
@class NetworkServices;
|
||||
|
||||
@interface MainController : NSObject
|
||||
{
|
||||
IBOutlet NSApplication* mApplication;
|
||||
|
||||
// The following item is added to NSSavePanels as an accessory view
|
||||
IBOutlet NSView* mFilterView;
|
||||
|
||||
// IBOutlet NSMenuItem* mOfflineMenuItem;
|
||||
IBOutlet NSMenuItem* mCloseWindowMenuItem;
|
||||
IBOutlet NSMenuItem* mCloseTabMenuItem;
|
||||
IBOutlet NSMenuItem* mToggleSidebarMenuItem;
|
||||
|
||||
IBOutlet NSMenu* mGoMenu;
|
||||
IBOutlet NSMenu* mBookmarksMenu;
|
||||
IBOutlet NSMenu* mDockMenu;
|
||||
IBOutlet NSMenu* mServersSubmenu;
|
||||
|
||||
IBOutlet NSMenuItem* mBookmarksToolbarMenuItem;
|
||||
IBOutlet NSMenuItem* mAddBookmarkMenuItem;
|
||||
IBOutlet NSMenuItem* mCreateBookmarksFolderMenuItem;
|
||||
IBOutlet NSMenuItem* mCreateBookmarksSeparatorMenuItem;
|
||||
|
||||
BOOL mOffline;
|
||||
|
||||
SplashScreenWindow* mSplashScreen;
|
||||
|
||||
PreferenceManager* mPreferenceManager;
|
||||
|
||||
BookmarksMenu* mMenuBookmarks;
|
||||
BookmarksMenu* mDockBookmarks;
|
||||
|
||||
KeychainService* mKeychainService;
|
||||
|
||||
FindDlgController* mFindDialog;
|
||||
|
||||
MVPreferencesController* mPreferencesController;
|
||||
|
||||
NSString* mStartURL;
|
||||
|
||||
SharedMenusObj* mSharedMenusObj;
|
||||
NetworkServices* mNetworkServices;
|
||||
}
|
||||
|
||||
// File menu actions.
|
||||
-(IBAction) newWindow:(id)aSender;
|
||||
-(IBAction) openFile:(id)aSender;
|
||||
-(IBAction) openLocation:(id)aSender;
|
||||
-(IBAction) savePage:(id)aSender;
|
||||
-(IBAction) pageSetup:(id)aSender;
|
||||
-(IBAction) printPage:(id)aSender;
|
||||
-(IBAction) toggleOfflineMode:(id)aSender;
|
||||
-(IBAction) sendURL:(id)aSender;
|
||||
|
||||
// Edit menu actions.
|
||||
-(IBAction) findInPage:(id)aSender;
|
||||
-(IBAction) findAgain:(id)aSender;
|
||||
-(IBAction) getInfo:(id)aSender;
|
||||
|
||||
// Go menu actions.
|
||||
-(IBAction) goBack:(id)aSender;
|
||||
-(IBAction) goForward:(id)aSender;
|
||||
-(IBAction) goHome:(id)aSender;
|
||||
-(IBAction) doSearch:(id)aSender;
|
||||
-(IBAction) previousTab:(id)aSender;
|
||||
-(IBAction) nextTab:(id)aSender;
|
||||
|
||||
// Local servers submenu
|
||||
-(IBAction) aboutServers:(id)aSender;
|
||||
-(IBAction) connectToServer:(id)aSender;
|
||||
|
||||
// View menu actions.
|
||||
-(IBAction) toggleSidebar:(id)sender;
|
||||
-(IBAction) toggleBookmarksToolbar:(id)aSender;
|
||||
-(IBAction) doReload:(id)aSender;
|
||||
-(IBAction) doStop:(id)aSender;
|
||||
-(IBAction) biggerTextSize:(id)aSender;
|
||||
-(IBAction) smallerTextSize:(id)aSender;
|
||||
-(IBAction) viewSource:(id)aSender;
|
||||
-(IBAction) manageSidebar: (id)aSender;
|
||||
|
||||
// Bookmarks menu actions.
|
||||
-(IBAction) importBookmarks:(id)aSender;
|
||||
-(IBAction) exportBookmarks:(id)aSender;
|
||||
-(IBAction) addBookmark:(id)aSender;
|
||||
-(IBAction) openMenuBookmark:(id)aSender;
|
||||
-(IBAction) addFolder:(id)aSender;
|
||||
-(IBAction) addSeparator:(id)aSender;
|
||||
|
||||
// Window menu actions
|
||||
-(IBAction) newTab:(id)aSender;
|
||||
-(IBAction) closeTab:(id)aSender;
|
||||
-(IBAction) downloadsWindow:(id)aSender;
|
||||
|
||||
// Help menu actions
|
||||
-(IBAction) infoLink:(id)aSender;
|
||||
-(IBAction) feedbackLink:(id)aSender;
|
||||
|
||||
-(BrowserWindowController*)openBrowserWindowWithURL: (NSString*)aURL andReferrer: (NSString*)aReferrer;
|
||||
- (void)openNewWindowOrTabWithURL:(NSString*)inURLString andReferrer:(NSString*)aReferrer;
|
||||
|
||||
- (void)adjustCloseWindowMenuItemKeyEquivalent:(BOOL)inHaveTabs;
|
||||
- (void)adjustCloseTabMenuItemKeyEquivalent:(BOOL)inHaveTabs;
|
||||
- (void)fixCloseMenuItemKeyEquivalents;
|
||||
|
||||
- (void)adjustBookmarksMenuItemsEnabling:(BOOL)inBrowserWindowFrontmost;
|
||||
|
||||
- (NSView*)getSavePanelView;
|
||||
- (NSWindow*)getFrontmostBrowserWindow;
|
||||
|
||||
- (MVPreferencesController *)preferencesController;
|
||||
- (void)displayPreferencesWindow:sender;
|
||||
- (PreferenceManager *)preferenceManager;
|
||||
- (BOOL)isMainWindowABrowserWindow;
|
||||
|
||||
// if the main window is a browser window, return its controller, otherwise nil
|
||||
- (BrowserWindowController*)getMainWindowBrowserController;
|
||||
|
||||
- (IBAction)showAboutBox:(id)sender;
|
||||
|
||||
+ (NSImage*)createImageForDragging:(NSImage*)aIcon title:(NSString*)aTitle;
|
||||
|
||||
- (void)updatePrebinding;
|
||||
- (void)prebindFinished:(NSNotification *)aNotification;
|
||||
|
||||
- (void)pumpGeckoEventQueue;
|
||||
|
||||
@end
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,140 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Christopher Seawood <cls@seawood.org>
|
||||
* Chris Waterson <waterson@netscape.com>
|
||||
*/
|
||||
|
||||
#line 26 "nsStaticComponents.cpp.in"
|
||||
#define XPCOM_TRANSLATE_NSGM_ENTRY_POINT 1
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsStaticComponent.h"
|
||||
|
||||
/**
|
||||
* Construct a unique NSGetModule entry point for a generic module.
|
||||
*/
|
||||
#define NSGETMODULE(_name) _name##_NSGetmodule
|
||||
|
||||
/**
|
||||
* Declare an NSGetModule() routine for a generic module.
|
||||
*/
|
||||
#define DECL_NSGETMODULE(_name) \
|
||||
extern nsModuleInfo NSMODULEINFO(_name); \
|
||||
extern "C" NS_EXPORT nsresult \
|
||||
NSGETMODULE(_name) (nsIComponentManager* aCompMgr, \
|
||||
nsIFile* aLocation, \
|
||||
nsIModule** aResult) \
|
||||
{ \
|
||||
return NS_NewGenericModule2(&NSMODULEINFO(_name), aResult);\
|
||||
}
|
||||
|
||||
// NSGetModule entry points
|
||||
DECL_NSGETMODULE(nsUConvModule)
|
||||
DECL_NSGETMODULE(nsI18nModule)
|
||||
DECL_NSGETMODULE(xpconnect)
|
||||
DECL_NSGETMODULE(necko_core_and_primary_protocols)
|
||||
DECL_NSGETMODULE(necko_secondary_protocols)
|
||||
DECL_NSGETMODULE(nsURILoaderModule)
|
||||
DECL_NSGETMODULE(nsPrefModule)
|
||||
DECL_NSGETMODULE(nsCJVMManagerModule)
|
||||
DECL_NSGETMODULE(nsSecurityManagerModule)
|
||||
DECL_NSGETMODULE(nsChromeModule)
|
||||
DECL_NSGETMODULE(nsRDFModule)
|
||||
DECL_NSGETMODULE(nsParserModule)
|
||||
DECL_NSGETMODULE(nsGfxMacModule)
|
||||
DECL_NSGETMODULE(nsImageLib2Module)
|
||||
DECL_NSGETMODULE(nsPluginModule)
|
||||
DECL_NSGETMODULE(javascript__protocol)
|
||||
DECL_NSGETMODULE(DOM_components)
|
||||
DECL_NSGETMODULE(nsViewModule)
|
||||
DECL_NSGETMODULE(nsWidgetMacModule)
|
||||
DECL_NSGETMODULE(nsContentModule)
|
||||
DECL_NSGETMODULE(nsLayoutModule)
|
||||
DECL_NSGETMODULE(nsMorkModule)
|
||||
DECL_NSGETMODULE(docshell_provider)
|
||||
DECL_NSGETMODULE(embedcomponents)
|
||||
DECL_NSGETMODULE(Browser_Embedding_Module)
|
||||
DECL_NSGETMODULE(nsEditorModule)
|
||||
DECL_NSGETMODULE(nsTransactionManagerModule)
|
||||
DECL_NSGETMODULE(nsProfileModule)
|
||||
DECL_NSGETMODULE(Session_History_Module)
|
||||
DECL_NSGETMODULE(application)
|
||||
DECL_NSGETMODULE(nsCookieModule)
|
||||
DECL_NSGETMODULE(nsXMLExtrasModule)
|
||||
DECL_NSGETMODULE(nsUniversalCharDetModule)
|
||||
DECL_NSGETMODULE(BOOT)
|
||||
DECL_NSGETMODULE(NSS)
|
||||
#line 52 "nsStaticComponents.cpp.in"
|
||||
|
||||
/**
|
||||
* The nsStaticModuleInfo
|
||||
*/
|
||||
static nsStaticModuleInfo gStaticModuleInfo[] = {
|
||||
#define MODULE(_name) { (#_name), NSGETMODULE(_name) }
|
||||
MODULE(nsUConvModule),
|
||||
MODULE(nsI18nModule),
|
||||
MODULE(xpconnect),
|
||||
MODULE(necko_core_and_primary_protocols),
|
||||
MODULE(necko_secondary_protocols),
|
||||
MODULE(nsURILoaderModule),
|
||||
MODULE(nsPrefModule),
|
||||
MODULE(nsCJVMManagerModule),
|
||||
MODULE(nsSecurityManagerModule),
|
||||
MODULE(nsChromeModule),
|
||||
MODULE(nsRDFModule),
|
||||
MODULE(nsParserModule),
|
||||
MODULE(nsGfxMacModule),
|
||||
MODULE(nsImageLib2Module),
|
||||
MODULE(nsPluginModule),
|
||||
MODULE(javascript__protocol),
|
||||
MODULE(DOM_components),
|
||||
MODULE(nsViewModule),
|
||||
MODULE(nsWidgetMacModule),
|
||||
MODULE(nsContentModule),
|
||||
MODULE(nsLayoutModule),
|
||||
MODULE(nsMorkModule),
|
||||
MODULE(docshell_provider),
|
||||
MODULE(embedcomponents),
|
||||
MODULE(Browser_Embedding_Module),
|
||||
MODULE(nsEditorModule),
|
||||
MODULE(nsTransactionManagerModule),
|
||||
MODULE(nsProfileModule),
|
||||
MODULE(Session_History_Module),
|
||||
MODULE(application),
|
||||
MODULE(nsCookieModule),
|
||||
MODULE(nsXMLExtrasModule),
|
||||
MODULE(nsUniversalCharDetModule),
|
||||
MODULE(BOOT),
|
||||
MODULE(NSS),
|
||||
#line 60 "nsStaticComponents.cpp.in"
|
||||
};
|
||||
|
||||
/**
|
||||
* Our NSGetStaticModuleInfoFunc
|
||||
*/
|
||||
nsresult
|
||||
app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count)
|
||||
{
|
||||
*info = gStaticModuleInfo;
|
||||
*count = sizeof(gStaticModuleInfo) / sizeof(gStaticModuleInfo[0]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef BookmarksExport_h__
|
||||
#define BookmarksExport_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIDOMElement;
|
||||
|
||||
class BookmarksExport
|
||||
{
|
||||
public:
|
||||
|
||||
BookmarksExport(nsIDOMDocument* inBookmarksDoc, const char* inLinebreakStr = "\n");
|
||||
~BookmarksExport();
|
||||
|
||||
// at some point we could use subclassing to support different export formats
|
||||
nsresult ExportBookmarksToHTML(const nsAString& inFilePath);
|
||||
|
||||
protected:
|
||||
|
||||
nsresult SetupOutputStream(const nsAString& inFilePath);
|
||||
void CloseOutputStream();
|
||||
|
||||
// return false on failure (mWriteStatus set)
|
||||
bool WriteChildren(nsIDOMElement* inElement, PRInt32 inDepth);
|
||||
bool WriteItem(nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot = PR_FALSE);
|
||||
|
||||
void WritePrologue();
|
||||
void WriteString(const char*inString, PRInt32 inLen);
|
||||
void WriteLinebreak();
|
||||
|
||||
protected:
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> mBookmarksDocument;
|
||||
nsCOMPtr<nsIOutputStream> mOutputStream;
|
||||
const char* mLinebreakStr;
|
||||
nsresult mWriteStatus;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BookmarksExport_h__
|
|
@ -1,286 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#import "BookmarksExport.h"
|
||||
#import "BookmarksService.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
/*
|
||||
Netscape HTML bookmarks format is:
|
||||
|
||||
<dl><p>
|
||||
<dt><h3>folder</h3>
|
||||
<dl><p>
|
||||
<dt>
|
||||
<dt>
|
||||
...
|
||||
</dl>
|
||||
..
|
||||
</dl>
|
||||
|
||||
*/
|
||||
|
||||
|
||||
BookmarksExport::BookmarksExport(nsIDOMDocument* inBookmarksDoc, const char* inLinebreakStr)
|
||||
: mBookmarksDocument(inBookmarksDoc)
|
||||
, mLinebreakStr(inLinebreakStr)
|
||||
, mWriteStatus(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
BookmarksExport::~BookmarksExport()
|
||||
{
|
||||
if (mOutputStream)
|
||||
(void)mOutputStream->Close();
|
||||
}
|
||||
|
||||
nsresult
|
||||
BookmarksExport::ExportBookmarksToHTML(const nsAString& inFilePath)
|
||||
{
|
||||
if (!mBookmarksDocument)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsresult rv = SetupOutputStream(inFilePath);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
WritePrologue();
|
||||
nsCOMPtr<nsIDOMElement> docElement;
|
||||
mBookmarksDocument->GetDocumentElement(getter_AddRefs(docElement));
|
||||
WriteItem(docElement, 0, PR_TRUE);
|
||||
|
||||
CloseOutputStream();
|
||||
return mWriteStatus;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BookmarksExport::SetupOutputStream(const nsAString& inFilePath)
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> destFile;
|
||||
nsresult rv = NS_NewLocalFile(inFilePath, PR_FALSE, getter_AddRefs(destFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), destFile);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// we have to give the file a 'TEXT' type for IE to import it correctly
|
||||
nsCOMPtr<nsILocalFileMac> macDestFile = do_QueryInterface(destFile);
|
||||
if (macDestFile)
|
||||
rv = macDestFile->SetFileType('TEXT');
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
BookmarksExport::CloseOutputStream()
|
||||
{
|
||||
(void)mOutputStream->Close();
|
||||
mOutputStream = nsnull;
|
||||
}
|
||||
|
||||
bool
|
||||
BookmarksExport::WriteChildren(nsIDOMElement* inElement, PRInt32 inDepth)
|
||||
{
|
||||
nsCOMPtr<nsIContent> curContent = do_QueryInterface(inElement);
|
||||
if (!curContent) return false;
|
||||
|
||||
// recurse to children
|
||||
PRInt32 numChildren;
|
||||
curContent->ChildCount(numChildren);
|
||||
for (PRInt32 i = 0; i < numChildren; i ++)
|
||||
{
|
||||
nsCOMPtr<nsIContent> curChild;
|
||||
curContent->ChildAt(i, *getter_AddRefs(curChild));
|
||||
|
||||
nsCOMPtr<nsIDOMElement> curElt = do_QueryInterface(curChild);
|
||||
if (!WriteItem(curElt, inDepth))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BookmarksExport::WriteItem(nsIDOMElement* inElement, PRInt32 inDepth, PRBool isRoot)
|
||||
{
|
||||
nsCOMPtr<nsIContent> curContent = do_QueryInterface(inElement);
|
||||
if (!inElement || !curContent)
|
||||
return false;
|
||||
|
||||
nsCOMPtr<nsIAtom> tagName;
|
||||
curContent->GetTag(*getter_AddRefs(tagName));
|
||||
|
||||
PRBool isContainer = isRoot || (tagName == BookmarksService::gFolderAtom);
|
||||
|
||||
nsAutoString href, title;
|
||||
|
||||
const char* const spaces = " ";
|
||||
const char* indentString = spaces + strlen(spaces) - (inDepth * 4);
|
||||
if (indentString < spaces)
|
||||
indentString = spaces;
|
||||
|
||||
if (isContainer)
|
||||
{
|
||||
if (!isRoot)
|
||||
{
|
||||
WriteString(indentString, strlen(indentString));
|
||||
|
||||
const char* const prefixString = "<DT><H3";
|
||||
WriteString(prefixString, strlen(prefixString));
|
||||
|
||||
nsAutoString typeAttribute;
|
||||
inElement->GetAttribute(NS_LITERAL_STRING("type"), typeAttribute);
|
||||
if (typeAttribute.Equals(NS_LITERAL_STRING("toolbar")))
|
||||
{
|
||||
const char* persToolbar = " PERSONAL_TOOLBAR_FOLDER=\"true\"";
|
||||
WriteString(persToolbar, strlen(persToolbar));
|
||||
}
|
||||
|
||||
WriteString(">", 1);
|
||||
|
||||
inElement->GetAttribute(NS_LITERAL_STRING("name"), title);
|
||||
|
||||
NS_ConvertUCS2toUTF8 titleConverter(title);
|
||||
const char* utf8String = titleConverter.get();
|
||||
|
||||
// we really need to convert entities in the title, like < > etc.
|
||||
WriteString(utf8String, strlen(utf8String));
|
||||
|
||||
WriteString("</H3>", 5);
|
||||
WriteLinebreak();
|
||||
}
|
||||
|
||||
WriteString(indentString, strlen(indentString));
|
||||
WriteString("<DL><p>", 7);
|
||||
WriteLinebreak();
|
||||
|
||||
if (!WriteChildren(inElement, inDepth + 1))
|
||||
return false;
|
||||
|
||||
WriteString(indentString, strlen(indentString));
|
||||
WriteString("</DL><p>", 8);
|
||||
WriteLinebreak();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tagName == BookmarksService::gBookmarkAtom)
|
||||
{
|
||||
WriteString(indentString, strlen(indentString));
|
||||
|
||||
const char* const bookmarkPrefix = "<DT><A HREF=\"";
|
||||
WriteString(bookmarkPrefix, strlen(bookmarkPrefix));
|
||||
|
||||
inElement->GetAttribute(NS_LITERAL_STRING("href"), href);
|
||||
inElement->GetAttribute(NS_LITERAL_STRING("name"), title);
|
||||
|
||||
NS_ConvertUCS2toUTF8 hrefConverter(href);
|
||||
const char* utf8String = hrefConverter.get();
|
||||
|
||||
WriteString(utf8String, strlen(utf8String));
|
||||
WriteString("\">", 2);
|
||||
|
||||
NS_ConvertUCS2toUTF8 titleConverter(title);
|
||||
utf8String = titleConverter.get();
|
||||
|
||||
WriteString(utf8String, strlen(utf8String));
|
||||
WriteString("</A>", 4);
|
||||
WriteLinebreak();
|
||||
}
|
||||
else if (tagName == BookmarksService::gSeparatorAtom)
|
||||
{
|
||||
WriteString(indentString, strlen(indentString));
|
||||
WriteString("<HR>", 4);
|
||||
WriteLinebreak();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BookmarksExport::WritePrologue()
|
||||
{
|
||||
const char* const gPrologueLines[] = {
|
||||
"<!DOCTYPE NETSCAPE-Bookmark-file-1>",
|
||||
"<!-- This is an automatically generated file.",
|
||||
"It will be read and overwritten.",
|
||||
"Do Not Edit! -->",
|
||||
"<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">",
|
||||
"<TITLE>Bookmarks</TITLE>",
|
||||
"<H1>Bookmarks</H1>",
|
||||
"",
|
||||
nil
|
||||
};
|
||||
|
||||
char* const *linePtr = gPrologueLines;
|
||||
|
||||
while (*linePtr)
|
||||
{
|
||||
WriteString(*linePtr, strlen(*linePtr));
|
||||
WriteLinebreak();
|
||||
linePtr++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BookmarksExport::WriteString(const char*inString, PRInt32 inLen)
|
||||
{
|
||||
PRUint32 bytesWritten;
|
||||
if (mWriteStatus == NS_OK)
|
||||
mWriteStatus = mOutputStream->Write(inString, inLen, &bytesWritten);
|
||||
}
|
||||
|
||||
void
|
||||
BookmarksExport::WriteLinebreak()
|
||||
{
|
||||
WriteString(mLinebreakStr, strlen(mLinebreakStr));
|
||||
}
|
||||
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,93 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2002 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Hewitt <hewitt@netscape.com> (Original Author)
|
||||
* David Haas <haasd@cae.wisc.edu>
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "AutoCompleteDataSource.h"
|
||||
#include "nsIAutoCompleteSession.h"
|
||||
#include "nsIAutoCompleteResults.h"
|
||||
#include "nsIAutoCompleteListener.h"
|
||||
|
||||
@class BookmarksOutlineView, PageProxyIcon;
|
||||
|
||||
@interface AutoCompleteTextField : NSTextField
|
||||
{
|
||||
IBOutlet PageProxyIcon *mProxyIcon;
|
||||
NSWindow *mPopupWin;
|
||||
NSTableView *mTableView;
|
||||
|
||||
AutoCompleteDataSource *mDataSource;
|
||||
|
||||
nsIAutoCompleteSession *mSession;
|
||||
nsIAutoCompleteResults *mResults;
|
||||
nsIAutoCompleteListener *mListener;
|
||||
|
||||
NSString *mSearchString;
|
||||
|
||||
// used to remember if backspace was pressed in complete: so we can check this in controlTextDidChange
|
||||
BOOL mBackspaced;
|
||||
// determines if the search currently pending should complete the default result when it is ready
|
||||
BOOL mCompleteResult;
|
||||
// should the autocomplete fill in the default completion into the text field? The default
|
||||
// is no, but this can be set with a user default pref.
|
||||
BOOL mCompleteWhileTyping;
|
||||
|
||||
NSTimer *mOpenTimer;
|
||||
}
|
||||
|
||||
- (void) setSession:(NSString *)aSession;
|
||||
- (NSString *) session;
|
||||
- (void) setPageProxyIcon:(NSImage *)aImage;
|
||||
|
||||
- (NSTableView *) tableView;
|
||||
- (int) visibleRows;
|
||||
|
||||
- (void) startSearch:(NSString*)aString complete:(BOOL)aComplete;
|
||||
- (void) performSearch;
|
||||
- (void) dataReady:(nsIAutoCompleteResults*)aResults status:(AutoCompleteStatus)aStatus;
|
||||
- (void) searchTimer:(NSTimer *)aTimer;
|
||||
- (void) clearResults;
|
||||
|
||||
- (void) completeDefaultResult;
|
||||
- (void) completeSelectedResult;
|
||||
- (void) completeResult:(int)aRow;
|
||||
- (void) enterResult:(int)aRow;
|
||||
- (void) revertText;
|
||||
|
||||
- (void) selectRowAt:(int)aRow;
|
||||
- (void) selectRowBy:(int)aRows;
|
||||
|
||||
- (void) openPopup;
|
||||
- (void) closePopup;
|
||||
- (void) resizePopup;
|
||||
- (BOOL) isOpen;
|
||||
|
||||
- (void) onRowClicked:(NSNotification *)aNote;
|
||||
- (void) onBlur:(NSNotification *)aNote;
|
||||
- (void) onResize:(NSNotification *)aNote;
|
||||
- (void) onUndoOrRedo:(NSNotification *)aNote;
|
||||
|
||||
- (void) setStringUndoably:(NSString*)aString fromLocation:(unsigned int)aLocation;
|
||||
- (id) fieldEditor;
|
||||
|
||||
@end
|
|
@ -1,626 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2002 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Hewitt <hewitt@netscape.com> (Original Author)
|
||||
* David Haas <haasd@cae.wisc.edu>
|
||||
*/
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
#import "AutoCompleteTextField.h"
|
||||
#import "BrowserWindowController.h"
|
||||
#import "PageProxyIcon.h"
|
||||
#import "CHBrowserService.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsString.h"
|
||||
#include "UserDefaults.h"
|
||||
|
||||
static const int kMaxRows = 6;
|
||||
static const int kFrameMargin = 1;
|
||||
|
||||
@interface AutoCompleteWindow : NSWindow
|
||||
- (BOOL)isKeyWindow;
|
||||
@end
|
||||
|
||||
@implementation AutoCompleteWindow
|
||||
|
||||
- (BOOL)isKeyWindow
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
||||
class AutoCompleteListener : public nsIAutoCompleteListener
|
||||
{
|
||||
public:
|
||||
AutoCompleteListener(AutoCompleteTextField* aTextField)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mTextField = aTextField;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHODIMP OnStatus(const PRUnichar* aText) { return NS_OK; }
|
||||
NS_IMETHODIMP SetParam(nsISupports *aParam) { return NS_OK; }
|
||||
NS_IMETHODIMP GetParam(nsISupports **aParam) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP OnAutoComplete(nsIAutoCompleteResults *aResults, AutoCompleteStatus aStatus)
|
||||
{
|
||||
[mTextField dataReady:aResults status:aStatus];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
AutoCompleteTextField *mTextField;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(AutoCompleteListener, nsIAutoCompleteListener)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@interface AutoCompleteTextField(Private)
|
||||
- (void)cleanup;
|
||||
@end
|
||||
|
||||
@implementation AutoCompleteTextField
|
||||
|
||||
- (void) awakeFromNib
|
||||
{
|
||||
NSTableColumn *column;
|
||||
NSScrollView *scrollView;
|
||||
NSCell *dataCell;
|
||||
|
||||
mSearchString = nil;
|
||||
mBackspaced = NO;
|
||||
mCompleteResult = NO;
|
||||
mOpenTimer = nil;
|
||||
|
||||
mSession = nsnull;
|
||||
mResults = nsnull;
|
||||
mListener = (nsIAutoCompleteListener *)new AutoCompleteListener(self);
|
||||
NS_IF_ADDREF(mListener);
|
||||
|
||||
[self setFont:[NSFont controlContentFontOfSize:0]];
|
||||
[self setDelegate: self];
|
||||
|
||||
// XXX the owner of the textfield should set this
|
||||
[self setSession:@"history"];
|
||||
|
||||
// construct and configure the popup window
|
||||
mPopupWin = [[AutoCompleteWindow alloc] initWithContentRect:NSMakeRect(0,0,0,0)
|
||||
styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||
[mPopupWin setReleasedWhenClosed:NO];
|
||||
[mPopupWin setLevel:NSFloatingWindowLevel];
|
||||
[mPopupWin setHasShadow:YES];
|
||||
[mPopupWin setAlphaValue:0.9];
|
||||
|
||||
// construct and configure the view
|
||||
mTableView = [[[NSTableView alloc] initWithFrame:NSMakeRect(0,0,0,0)] autorelease];
|
||||
[mTableView setIntercellSpacing:NSMakeSize(1, 2)];
|
||||
[mTableView setTarget:self];
|
||||
[mTableView setAction:@selector(onRowClicked:)];
|
||||
|
||||
// Create the icon column if we have a proxy icon
|
||||
if (mProxyIcon) {
|
||||
column = [[[NSTableColumn alloc] initWithIdentifier:@"icon"] autorelease];
|
||||
[column setWidth:[mProxyIcon frame].origin.x + [mProxyIcon frame].size.width];
|
||||
dataCell = [[[NSImageCell alloc] initImageCell:nil] autorelease];
|
||||
[column setDataCell:dataCell];
|
||||
[mTableView addTableColumn: column];
|
||||
}
|
||||
|
||||
// create the text columns
|
||||
column = [[[NSTableColumn alloc] initWithIdentifier:@"col1"] autorelease];
|
||||
[mTableView addTableColumn: column];
|
||||
column = [[[NSTableColumn alloc] initWithIdentifier:@"col2"] autorelease];
|
||||
[[column dataCell] setTextColor:[NSColor darkGrayColor]];
|
||||
[mTableView addTableColumn: column];
|
||||
|
||||
// hide the table header
|
||||
[mTableView setHeaderView:nil];
|
||||
|
||||
// construct the scroll view that contains the table view
|
||||
scrollView = [[[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,0,0)] autorelease];
|
||||
[scrollView setHasVerticalScroller:YES];
|
||||
[[scrollView verticalScroller] setControlSize:NSSmallControlSize];
|
||||
[scrollView setDocumentView: mTableView];
|
||||
|
||||
// construct the datasource
|
||||
mDataSource = [[AutoCompleteDataSource alloc] init];
|
||||
[mTableView setDataSource: mDataSource];
|
||||
|
||||
[mPopupWin setContentView:scrollView];
|
||||
|
||||
// listen for when window resigns from key handling
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onBlur:)
|
||||
name:NSWindowDidResignKeyNotification object:nil];
|
||||
|
||||
// listen for when window is about to be moved or resized
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onBlur:)
|
||||
name:NSWindowWillMoveNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResize:)
|
||||
name:NSWindowDidResizeNotification object:nil];
|
||||
|
||||
// listen for Undo/Redo to make sure autocomplete doesn't get horked.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onUndoOrRedo:)
|
||||
name:NSUndoManagerDidRedoChangeNotification
|
||||
object:[[self fieldEditor] undoManager]];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onUndoOrRedo:)
|
||||
name:NSUndoManagerDidUndoChangeNotification
|
||||
object:[[self fieldEditor] undoManager]];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self
|
||||
selector: @selector(shutdown:)
|
||||
name: XPCOMShutDownNotificationName
|
||||
object: nil];
|
||||
|
||||
// read the user default on if we should auto-complete the text field as the user
|
||||
// types or make them pick something from a list (a-la mozilla).
|
||||
mCompleteWhileTyping = [[NSUserDefaults standardUserDefaults] boolForKey:USER_DEFAULTS_AUTOCOMPLETE_WHILE_TYPING];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[self cleanup];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)cleanup
|
||||
{
|
||||
[mSearchString release]; mSearchString = nil;
|
||||
[mPopupWin release]; mPopupWin = nil;
|
||||
[mDataSource release]; mDataSource = nil;
|
||||
|
||||
NS_IF_RELEASE(mSession);
|
||||
NS_IF_RELEASE(mResults);
|
||||
NS_IF_RELEASE(mListener);
|
||||
}
|
||||
|
||||
- (void)shutdown: (NSNotification*)aNotification
|
||||
{
|
||||
[self cleanup];
|
||||
}
|
||||
|
||||
- (void) setSession:(NSString *)aSession
|
||||
{
|
||||
NS_IF_RELEASE(mSession);
|
||||
|
||||
// XXX add aSession to contract id
|
||||
nsCOMPtr<nsIAutoCompleteSession> session =
|
||||
do_GetService("@mozilla.org/autocompleteSession;1?type=history");
|
||||
mSession = session;
|
||||
NS_IF_ADDREF(mSession);
|
||||
}
|
||||
|
||||
- (NSString *) session
|
||||
{
|
||||
// XXX return session name
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (NSTableView *) tableView
|
||||
{
|
||||
return mTableView;
|
||||
}
|
||||
|
||||
- (int) visibleRows
|
||||
{
|
||||
int minRows = [mDataSource rowCount];
|
||||
return minRows < kMaxRows ? minRows : kMaxRows;
|
||||
}
|
||||
|
||||
- (void) setPageProxyIcon:(NSImage *)aImage
|
||||
{
|
||||
[mProxyIcon setImage:aImage];
|
||||
}
|
||||
|
||||
-(id) fieldEditor
|
||||
{
|
||||
return [[self window] fieldEditor:NO forObject:self];
|
||||
}
|
||||
// searching ////////////////////////////
|
||||
|
||||
- (void) startSearch:(NSString*)aString complete:(BOOL)aComplete
|
||||
{
|
||||
if (mSearchString)
|
||||
[mSearchString release];
|
||||
mSearchString = [aString retain];
|
||||
|
||||
mCompleteResult = aComplete;
|
||||
|
||||
if ([self isOpen]) {
|
||||
[self performSearch];
|
||||
} else {
|
||||
// delay the search when the popup is not yet opened so that users
|
||||
// don't see a jerky flashing popup when they start typing for the first time
|
||||
if (mOpenTimer) {
|
||||
[mOpenTimer invalidate];
|
||||
[mOpenTimer release];
|
||||
}
|
||||
|
||||
mOpenTimer = [[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(searchTimer:)
|
||||
userInfo:nil repeats:NO] retain];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) performSearch
|
||||
{
|
||||
nsAutoString searchString;
|
||||
[mSearchString assignTo_nsAString:searchString];
|
||||
nsresult rv = mSession->OnStartLookup(searchString.get(), mResults, mListener);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
NSLog(@"Unable to perform autocomplete lookup");
|
||||
}
|
||||
|
||||
- (void) dataReady:(nsIAutoCompleteResults*)aResults status:(AutoCompleteStatus)aStatus
|
||||
{
|
||||
NS_IF_RELEASE(mResults);
|
||||
mResults = nsnull;
|
||||
|
||||
if (aStatus == nsIAutoCompleteStatus::failed) {
|
||||
[mDataSource setErrorMessage:@""];
|
||||
} else if (aStatus == nsIAutoCompleteStatus::ignored) {
|
||||
[mDataSource setErrorMessage:@""];
|
||||
} else if (aStatus == nsIAutoCompleteStatus::noMatch) {
|
||||
[mDataSource setErrorMessage:@""];
|
||||
} else if (aStatus == nsIAutoCompleteStatus::matchFound) {
|
||||
mResults = aResults;
|
||||
NS_IF_ADDREF(mResults);
|
||||
[mDataSource setResults:aResults];
|
||||
[self completeDefaultResult];
|
||||
}
|
||||
|
||||
if ([mDataSource rowCount] > 0) {
|
||||
[mTableView noteNumberOfRowsChanged];
|
||||
[self openPopup];
|
||||
} else {
|
||||
[self closePopup];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) searchTimer:(NSTimer *)aTimer
|
||||
{
|
||||
[mOpenTimer release];
|
||||
mOpenTimer = nil;
|
||||
|
||||
[self performSearch];
|
||||
}
|
||||
|
||||
- (void) clearResults
|
||||
{
|
||||
// clear out search data
|
||||
if (mSearchString)
|
||||
[mSearchString release];
|
||||
mSearchString = nil;
|
||||
NS_IF_RELEASE(mResults);
|
||||
mResults = nsnull;
|
||||
|
||||
[mDataSource setResults:nil];
|
||||
|
||||
[self closePopup];
|
||||
}
|
||||
|
||||
// handling the popup /////////////////////////////////
|
||||
|
||||
- (void) openPopup
|
||||
{
|
||||
[self resizePopup];
|
||||
|
||||
// show the popup
|
||||
if ([mPopupWin isVisible] == NO)
|
||||
[mPopupWin orderFront:nil];
|
||||
}
|
||||
|
||||
- (void) resizePopup
|
||||
{
|
||||
NSRect locationFrame, winFrame;
|
||||
NSPoint locationOrigin;
|
||||
int tableHeight;
|
||||
|
||||
if ([self visibleRows] == 0) {
|
||||
[self closePopup];
|
||||
return;
|
||||
}
|
||||
|
||||
// get the origin of the location bar in coordinates of the root view
|
||||
locationFrame = [[self superview] frame];
|
||||
locationOrigin = [[[self superview] superview] convertPoint:locationFrame.origin
|
||||
toView:[[[self window] contentView] superview]];
|
||||
|
||||
// get the height of the table view
|
||||
winFrame = [[self window] frame];
|
||||
tableHeight = (int)([mTableView rowHeight]+[mTableView intercellSpacing].height)*[self visibleRows];
|
||||
|
||||
// make the columns split the width of the popup
|
||||
[[mTableView tableColumnWithIdentifier:@"col1"] setWidth:locationFrame.size.width/2];
|
||||
|
||||
// position the popup anchored to bottom/left of location bar (
|
||||
[mPopupWin setFrame:NSMakeRect(winFrame.origin.x + locationOrigin.x + kFrameMargin,
|
||||
((winFrame.origin.y + locationOrigin.y) - tableHeight) - kFrameMargin,
|
||||
locationFrame.size.width - (2*kFrameMargin),
|
||||
tableHeight) display:NO];
|
||||
}
|
||||
|
||||
- (void) closePopup
|
||||
{
|
||||
[mPopupWin close];
|
||||
}
|
||||
|
||||
- (BOOL) isOpen
|
||||
{
|
||||
return [mPopupWin isVisible];
|
||||
}
|
||||
|
||||
// url completion ////////////////////////////
|
||||
|
||||
- (void) completeDefaultResult
|
||||
{
|
||||
PRInt32 defaultRow;
|
||||
mResults->GetDefaultItemIndex(&defaultRow);
|
||||
|
||||
if (mCompleteResult && mCompleteWhileTyping) {
|
||||
[self selectRowAt:defaultRow];
|
||||
[self completeResult:defaultRow];
|
||||
} else {
|
||||
[self selectRowAt:-1];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) completeSelectedResult
|
||||
{
|
||||
[self completeResult:[mTableView selectedRow]];
|
||||
}
|
||||
|
||||
- (void) completeResult:(int)aRow
|
||||
{
|
||||
if (aRow < 0 && mSearchString) {
|
||||
// reset to the original search string with the insertion point at the end. Note
|
||||
// we have to make our range before we call setStringUndoably: because it calls
|
||||
// clearResults() which destroys |mSearchString|.
|
||||
NSRange selectAtEnd = NSMakeRange([mSearchString length],0);
|
||||
[self setStringUndoably:mSearchString fromLocation:0];
|
||||
[[self fieldEditor] setSelectedRange:selectAtEnd];
|
||||
}
|
||||
else {
|
||||
if ([mDataSource rowCount] <= 0)
|
||||
return;
|
||||
|
||||
// Fill in the suggestion from the list, but change only the text
|
||||
// after what is typed and select just that part. This allows the
|
||||
// user to see what they have typed and what change the autocomplete
|
||||
// makes while allowing them to continue typing w/out having to
|
||||
// reset the insertion point.
|
||||
NSString *result = [mDataSource resultString:aRow column:@"col1"];
|
||||
NSRange matchRange = [result rangeOfString:mSearchString];
|
||||
if (matchRange.length > 0 && matchRange.location != NSNotFound) {
|
||||
unsigned int location = matchRange.location + matchRange.length;
|
||||
result = [result substringWithRange:NSMakeRange(location, [result length]-location)];
|
||||
[self setStringUndoably:result fromLocation:[mSearchString length]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) enterResult:(int)aRow
|
||||
{
|
||||
if (aRow >= 0 && [mDataSource rowCount] > 0) {
|
||||
[self setStringUndoably:[mDataSource resultString:[mTableView selectedRow] column:@"col1"] fromLocation:0];
|
||||
[self closePopup];
|
||||
} else if (mOpenTimer) {
|
||||
// if there was a search timer going when we hit enter, cancel it
|
||||
[mOpenTimer invalidate];
|
||||
[mOpenTimer release];
|
||||
mOpenTimer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) revertText
|
||||
{
|
||||
BrowserWindowController *controller = (BrowserWindowController *)[[self window] windowController];
|
||||
NSString *url = [[controller getBrowserWrapper] getCurrentURLSpec];
|
||||
if (url) {
|
||||
[self clearResults];
|
||||
NSTextView *fieldEditor = [self fieldEditor];
|
||||
[[fieldEditor undoManager] removeAllActions];
|
||||
[fieldEditor setString:url];
|
||||
[fieldEditor selectAll:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setStringUndoably:(NSString *)aString fromLocation:(unsigned int)aLocation
|
||||
{
|
||||
NSTextView *fieldEditor = [self fieldEditor];
|
||||
if ( aLocation > [[fieldEditor string] length] ) // sanity check or AppKit crashes
|
||||
return;
|
||||
NSRange range = NSMakeRange(aLocation,[[fieldEditor string] length] - aLocation);
|
||||
if ([fieldEditor shouldChangeTextInRange:range replacementString:aString]) {
|
||||
[[fieldEditor textStorage] replaceCharactersInRange:range withString:aString];
|
||||
// Whenever we send [self didChangeText], we trigger the
|
||||
// textDidChange method, which will begin a new search with
|
||||
// a new search string (which we just inserted) if the selection
|
||||
// is at the end of the string. So, we "select" the first character
|
||||
// to prevent that badness from happening.
|
||||
[fieldEditor setSelectedRange:NSMakeRange(0,0)];
|
||||
[fieldEditor didChangeText];
|
||||
}
|
||||
|
||||
// sanity check and don't update the highlight if we're starting from the
|
||||
// beginning of the string. There's no need for that since no autocomplete
|
||||
// result would ever replace the string from location 0.
|
||||
if ( aLocation > [[fieldEditor string] length] || !aLocation )
|
||||
return;
|
||||
range = NSMakeRange(aLocation,[[fieldEditor string] length] - aLocation);
|
||||
[fieldEditor setSelectedRange:range];
|
||||
}
|
||||
|
||||
// selecting rows /////////////////////////////////////////
|
||||
|
||||
- (void) selectRowAt:(int)aRow
|
||||
{
|
||||
if (aRow >= -1 && [mDataSource rowCount] > 0) {
|
||||
// show the popup
|
||||
if ([mPopupWin isVisible] == NO)
|
||||
[mPopupWin orderFront:nil];
|
||||
|
||||
if ( aRow == -1 )
|
||||
[mTableView deselectAll:self];
|
||||
else {
|
||||
[mTableView selectRow:aRow byExtendingSelection:NO];
|
||||
[mTableView scrollRowToVisible: aRow];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) selectRowBy:(int)aRows
|
||||
{
|
||||
int row = [mTableView selectedRow];
|
||||
|
||||
if (row == -1 && aRows < 0) {
|
||||
// if nothing is selected and you scroll up, go to last row
|
||||
row = [mTableView numberOfRows]-1;
|
||||
} else if (row == [mTableView numberOfRows]-1 && aRows == 1) {
|
||||
// if the last row is selected and you scroll down, do nothing. pins
|
||||
// the selection at the bottom.
|
||||
} else if (aRows+row < 0) {
|
||||
// if you scroll up beyond first row...
|
||||
if (row == 0)
|
||||
row = -1; // ...and first row is selected, select nothing
|
||||
else
|
||||
row = 0; // ...else, go to first row
|
||||
} else if (aRows+row >= [mTableView numberOfRows]) {
|
||||
// if you scroll down beyond the last row...
|
||||
if (row == [mTableView numberOfRows]-1)
|
||||
row = 0; // and last row is selected, select first row
|
||||
else
|
||||
row = [mTableView numberOfRows]-1; // else, go to last row
|
||||
} else {
|
||||
// no special case, just increment current row
|
||||
row += aRows;
|
||||
}
|
||||
|
||||
[self selectRowAt:row];
|
||||
}
|
||||
|
||||
// event handlers ////////////////////////////////////////////
|
||||
|
||||
- (void) onRowClicked:(NSNotification *)aNote
|
||||
{
|
||||
[self enterResult:[mTableView clickedRow]];
|
||||
[[[self window] windowController] goToLocationFromToolbarURLField:self];
|
||||
}
|
||||
|
||||
- (void) onBlur:(NSNotification *)aNote
|
||||
{
|
||||
// close up the popup and make sure we clear any past selection. We cannot
|
||||
// use |selectAt:-1| because that would show the popup, even for a brief instant
|
||||
// and cause flashing.
|
||||
[mTableView deselectAll:self];
|
||||
[self closePopup];
|
||||
}
|
||||
|
||||
- (void) onResize:(NSNotification *)aNote
|
||||
{
|
||||
[self resizePopup];
|
||||
}
|
||||
|
||||
- (void) onUndoOrRedo:(NSNotification *)aNote
|
||||
{
|
||||
[mTableView deselectAll:self];
|
||||
[self clearResults];
|
||||
}
|
||||
|
||||
|
||||
// NSTextField delegate //////////////////////////////////
|
||||
- (void)controlTextDidChange:(NSNotification *)aNote
|
||||
{
|
||||
NSTextView *fieldEditor = [[aNote userInfo] objectForKey:@"NSFieldEditor"];
|
||||
NSRange range = [fieldEditor selectedRange];
|
||||
// make sure we're typing at the end of the string
|
||||
if (range.location == [[fieldEditor string] length]) {
|
||||
// when we ask for a NSTextView string, Cocoa returns
|
||||
// a pointer to the view's backing store. So, the value
|
||||
// of the string continually changes as we edit the text view.
|
||||
// Since we'll edit the text view as we add in autocomplete results,
|
||||
// we've got to make a copy of the string as it currently stands
|
||||
// to know what we were searching for in the first place.
|
||||
NSString *searchString = [[fieldEditor string] copyWithZone:nil];
|
||||
[self startSearch:searchString complete:!mBackspaced];
|
||||
[searchString release];
|
||||
}
|
||||
else if (([mTableView selectedRow] == -1) || mBackspaced)
|
||||
[self clearResults];
|
||||
|
||||
mBackspaced = NO;
|
||||
}
|
||||
|
||||
- (void)controlTextDidEndEditing:(NSNotification *)aNote
|
||||
{
|
||||
[self closePopup];
|
||||
[[[[aNote userInfo] objectForKey:@"NSFieldEditor"] undoManager] removeAllActions];
|
||||
}
|
||||
|
||||
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command
|
||||
{
|
||||
if (command == @selector(insertNewline:)) {
|
||||
[self enterResult:[mTableView selectedRow]];
|
||||
[mTableView deselectAll:self];
|
||||
} else if (command == @selector(moveUp:)) {
|
||||
[self selectRowBy:-1];
|
||||
[self completeSelectedResult];
|
||||
return YES;
|
||||
} else if (command == @selector(moveDown:)) {
|
||||
[self selectRowBy:1];
|
||||
[self completeSelectedResult];
|
||||
return YES;
|
||||
} else if (command == @selector(scrollPageUp:)) {
|
||||
[self selectRowBy:-kMaxRows];
|
||||
[self completeSelectedResult];
|
||||
} else if (command == @selector(scrollPageDown:)) {
|
||||
[self selectRowBy:kMaxRows];
|
||||
[self completeSelectedResult];
|
||||
} else if (command == @selector(moveToBeginningOfDocument:)) {
|
||||
[self selectRowAt:0];
|
||||
[self completeSelectedResult];
|
||||
} else if (command == @selector(moveToEndOfDocument:)) {
|
||||
[self selectRowAt:[mTableView numberOfRows]-1];
|
||||
[self completeSelectedResult];
|
||||
} else if (command == @selector(insertTab:)) {
|
||||
if ([mPopupWin isVisible]) {
|
||||
[self selectRowBy:1];
|
||||
[self completeSelectedResult];
|
||||
return YES;
|
||||
}
|
||||
} else if (command == @selector(deleteBackward:) ||
|
||||
command == @selector(deleteForward:)) {
|
||||
// if the user deletes characters, we need to know so that
|
||||
// we can prevent autocompletion later when search results come in
|
||||
if ([[textView string] length] > 1) {
|
||||
[self selectRowAt:-1];
|
||||
mBackspaced = YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,436 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Matt Judy <matt@nibfile.com> (Original Author)
|
||||
* David Haas <haasd@cae.wisc.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
#import "NSPasteboard+Utils.h"
|
||||
|
||||
#import "BrowserTabView.h"
|
||||
#import "BookmarksService.h"
|
||||
#import "BrowserWrapper.h"
|
||||
#import "BrowserWindowController.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
//////////////////////////
|
||||
// NEEDS IMPLEMENTED : Implement drag tracking for moving tabs around.
|
||||
// Implementation hints : Track drags ;)
|
||||
// : Change tab controlTint to indicate drag location?
|
||||
// : Move tab titles around when dragging.
|
||||
//////////////////////////
|
||||
|
||||
@interface BrowserTabView (Private)
|
||||
|
||||
- (void)showOrHideTabsAsAppropriate;
|
||||
- (BOOL)handleDropOnTab:(NSTabViewItem*)overTabViewItem overContent:(BOOL)overContentArea withURL:(NSString*)url;
|
||||
- (BrowserTabViewItem*)getTabViewItemFromWindowPoint:(NSPoint)point;
|
||||
- (void)showDragDestinationIndicator;
|
||||
- (void)hideDragDestinationIndicator;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#define kTabDropTargetHeight 18.0
|
||||
|
||||
@implementation BrowserTabView
|
||||
|
||||
/******************************************/
|
||||
/*** Initialization ***/
|
||||
/******************************************/
|
||||
|
||||
- (id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
if ( (self = [super initWithFrame:frameRect]) ) {
|
||||
autoHides = YES;
|
||||
maxNumberOfTabs = 0; // no max
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[self showOrHideTabsAsAppropriate];
|
||||
[self registerForDraggedTypes:[NSArray arrayWithObjects:
|
||||
@"MozURLType", @"MozBookmarkType", NSStringPboardType, NSFilenamesPboardType, NSURLPboardType, nil]];
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
/*** Overridden Methods ***/
|
||||
/******************************************/
|
||||
|
||||
- (BOOL)isOpaque
|
||||
{
|
||||
// see http://developer.apple.com/qa/qa2001/qa1117.html
|
||||
if ( ([self tabViewType] == NSNoTabsBezelBorder) && (NSAppKitVersionNumber < 633) )
|
||||
return NO;
|
||||
|
||||
return [super isOpaque];
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)aRect
|
||||
{
|
||||
if (mIsDropTarget)
|
||||
{
|
||||
NSRect hilightRect = aRect;
|
||||
hilightRect.size.height = kTabDropTargetHeight; // no need to move origin.y; our coords are flipped
|
||||
NSBezierPath* dropTargetOutline = [NSBezierPath bezierPathWithRect:hilightRect];
|
||||
|
||||
[[[NSColor colorForControlTint:NSDefaultControlTint] colorWithAlphaComponent:0.5] set];
|
||||
[dropTargetOutline fill];
|
||||
}
|
||||
|
||||
[super drawRect:aRect];
|
||||
}
|
||||
|
||||
- (void)addTabViewItem:(NSTabViewItem *)tabViewItem
|
||||
{
|
||||
[super addTabViewItem:tabViewItem];
|
||||
[self showOrHideTabsAsAppropriate];
|
||||
}
|
||||
|
||||
- (void)removeTabViewItem:(NSTabViewItem *)tabViewItem
|
||||
{
|
||||
[super removeTabViewItem:tabViewItem];
|
||||
[self showOrHideTabsAsAppropriate];
|
||||
}
|
||||
|
||||
- (void)insertTabViewItem:(NSTabViewItem *)tabViewItem atIndex:(int)index
|
||||
{
|
||||
[super insertTabViewItem:tabViewItem atIndex:index];
|
||||
[self showOrHideTabsAsAppropriate];
|
||||
}
|
||||
|
||||
- (BrowserTabViewItem*)itemWithTag:(int)tag
|
||||
{
|
||||
NSArray* tabViewItems = [self tabViewItems];
|
||||
|
||||
for (unsigned int i = 0; i < [tabViewItems count]; i ++)
|
||||
{
|
||||
id tabItem = [tabViewItems objectAtIndex:i];
|
||||
if ([tabItem isMemberOfClass:[BrowserTabViewItem class]] &&
|
||||
([(BrowserTabViewItem*)tabItem tag] == tag))
|
||||
{
|
||||
return tabItem;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
/*** Accessor Methods ***/
|
||||
/******************************************/
|
||||
|
||||
- (BOOL)autoHides
|
||||
{
|
||||
return autoHides;
|
||||
}
|
||||
|
||||
- (void)setAutoHides:(BOOL)newSetting
|
||||
{
|
||||
autoHides = newSetting;
|
||||
}
|
||||
|
||||
- (int)maxNumberOfTabs
|
||||
{
|
||||
return maxNumberOfTabs;
|
||||
}
|
||||
|
||||
- (void)setMaxNumberOfTabs:(int)maxTabs
|
||||
{
|
||||
maxNumberOfTabs = maxTabs;
|
||||
}
|
||||
|
||||
- (BOOL)canMakeNewTabs
|
||||
{
|
||||
return maxNumberOfTabs == 0 || [self numberOfTabViewItems] < maxNumberOfTabs;
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
/*** Instance Methods ***/
|
||||
/******************************************/
|
||||
|
||||
// 03-03-2002 mlj: Modifies tab view size and type appropriately... Fragile.
|
||||
// Only to be used with the 2 types of tab view which we use in Chimera.
|
||||
- (void)showOrHideTabsAsAppropriate
|
||||
{
|
||||
//if ( autoHides == YES )
|
||||
{
|
||||
BOOL tabVisibilityChanged = NO;
|
||||
BOOL tabsVisible = NO;
|
||||
|
||||
if ( [[self tabViewItems] count] < 2)
|
||||
{
|
||||
if ( [self tabViewType] != NSNoTabsBezelBorder )
|
||||
{
|
||||
[self setTabViewType:NSNoTabsBezelBorder];
|
||||
tabVisibilityChanged = YES;
|
||||
}
|
||||
tabsVisible = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( [self tabViewType] != NSTopTabsBezelBorder )
|
||||
{
|
||||
[self setTabViewType:NSTopTabsBezelBorder];
|
||||
tabVisibilityChanged = YES;
|
||||
}
|
||||
tabsVisible = YES;
|
||||
}
|
||||
|
||||
// tell the tabs that visibility changed
|
||||
NSArray* tabViewItems = [self tabViewItems];
|
||||
for (unsigned int i = 0; i < [tabViewItems count]; i ++)
|
||||
{
|
||||
NSTabViewItem* tabItem = [tabViewItems objectAtIndex:i];
|
||||
if ([tabItem isMemberOfClass:[BrowserTabViewItem class]])
|
||||
[(BrowserTabViewItem*)tabItem updateTabVisibility:tabsVisible];
|
||||
}
|
||||
|
||||
if (tabVisibilityChanged)
|
||||
{
|
||||
[[[[self window] windowController] bookmarksToolbar] setDrawBottomBorder:!tabsVisible];
|
||||
|
||||
// tell the superview to resize its subviews
|
||||
[[self superview] resizeSubviewsWithOldSize:[[self superview] frame].size];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// return the frame we want to have to make us display correctly in the supplied frame.
|
||||
const float kTabsVisibleTopGap = 4.0; // space above the tabs
|
||||
const float kTabsInvisibleTopGap = -7.0; // space removed to push tab content up when no tabs are visible
|
||||
|
||||
- (float)getExtraTopSpace;
|
||||
{
|
||||
return ([self tabsVisible]) ? kTabsVisibleTopGap : kTabsInvisibleTopGap;
|
||||
}
|
||||
|
||||
- (BOOL)tabsVisible
|
||||
{
|
||||
return ([[self tabViewItems] count] > 1);
|
||||
}
|
||||
|
||||
- (BOOL)handleDropOnTab:(NSTabViewItem*)overTabViewItem overContent:(BOOL)overContentArea withURL:(NSString*)url
|
||||
{
|
||||
if (overTabViewItem)
|
||||
{
|
||||
[[overTabViewItem view] loadURI: url referrer:nil flags: NSLoadFlagsNone activate:NO];
|
||||
return YES;
|
||||
}
|
||||
else if (overContentArea)
|
||||
{
|
||||
[[[self selectedTabViewItem] view] loadURI: url referrer:nil flags: NSLoadFlagsNone activate:NO];
|
||||
return YES;
|
||||
}
|
||||
else if ([self canMakeNewTabs])
|
||||
{
|
||||
[self addTabForURL:url referrer:nil];
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BrowserTabViewItem*)getTabViewItemFromWindowPoint:(NSPoint)point
|
||||
{
|
||||
NSPoint localPoint = [self convertPoint: point fromView: nil];
|
||||
NSTabViewItem* overTabViewItem = [self tabViewItemAtPoint: localPoint];
|
||||
return (BrowserTabViewItem*)overTabViewItem;
|
||||
}
|
||||
|
||||
- (void)showDragDestinationIndicator
|
||||
{
|
||||
if (!mIsDropTarget)
|
||||
{
|
||||
NSRect invalidRect = [self bounds];
|
||||
invalidRect.size.height = kTabDropTargetHeight;
|
||||
[self setNeedsDisplayInRect:invalidRect];
|
||||
mIsDropTarget = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)hideDragDestinationIndicator
|
||||
{
|
||||
if (mIsDropTarget)
|
||||
{
|
||||
NSRect invalidRect = [self bounds];
|
||||
invalidRect.size.height = kTabDropTargetHeight;
|
||||
[self setNeedsDisplayInRect:invalidRect];
|
||||
mIsDropTarget = NO;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// NSDraggingDestination ///////////
|
||||
|
||||
- (unsigned int)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPoint localPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
|
||||
NSTabViewItem* overTabViewItem = [self tabViewItemAtPoint: localPoint];
|
||||
BOOL overContentArea = NSPointInRect(localPoint, [self contentRect]);
|
||||
|
||||
if (overTabViewItem)
|
||||
return NSDragOperationNone; // the tab will handle it
|
||||
|
||||
if (!overContentArea && ![self canMakeNewTabs])
|
||||
return NSDragOperationNone;
|
||||
|
||||
[self showDragDestinationIndicator]; // XXX optimize
|
||||
return NSDragOperationGeneric;
|
||||
}
|
||||
|
||||
- (unsigned int)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPoint localPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
|
||||
NSTabViewItem* overTabViewItem = [self tabViewItemAtPoint: localPoint];
|
||||
BOOL overContentArea = NSPointInRect(localPoint, [self contentRect]);
|
||||
|
||||
if (overTabViewItem)
|
||||
return NSDragOperationNone; // the tab will handle it
|
||||
|
||||
if (!overContentArea && ![self canMakeNewTabs])
|
||||
{
|
||||
[self hideDragDestinationIndicator];
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
[self showDragDestinationIndicator];
|
||||
return NSDragOperationGeneric;
|
||||
}
|
||||
|
||||
- (void)draggingExited:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
[self hideDragDestinationIndicator];
|
||||
}
|
||||
|
||||
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
// determine if we are over a tab or the content area
|
||||
NSPoint localPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
|
||||
NSTabViewItem* overTabViewItem = [self tabViewItemAtPoint: localPoint];
|
||||
BOOL overContentArea = NSPointInRect(localPoint, [self contentRect]);
|
||||
NSArray* pasteBoardTypes = [[sender draggingPasteboard] types];
|
||||
|
||||
[self hideDragDestinationIndicator];
|
||||
|
||||
if ([pasteBoardTypes containsObject: @"MozBookmarkType"])
|
||||
{
|
||||
NSArray* contentIds = [[sender draggingPasteboard] propertyListForType: @"MozBookmarkType"];
|
||||
if (contentIds)
|
||||
{
|
||||
BookmarksManager* bmManager = [BookmarksManager sharedBookmarksManager];
|
||||
|
||||
// drag type is chimera bookmarks
|
||||
for (unsigned int i = 0; i < [contentIds count]; ++i)
|
||||
{
|
||||
BookmarkItem* item = [bmManager getWrapperForNumber:[contentIds objectAtIndex:i]];
|
||||
if ([item isGroup])
|
||||
{
|
||||
NSArray* groupURLs = [bmManager getBookmarkGroupURIs:item];
|
||||
[[[self window] windowController] openTabGroup:groupURLs replaceExistingTabs:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle multiple items?
|
||||
return [self handleDropOnTab:overTabViewItem overContent:overContentArea withURL:[item url]];
|
||||
}
|
||||
|
||||
} // for each item
|
||||
}
|
||||
}
|
||||
else if ([pasteBoardTypes containsObject: @"MozURLType"])
|
||||
{
|
||||
// drag type is MozURLType
|
||||
NSDictionary* data = [[sender draggingPasteboard] propertyListForType: @"MozURLType"];
|
||||
if (data) {
|
||||
NSString* urlString = [data objectForKey:@"url"];
|
||||
return [self handleDropOnTab:overTabViewItem overContent:overContentArea withURL:urlString];
|
||||
}
|
||||
}
|
||||
else if ([pasteBoardTypes containsObject: NSStringPboardType])
|
||||
{
|
||||
NSString* urlString = [[sender draggingPasteboard] stringForType: NSStringPboardType];
|
||||
return [self handleDropOnTab:overTabViewItem overContent:overContentArea withURL:urlString];
|
||||
}
|
||||
else if ([pasteBoardTypes containsObject: NSURLPboardType])
|
||||
{
|
||||
NSURL* urlData = [NSURL URLFromPasteboard:[sender draggingPasteboard]];
|
||||
return [self handleDropOnTab:overTabViewItem overContent:overContentArea withURL:[urlData absoluteString]];
|
||||
}
|
||||
else if ([pasteBoardTypes containsObject: NSFilenamesPboardType])
|
||||
{
|
||||
NSString* urlString = [[sender draggingPasteboard] stringForType: NSFilenamesPboardType];
|
||||
return [self handleDropOnTab:overTabViewItem overContent:overContentArea withURL:urlString];
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
-(void)addTabForURL:(NSString*)aURL referrer:(NSString*)aReferrer
|
||||
{
|
||||
[[[self window] windowController] openNewTabWithURL:aURL referrer:aReferrer loadInBackground:YES];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (BrowserTabViewItem*)makeNewTabItem
|
||||
{
|
||||
return [[[BrowserTabViewItem alloc] init] autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "BrowserWrapper.h"
|
||||
#import "Find.h"
|
||||
#import "BookmarksToolbar.h"
|
||||
|
||||
#include "nsIBrowserHistory.h"
|
||||
|
||||
class nsIURIFixup;
|
||||
class nsIBrowserHistory;
|
||||
class nsIDOMEvent;
|
||||
class nsIDOMNode;
|
||||
|
||||
|
||||
//
|
||||
// ThrobberHandler
|
||||
//
|
||||
// A helper class that handles animating the throbber when it's alive. It starts
|
||||
// automatically when you init it. To get it to stop, call |stopThrobber|. Calling
|
||||
// |release| is not enough because the timer used to animate the images holds a strong
|
||||
// ref back to the handler so it won't go away unless you break that cycle manually with
|
||||
// |stopThrobber|.
|
||||
//
|
||||
// This class must be separate from BrowserWindowController else the
|
||||
// same thing will happen there and the timer will cause it to stay alive and continue
|
||||
// loading the webpage even though the window has gone away.
|
||||
//
|
||||
@interface ThrobberHandler : NSObject
|
||||
{
|
||||
NSTimer* mTimer;
|
||||
NSArray* mImages;
|
||||
unsigned int mFrame;
|
||||
}
|
||||
|
||||
// public
|
||||
- (id)initWithToolbarItem:(NSToolbarItem*)inButton images:(NSArray*)inImages;
|
||||
- (void)stopThrobber;
|
||||
|
||||
// internal
|
||||
- (void)startThrobber;
|
||||
- (void)pulseThrobber:(id)aSender;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eNewTabEmpty,
|
||||
eNewTabAboutBlank,
|
||||
eNewTabHomepage
|
||||
|
||||
} ENewTabContents;
|
||||
|
||||
@class BookmarksDataSource;
|
||||
@class HistoryDataSource;
|
||||
@class BrowserTabView;
|
||||
@class PageProxyIcon;
|
||||
@class BrowserContentView;
|
||||
@class BrowserTabViewItem;
|
||||
|
||||
@interface BrowserWindowController : NSWindowController<Find>
|
||||
{
|
||||
IBOutlet BrowserTabView* mTabBrowser;
|
||||
IBOutlet NSDrawer* mSidebarDrawer;
|
||||
IBOutlet NSTabView* mSidebarTabView;
|
||||
IBOutlet NSTabView* mSidebarSourceTabView;
|
||||
IBOutlet NSView* mLocationToolbarView;
|
||||
IBOutlet NSTextField* mURLBar;
|
||||
IBOutlet NSTextField* mStatus;
|
||||
IBOutlet NSProgressIndicator* mProgress; // STRONG reference
|
||||
IBOutlet NSImageView* mLock;
|
||||
IBOutlet NSWindow* mLocationSheetWindow;
|
||||
IBOutlet NSTextField* mLocationSheetURLField;
|
||||
IBOutlet NSView* mStatusBar; // contains the status text, progress bar, and lock
|
||||
IBOutlet PageProxyIcon* mProxyIcon;
|
||||
IBOutlet BrowserContentView* mContentView;
|
||||
|
||||
IBOutlet BookmarksDataSource* mSidebarBookmarksDataSource;
|
||||
IBOutlet HistoryDataSource* mHistoryDataSource;
|
||||
|
||||
IBOutlet BookmarksToolbar* mPersonalToolbar;
|
||||
|
||||
IBOutlet NSWindow* mAddBookmarkSheetWindow;
|
||||
IBOutlet NSTextField* mAddBookmarkTitleField;
|
||||
IBOutlet NSPopUpButton* mAddBookmarkFolderField;
|
||||
IBOutlet NSButton* mAddBookmarkCheckbox;
|
||||
|
||||
// Context menu outlets.
|
||||
IBOutlet NSMenu* mPageMenu;
|
||||
IBOutlet NSMenu* mImageMenu;
|
||||
IBOutlet NSMenu* mInputMenu;
|
||||
IBOutlet NSMenu* mLinkMenu;
|
||||
IBOutlet NSMenu* mImageLinkMenu;
|
||||
IBOutlet NSMenu* mTabMenu;
|
||||
|
||||
// Context menu item outlets
|
||||
IBOutlet NSMenuItem* mBackItem;
|
||||
IBOutlet NSMenuItem* mForwardItem;
|
||||
IBOutlet NSMenuItem* mCopyItem;
|
||||
|
||||
NSToolbarItem* mSidebarToolbarItem;
|
||||
NSToolbarItem* mBookmarkToolbarItem;
|
||||
|
||||
BOOL mInitialized;
|
||||
NSString* mPendingURL;
|
||||
NSString* mPendingReferrer;
|
||||
BOOL mPendingActivate;
|
||||
|
||||
BrowserWrapper* mBrowserView;
|
||||
|
||||
BOOL mMoveReentrant;
|
||||
BOOL mClosingWindow;
|
||||
|
||||
BOOL mShouldAutosave;
|
||||
BOOL mShouldLoadHomePage;
|
||||
|
||||
BOOL mDrawerCachedFrame;
|
||||
NSRect mCachedFrameBeforeDrawerOpen; // This is used by the drawer to figure out if the window should
|
||||
// be returned to its original position when the drawer closes.
|
||||
NSRect mCachedFrameAfterDrawerOpen;
|
||||
|
||||
unsigned int mChromeMask; // Indicates which parts of the window to show (e.g., don't show toolbars)
|
||||
|
||||
// Context menu members.
|
||||
int mContextMenuFlags;
|
||||
nsIDOMEvent* mContextMenuEvent;
|
||||
nsIDOMNode* mContextMenuNode;
|
||||
|
||||
// Cached bookmark ds used when adding through a sheet
|
||||
BookmarksDataSource* mCachedBMDS;
|
||||
|
||||
// Throbber state variables.
|
||||
ThrobberHandler* mThrobberHandler;
|
||||
NSArray* mThrobberImages;
|
||||
|
||||
// Funky field editor for URL bar
|
||||
NSTextView *mURLFieldEditor;
|
||||
|
||||
// cached superview for progress meter so we know where to add/remove it. This
|
||||
// could be an outlet, but i figure it's easier to get it at runtime thereby saving
|
||||
// someone from messing up in the nib when making changes.
|
||||
NSView* mProgressSuperview; // WEAK ptr
|
||||
|
||||
nsIURIFixup* mURIFixer; // [STRONG] should be nsCOMPtr, but can't
|
||||
nsIBrowserHistory* mGlobalHistory; // [STRONG] should be nsCOMPtr, but can't
|
||||
}
|
||||
|
||||
- (void)dealloc;
|
||||
|
||||
- (id)getTabBrowser;
|
||||
- (BOOL)newTabsAllowed;
|
||||
- (BrowserWrapper*)getBrowserWrapper;
|
||||
|
||||
- (void)loadURL:(NSString*)aURLSpec referrer:(NSString*)aReferrer activate:(BOOL)activate;
|
||||
- (void)updateLocationFields:(NSString *)locationString;
|
||||
- (void)updateSiteIcons:(NSImage *)siteIconImage;
|
||||
- (void)updateToolbarItems;
|
||||
- (void)loadingStarted;
|
||||
- (void)loadingDone;
|
||||
- (void)focusURLBar;
|
||||
|
||||
// call to update the image of the lock icon with a value from nsIWebProgressListener
|
||||
- (void)updateLock:(unsigned int)securityState;
|
||||
|
||||
- (void)performAppropriateLocationAction;
|
||||
- (IBAction)goToLocationFromToolbarURLField:(id)sender;
|
||||
- (void)beginLocationSheet;
|
||||
- (IBAction)endLocationSheet:(id)sender;
|
||||
- (IBAction)cancelLocationSheet:(id)sender;
|
||||
|
||||
- (IBAction)cancelAddBookmarkSheet:(id)sender;
|
||||
- (IBAction)endAddBookmarkSheet:(id)sender;
|
||||
- (void)cacheBookmarkDS:(BookmarksDataSource*)aDS;
|
||||
|
||||
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize;
|
||||
|
||||
- (IBAction)viewSource:(id)aSender; // focussed frame or page
|
||||
- (IBAction)viewPageSource:(id)aSender; // top-level page
|
||||
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView;
|
||||
- (void)saveURL:(NSView*)aFilterView url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename;
|
||||
|
||||
- (IBAction)printDocument:(id)aSender;
|
||||
- (IBAction)pageSetup:(id)aSender;
|
||||
- (IBAction)performSearch:(id)aSender;
|
||||
- (IBAction)sendURL:(id)aSender;
|
||||
|
||||
- (void)startThrobber;
|
||||
- (void)stopThrobber;
|
||||
- (void)clickThrobber:(id)aSender;
|
||||
|
||||
- (IBAction)biggerTextSize:(id)aSender;
|
||||
- (IBAction)smallerTextSize:(id)aSender;
|
||||
|
||||
- (void)getInfo:(id)sender;
|
||||
- (BOOL)canGetInfo;
|
||||
|
||||
- (BOOL)shouldShowBookmarkToolbar;
|
||||
|
||||
- (void)addBookmarkExtended: (BOOL)aIsFromMenu isFolder:(BOOL)aIsFolder URL:(NSString*)aURL title:(NSString*)aTitle;
|
||||
- (IBAction)manageBookmarks: (id)aSender;
|
||||
- (IBAction)manageHistory: (id)aSender;
|
||||
- (void)importBookmarks: (NSString*)aURLSpec;
|
||||
- (IBAction)toggleSidebar:(id)aSender;
|
||||
- (BOOL)bookmarksAreVisible:(BOOL)inRequireSelection;
|
||||
|
||||
- (void)createNewTab:(ENewTabContents)contents;
|
||||
|
||||
- (IBAction)newTab:(id)sender;
|
||||
- (IBAction)closeCurrentTab:(id)sender;
|
||||
- (IBAction)previousTab:(id)sender;
|
||||
- (IBAction)nextTab:(id)sender;
|
||||
|
||||
- (IBAction)closeSendersTab:(id)sender;
|
||||
- (IBAction)closeOtherTabs:(id)sender;
|
||||
- (IBAction)reloadSendersTab:(id)sender;
|
||||
- (IBAction)moveTabToNewWindow:(id)sender;
|
||||
|
||||
- (IBAction)back:(id)aSender;
|
||||
- (IBAction)forward:(id)aSender;
|
||||
- (IBAction)reload:(id)aSender;
|
||||
- (IBAction)stop:(id)aSender;
|
||||
- (IBAction)home:(id)aSender;
|
||||
|
||||
- (IBAction)frameToNewWindow:(id)sender;
|
||||
- (IBAction)frameToNewTab:(id)sender;
|
||||
- (IBAction)frameToThisWindow:(id)sender;
|
||||
|
||||
- (void)openNewWindowWithURL: (NSString*)aURLSpec referrer:(NSString*)aReferrer loadInBackground: (BOOL)aLoadInBG;
|
||||
- (void)openNewWindowWithGroup: (nsIContent*)aFolderContent loadInBackground: (BOOL)aLoadInBG;
|
||||
- (void)openNewTabWithURL: (NSString*)aURLSpec referrer: (NSString*)aReferrer loadInBackground: (BOOL)aLoadInBG;
|
||||
|
||||
- (void)openTabGroup:(NSArray*)urlArray replaceExistingTabs:(BOOL)replaceExisting;
|
||||
|
||||
-(BrowserTabViewItem*)createNewTabItem;
|
||||
|
||||
- (void)closeBrowserWindow:(BrowserWrapper*)inBrowser;
|
||||
|
||||
-(void)autosaveWindowFrame;
|
||||
-(void)disableAutosave;
|
||||
-(void)disableLoadPage;
|
||||
|
||||
-(void)setChromeMask:(unsigned int)aMask;
|
||||
-(unsigned int)chromeMask;
|
||||
|
||||
-(id)getAddBookmarkSheetWindow;
|
||||
-(id)getAddBookmarkTitle;
|
||||
-(id)getAddBookmarkFolder;
|
||||
-(id)getAddBookmarkCheckbox;
|
||||
|
||||
// Called when a context menu should be shown.
|
||||
- (void)onShowContextMenu:(int)flags domEvent:(nsIDOMEvent*)aEvent domNode:(nsIDOMNode*)aNode;
|
||||
- (NSMenu*)getContextMenu;
|
||||
|
||||
// Context menu methods
|
||||
- (IBAction)openLinkInNewWindow:(id)aSender;
|
||||
- (IBAction)openLinkInNewTab:(id)aSender;
|
||||
- (void)openLinkInNewWindowOrTab: (BOOL)aUseWindow;
|
||||
|
||||
- (IBAction)savePageAs:(id)aSender;
|
||||
- (IBAction)saveFrameAs:(id)aSender;
|
||||
- (IBAction)saveLinkAs:(id)aSender;
|
||||
- (IBAction)saveImageAs:(id)aSender;
|
||||
|
||||
- (IBAction)viewOnlyThisImage:(id)aSender;
|
||||
|
||||
- (IBAction)bookmarkPage: (id)aSender;
|
||||
- (IBAction)bookmarkLink: (id)aSender;
|
||||
|
||||
- (IBAction)copyLinkLocation:(id)aSender;
|
||||
- (IBAction)copyImage:(id)sender;
|
||||
- (IBAction)copyImageLocation:(id)sender;
|
||||
|
||||
- (BookmarksToolbar*) bookmarksToolbar;
|
||||
|
||||
- (NSProgressIndicator*) progressIndicator;
|
||||
- (void) showProgressIndicator;
|
||||
- (void) hideProgressIndicator;
|
||||
|
||||
- (BOOL) isResponderGeckoView:(NSResponder*) responder;
|
||||
|
||||
// called when the internal window focus has changed
|
||||
// this allows us to dispatch activate and deactivate events as necessary
|
||||
- (void) focusChangedFrom:(NSResponder*) oldResponder to:(NSResponder*) newResponder;
|
||||
|
||||
// Called to get cached versions of our security icons
|
||||
+ (NSImage*) insecureIcon;
|
||||
+ (NSImage*) secureIcon;
|
||||
+ (NSImage*) brokenIcon;
|
||||
|
||||
// cache the toolbar defaults we parse from a plist
|
||||
+ (NSArray*) toolbarDefaults;
|
||||
|
||||
// Accessor to get the sidebar drawer
|
||||
- (NSDrawer *)sidebarDrawer;
|
||||
|
||||
// Accessor to get the proxy icon view
|
||||
- (PageProxyIcon *)proxyIconView;
|
||||
|
||||
// Accessor for the bm data source
|
||||
- (BookmarksDataSource*)bookmarksDataSource;
|
||||
|
||||
@end
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,124 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "CHBrowserView.h"
|
||||
|
||||
@class BrowserWindowController;
|
||||
@class ToolTip;
|
||||
|
||||
@interface BrowserWrapper : NSView <CHBrowserListener, CHBrowserContainer>
|
||||
{
|
||||
NSTextField* mUrlbar;
|
||||
NSTextField* mStatus;
|
||||
BrowserWindowController* mWindowController;
|
||||
NSTabViewItem* mTabItem;
|
||||
NSWindow* mWindow;
|
||||
|
||||
NSImage* mSiteIconImage; // current proxy icon image, which may be a site icon (favicon).
|
||||
NSString* mSiteIconURI; // uri from which we loaded the site icon
|
||||
|
||||
// the secure state of this browser. We need to hold it so that we can set
|
||||
// the global lock icon whenever we become the primary. Value is one of
|
||||
// security enums in nsIWebProgressListener.
|
||||
unsigned long mSecureState;
|
||||
// the title associated with this tab's url. We need to hold it so that we
|
||||
// can set the window title whenever we become the primary.
|
||||
NSString* mTitle;
|
||||
// the title we use for the tab. This differs for mTitle when the tab is loading
|
||||
NSString* mTabTitle;
|
||||
|
||||
CHBrowserView* mBrowserView;
|
||||
NSString* mDefaultStatusString;
|
||||
NSString* mLoadingStatusString;
|
||||
ToolTip* mToolTip;
|
||||
|
||||
double mProgress;
|
||||
|
||||
BOOL mIsPrimary;
|
||||
BOOL mIsBusy;
|
||||
BOOL mOffline;
|
||||
BOOL mListenersAttached; // We hook up our click and context menu listeners lazily.
|
||||
// If we never become the primary view, we don't bother creating the listeners.
|
||||
BOOL mIsBookmarksImport; // This view was created for the purpose of importing bookmarks. Upon
|
||||
// completion, we need to do the import and then destroy ourselves.
|
||||
BOOL mActivateOnLoad; // If set, activate the browser view when loading starts.
|
||||
}
|
||||
|
||||
- (id)initWithTab:(NSTabViewItem*)aTab andWindow:(NSWindow*)aWindow;
|
||||
|
||||
- (IBAction)load:(id)sender;
|
||||
- (void)awakeFromNib;
|
||||
- (void)setFrame:(NSRect)frameRect;
|
||||
- (CHBrowserView*)getBrowserView;
|
||||
- (BOOL)isBusy;
|
||||
- (BOOL)isEmpty; // is about:blank loaded?
|
||||
- (void)windowClosed;
|
||||
|
||||
- (NSString*)getCurrentURLSpec;
|
||||
|
||||
- (void)loadURI:(NSString *)urlSpec referrer:(NSString*)referrer flags:(unsigned int)flags activate:(BOOL)activate;
|
||||
- (void)makePrimaryBrowserView: (id)aUrlbar status: (id)aStatus
|
||||
windowController: (BrowserWindowController*)aWindowController;
|
||||
- (void)disconnectView;
|
||||
- (void)setTab: (NSTabViewItem*)tab;
|
||||
- (NSTabViewItem*) tab;
|
||||
|
||||
- (NSWindow*)getNativeWindow;
|
||||
- (NSMenu*)getContextMenu;
|
||||
- (void)setIsBookmarksImport:(BOOL)aIsImport;
|
||||
|
||||
- (void)getTitle:(NSString **)outTitle andHref:(NSString**)outHrefString;
|
||||
|
||||
// CHBrowserListener messages
|
||||
- (void)onLoadingStarted;
|
||||
- (void)onLoadingCompleted:(BOOL)succeeded;
|
||||
- (void)onProgressChange:(int)currentBytes outOf:(int)maxBytes;
|
||||
- (void)onLocationChange:(NSString*)urlSpec;
|
||||
- (void)onStatusChange:(NSString*)aMessage;
|
||||
- (void)onSecurityStateChange:(unsigned long)newState;
|
||||
- (void)onShowTooltip:(NSPoint)where withText:(NSString*)text;
|
||||
- (void)onHideTooltip;
|
||||
|
||||
// CHBrowserContainer messages
|
||||
- (void)setStatus:(NSString *)statusString ofType:(NSStatusType)type;
|
||||
- (NSString *)title;
|
||||
- (void)setTitle:(NSString *)title;
|
||||
- (void)sizeBrowserTo:(NSSize)dimensions;
|
||||
- (CHBrowserView*)createBrowserWindow:(unsigned int)mask;
|
||||
|
||||
@end
|
|
@ -1,851 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
#import "PreferenceManager.h"
|
||||
#import "BrowserWrapper.h"
|
||||
#import "BrowserWindowController.h"
|
||||
#import "BookmarksService.h"
|
||||
#import "SiteIconProvider.h"
|
||||
#import "BrowserTabViewItem.h"
|
||||
#import "ToolTip.h"
|
||||
#import "PageProxyIcon.h"
|
||||
#import "KeychainService.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "ContentClickListener.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIWebBrowser.h"
|
||||
#include "nsIWebBrowserSetup.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIChromeEventHandler.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "CHBrowserService.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
|
||||
#include <QuickDraw.h>
|
||||
|
||||
static const char* ioServiceContractID = "@mozilla.org/network/io-service;1";
|
||||
|
||||
const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
||||
|
||||
@interface BrowserWrapper(Private)
|
||||
|
||||
- (void)setPendingActive:(BOOL)active;
|
||||
- (void)registerNotificationListener;
|
||||
|
||||
- (void)setSiteIconImage:(NSImage*)inSiteIcon;
|
||||
- (void)setSiteIconURI:(NSString*)inSiteIconURI;
|
||||
|
||||
- (void)updateSiteIconImage:(NSImage*)inSiteIcon withURI:(NSString *)inSiteIconURI;
|
||||
|
||||
- (void)setTabTitle:(NSString*)tabTitle windowTitle:(NSString*)windowTitle;
|
||||
|
||||
@end
|
||||
|
||||
@implementation BrowserWrapper
|
||||
|
||||
- (id)initWithTab:(NSTabViewItem*)aTab andWindow:(NSWindow*)aWindow
|
||||
{
|
||||
mTabItem = aTab;
|
||||
mWindow = aWindow;
|
||||
mIsBookmarksImport = NO;
|
||||
return [self initWithFrame: NSZeroRect];
|
||||
}
|
||||
|
||||
//
|
||||
// initWithFrame: (designated initializer)
|
||||
//
|
||||
// Create a Gecko browser view and hook everything up to the UI
|
||||
//
|
||||
- (id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
if ( (self = [super initWithFrame: frameRect]) ) {
|
||||
mBrowserView = [[[CHBrowserView alloc] initWithFrame:[self bounds] andWindow: [self getNativeWindow]] autorelease];
|
||||
[self addSubview: mBrowserView];
|
||||
[mBrowserView setContainer:self];
|
||||
[mBrowserView addListener:self];
|
||||
[[KeychainService instance] addListenerToView:mBrowserView];
|
||||
mIsBusy = NO;
|
||||
mListenersAttached = NO;
|
||||
mSecureState = nsIWebProgressListener::STATE_IS_INSECURE;
|
||||
mProgress = 0.0;
|
||||
|
||||
BOOL gotPref;
|
||||
BOOL pluginsEnabled = [[PreferenceManager sharedInstance] getBooleanPref:"chimera.enable_plugins" withSuccess:&gotPref];
|
||||
if (gotPref && !pluginsEnabled)
|
||||
[mBrowserView setProperty:nsIWebBrowserSetup::SETUP_ALLOW_PLUGINS toValue:PR_FALSE];
|
||||
|
||||
mToolTip = [[ToolTip alloc] init];
|
||||
|
||||
//[self setSiteIconImage:[NSImage imageNamed:@"globe_ico"]];
|
||||
//[self setSiteIconURI: [NSString string]];
|
||||
|
||||
mDefaultStatusString = nil;
|
||||
mLoadingStatusString = nil;
|
||||
|
||||
[self registerNotificationListener];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
#if DEBUG
|
||||
NSLog(@"The browser wrapper died.");
|
||||
#endif
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
|
||||
[mSiteIconImage release];
|
||||
[mSiteIconURI release];
|
||||
[mDefaultStatusString release];
|
||||
[mLoadingStatusString release];
|
||||
|
||||
[mToolTip release];
|
||||
[mTitle release];
|
||||
[mTabTitle release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
-(void)windowClosed
|
||||
{
|
||||
// Break the cycle, but don't clear ourselves as the container
|
||||
// before we call |destroyWebBrowser| or onUnload handlers won't be
|
||||
// able to create new windows. The container will get cleared
|
||||
// when the CHBrowserListener goes away as a result of the
|
||||
// |destroyWebBrowser| call. (bug 174416)
|
||||
[mBrowserView removeListener: self];
|
||||
[mBrowserView destroyWebBrowser];
|
||||
|
||||
// We don't want site icon notifications when the window has gone away
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:SiteIconLoadNotificationName object:nil];
|
||||
// We're basically a zombie now. Clear fields which are in an undefined state.
|
||||
mIsPrimary = NO;
|
||||
mWindowController = nil;
|
||||
}
|
||||
|
||||
- (IBAction)load:(id)sender
|
||||
{
|
||||
[mBrowserView loadURI:[mUrlbar stringValue] referrer:nil flags:NSLoadFlagsNone];
|
||||
}
|
||||
|
||||
-(void)disconnectView
|
||||
{
|
||||
mUrlbar = nil;
|
||||
mStatus = nil;
|
||||
mIsPrimary = NO;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kOfflineNotificationName object:nil];
|
||||
|
||||
[mBrowserView setActive: NO];
|
||||
}
|
||||
|
||||
-(void)setTab: (NSTabViewItem*)tab
|
||||
{
|
||||
mTabItem = tab;
|
||||
}
|
||||
|
||||
-(NSTabViewItem*)tab
|
||||
{
|
||||
return mTabItem;
|
||||
}
|
||||
|
||||
-(void)makePrimaryBrowserView: (id)aUrlbar status: (id)aStatus
|
||||
windowController: (BrowserWindowController*)aWindowController
|
||||
{
|
||||
mUrlbar = aUrlbar;
|
||||
mStatus = aStatus;
|
||||
mWindowController = aWindowController;
|
||||
|
||||
if (mIsBusy)
|
||||
{
|
||||
[mWindowController startThrobber];
|
||||
[mWindowController showProgressIndicator];
|
||||
|
||||
if (mProgress > 0.0)
|
||||
{
|
||||
[[mWindowController progressIndicator] setIndeterminate:NO];
|
||||
[[mWindowController progressIndicator] setDoubleValue:mProgress];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[mWindowController progressIndicator] setIndeterminate:YES];
|
||||
[[mWindowController progressIndicator] startAnimation:self];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[mWindowController stopThrobber];
|
||||
[mWindowController hideProgressIndicator];
|
||||
|
||||
[mDefaultStatusString autorelease];
|
||||
mDefaultStatusString = nil;
|
||||
[mLoadingStatusString autorelease];
|
||||
mLoadingStatusString = [NSLocalizedString(@"DocumentDone", @"") retain];
|
||||
}
|
||||
|
||||
[mStatus setStringValue:mLoadingStatusString];
|
||||
|
||||
mIsPrimary = YES;
|
||||
|
||||
// update the global lock icon to the current state of this browser. We need
|
||||
// to do this after we set |mIsPrimary|.
|
||||
[self onSecurityStateChange:mSecureState];
|
||||
|
||||
// update the window's title.
|
||||
[self setTabTitle:mTabTitle windowTitle:mTitle];
|
||||
|
||||
if ([[self window] isKeyWindow])
|
||||
[mBrowserView setActive: YES];
|
||||
|
||||
nsCOMPtr<nsIIOService> ioService(do_GetService(ioServiceContractID));
|
||||
if (!ioService)
|
||||
return;
|
||||
PRBool offline = PR_FALSE;
|
||||
ioService->GetOffline(&offline);
|
||||
mOffline = offline;
|
||||
|
||||
if (mWindowController) // Only register if we're the content area.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(offlineModeChanged:)
|
||||
name:kOfflineNotificationName
|
||||
object:nil];
|
||||
|
||||
// Update the URL bar.
|
||||
[mWindowController updateLocationFields:[self getCurrentURLSpec]];
|
||||
[mWindowController updateSiteIcons:mSiteIconImage];
|
||||
|
||||
if (mWindowController && !mListenersAttached)
|
||||
{
|
||||
mListenersAttached = YES;
|
||||
|
||||
// We need to hook up our click and context menu listeners.
|
||||
ContentClickListener* clickListener = new ContentClickListener(mWindowController);
|
||||
if (!clickListener)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> contentWindow = getter_AddRefs([[self getBrowserView] getContentWindow]);
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(contentWindow));
|
||||
nsCOMPtr<nsIChromeEventHandler> chromeHandler;
|
||||
piWindow->GetChromeEventHandler(getter_AddRefs(chromeHandler));
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(chromeHandler));
|
||||
if ( rec )
|
||||
rec->AddEventListenerByIID(clickListener, NS_GET_IID(nsIDOMMouseListener));
|
||||
}
|
||||
}
|
||||
|
||||
-(NSString*)getCurrentURLSpec
|
||||
{
|
||||
return [mBrowserView getCurrentURLSpec];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setFrame:(NSRect)frameRect
|
||||
{
|
||||
[super setFrame:frameRect];
|
||||
|
||||
// Only resize our browser view if we are visible. If we're hidden, the frame
|
||||
// will get reset when we get placed back into the view hierarchy anyway. This
|
||||
// enhancement keeps resizing in a window with many tabs from being slow.
|
||||
if ([self window]) {
|
||||
NSRect bounds = [self bounds];
|
||||
[mBrowserView setFrame:bounds];
|
||||
}
|
||||
}
|
||||
|
||||
-(BOOL)isBusy
|
||||
{
|
||||
return mIsBusy;
|
||||
}
|
||||
|
||||
- (void)loadURI:(NSString *)urlSpec referrer:(NSString*)referrer flags:(unsigned int)flags activate:(BOOL)activate
|
||||
{
|
||||
mActivateOnLoad = activate;
|
||||
[mBrowserView loadURI:urlSpec referrer:referrer flags:flags];
|
||||
}
|
||||
|
||||
- (void)onLoadingStarted
|
||||
{
|
||||
if (mDefaultStatusString) {
|
||||
[mDefaultStatusString autorelease];
|
||||
mDefaultStatusString = nil;
|
||||
}
|
||||
|
||||
[mWindowController showProgressIndicator];
|
||||
[[mWindowController progressIndicator] setIndeterminate:YES];
|
||||
[[mWindowController progressIndicator] startAnimation:self];
|
||||
|
||||
[mLoadingStatusString autorelease];
|
||||
mLoadingStatusString = [NSLocalizedString(@"TabLoading", @"") retain];
|
||||
[mStatus setStringValue:mLoadingStatusString];
|
||||
|
||||
mProgress = 0.0;
|
||||
mIsBusy = YES;
|
||||
|
||||
[mTabTitle autorelease];
|
||||
mTabTitle = [mLoadingStatusString retain];
|
||||
[mTabItem setLabel:mTabTitle];
|
||||
|
||||
if (mWindowController)
|
||||
[mWindowController loadingStarted];
|
||||
}
|
||||
|
||||
- (void)onLoadingCompleted:(BOOL)succeeded
|
||||
{
|
||||
if (mActivateOnLoad) {
|
||||
// if we're the front/key window, focus the content area. If we're not,
|
||||
// tell the focus controller that the content area should be focused when
|
||||
// we do finally become the key window
|
||||
if ( [NSApp keyWindow] == [mBrowserView window] )
|
||||
[mBrowserView setActive:YES];
|
||||
else {
|
||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||
nsCOMPtr<nsIWebBrowser> webBrowser = getter_AddRefs([mBrowserView getWebBrowser]);
|
||||
if ( webBrowser ) {
|
||||
webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
|
||||
if ( domWindow ) {
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow ( do_QueryInterface(domWindow) );
|
||||
nsCOMPtr<nsIFocusController> controller;
|
||||
piWindow->GetRootFocusController(getter_AddRefs(controller));
|
||||
if ( controller ) {
|
||||
nsCOMPtr<nsIDOMWindowInternal> windowInt ( do_QueryInterface(domWindow) );
|
||||
controller->SetFocusedWindow(windowInt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mActivateOnLoad = NO;
|
||||
}
|
||||
|
||||
[[mWindowController progressIndicator] setIndeterminate:YES];
|
||||
[[mWindowController progressIndicator] stopAnimation:self];
|
||||
[mWindowController hideProgressIndicator];
|
||||
|
||||
[mLoadingStatusString autorelease];
|
||||
mLoadingStatusString = [NSLocalizedString(@"DocumentDone", @"") retain];
|
||||
if (mDefaultStatusString) {
|
||||
[mStatus setStringValue:mDefaultStatusString];
|
||||
}
|
||||
else {
|
||||
[mStatus setStringValue:mLoadingStatusString];
|
||||
}
|
||||
|
||||
mProgress = 1.0;
|
||||
mIsBusy = NO;
|
||||
|
||||
// need to check succeeded here because for a charset-induced reload,
|
||||
// this can get called initially with a failure code.
|
||||
if (mIsBookmarksImport && succeeded)
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||
nsCOMPtr<nsIWebBrowser> webBrowser = getter_AddRefs([mBrowserView getWebBrowser]);
|
||||
webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
|
||||
if (domWindow)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
domWindow->GetDocument(getter_AddRefs(domDocument));
|
||||
if (domDocument)
|
||||
BookmarksService::ImportBookmarks(domDocument);
|
||||
}
|
||||
[self windowClosed];
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
if (mWindowController)
|
||||
[mWindowController loadingDone];
|
||||
}
|
||||
|
||||
- (void)onProgressChange:(int)currentBytes outOf:(int)maxBytes
|
||||
{
|
||||
if (maxBytes > 0)
|
||||
{
|
||||
mProgress = ((double)currentBytes / (double)maxBytes) * 100.0;
|
||||
if (mIsPrimary)
|
||||
{
|
||||
BOOL isIndeterminate = [[mWindowController progressIndicator] isIndeterminate];
|
||||
if (isIndeterminate)
|
||||
[[mWindowController progressIndicator] setIndeterminate:NO];
|
||||
[[mWindowController progressIndicator] setDoubleValue:mProgress];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onLocationChange:(NSString*)urlSpec
|
||||
{
|
||||
BOOL useSiteIcons = [[PreferenceManager sharedInstance] getBooleanPref:"browser.chrome.site_icons" withSuccess:NULL];
|
||||
BOOL siteIconLoadInitiated = NO;
|
||||
|
||||
SiteIconProvider* faviconProvider = [SiteIconProvider sharedFavoriteIconProvider];
|
||||
NSString* faviconURI = [SiteIconProvider faviconLocationStringFromURI:urlSpec];
|
||||
|
||||
if (useSiteIcons && [faviconURI length] > 0)
|
||||
{
|
||||
// if the favicon uri has changed, fire off favicon load. When it completes, our
|
||||
// imageLoadedNotification selector gets called.
|
||||
if (![faviconURI isEqualToString:mSiteIconURI])
|
||||
siteIconLoadInitiated = [faviconProvider loadFavoriteIcon:self forURI:urlSpec withUserData:nil allowNetwork:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([urlSpec isEqualToString:@"about:blank"])
|
||||
faviconURI = urlSpec;
|
||||
else
|
||||
faviconURI = @"";
|
||||
}
|
||||
|
||||
if (!siteIconLoadInitiated)
|
||||
[self updateSiteIconImage:nil withURI:faviconURI];
|
||||
|
||||
if (mIsPrimary)
|
||||
[mWindowController updateLocationFields:urlSpec];
|
||||
}
|
||||
|
||||
- (void)onStatusChange:(NSString*)aStatusString
|
||||
{
|
||||
if (![[mStatus stringValue] isEqualToString:aStatusString])
|
||||
{
|
||||
[mStatus setStringValue: aStatusString];
|
||||
//[mStatus displayIfNeeded]; // XXX expensive; slows page load
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// onSecurityStateChange:
|
||||
//
|
||||
// Update the lock to the appropriate icon to match what necko is telling us, but
|
||||
// only if we own the UI. If we're not the primary browser, we have no business
|
||||
// mucking with the lock icon.
|
||||
//
|
||||
- (void)onSecurityStateChange:(unsigned long)newState
|
||||
{
|
||||
mSecureState = newState;
|
||||
if ( mIsPrimary )
|
||||
[mWindowController updateLock:newState];
|
||||
}
|
||||
|
||||
- (void)setStatus:(NSString *)statusString ofType:(NSStatusType)type
|
||||
{
|
||||
NSString* newStatus = nil;
|
||||
|
||||
if (type == NSStatusTypeScriptDefault)
|
||||
{
|
||||
[mDefaultStatusString autorelease];
|
||||
mDefaultStatusString = statusString;
|
||||
[mDefaultStatusString retain];
|
||||
}
|
||||
else if (!statusString)
|
||||
{
|
||||
newStatus = (mDefaultStatusString) ? mDefaultStatusString : mLoadingStatusString;
|
||||
}
|
||||
else
|
||||
{
|
||||
newStatus = statusString;
|
||||
}
|
||||
|
||||
if (newStatus && ![[mStatus stringValue] isEqualToString:newStatus])
|
||||
{
|
||||
[mStatus setStringValue:newStatus];
|
||||
//[mStatus displayIfNeeded]; // force an immediate display. This works around some issues
|
||||
// where cocoa unions update rects in the content and chrome,
|
||||
// causing slow updating (bug 2194819).
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)title
|
||||
{
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
- (void)setTitle:(NSString *)title
|
||||
{
|
||||
if ([title length] == 0)
|
||||
{
|
||||
// if we get a blank title that is not for "about:blank", use the url,
|
||||
// or filename
|
||||
NSString* curURL = [self getCurrentURLSpec];
|
||||
if (![curURL isEqualToString:@"about:blank"])
|
||||
{
|
||||
if ([curURL hasPrefix:@"file://"])
|
||||
title = [curURL lastPathComponent];
|
||||
else
|
||||
title = curURL;
|
||||
}
|
||||
}
|
||||
|
||||
[self setTabTitle:title windowTitle:title];
|
||||
}
|
||||
|
||||
- (void)setTabTitle:(NSString*)tabTitle windowTitle:(NSString*)windowTitle
|
||||
{
|
||||
[mTabTitle autorelease];
|
||||
if (tabTitle && [tabTitle length] > 0)
|
||||
mTabTitle = tabTitle;
|
||||
else
|
||||
mTabTitle = NSLocalizedString(@"UntitledPageTitle", @"");
|
||||
[mTabTitle retain];
|
||||
|
||||
[mTitle autorelease];
|
||||
if (windowTitle && [windowTitle length] > 0)
|
||||
mTitle = windowTitle;
|
||||
else
|
||||
mTitle = NSLocalizedString(@"UntitledPageTitle", @"");
|
||||
|
||||
if (mOffline)
|
||||
mTitle = [NSString stringWithFormat:NSLocalizedString(@"OfflineTitleFormat", @""), mTitle];
|
||||
[mTitle retain];
|
||||
|
||||
if (mIsPrimary)
|
||||
[[mWindowController window] setTitle:[mTitle stringByTruncatingTo:80 at:kTruncateAtEnd]];
|
||||
|
||||
// Always set the tab.
|
||||
[mTabItem setLabel:mTabTitle]; // tab titles get truncated when setting them to tabs
|
||||
}
|
||||
|
||||
- (BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
//
|
||||
// onShowTooltip:where:withText
|
||||
//
|
||||
// Unfortunately, we can't use cocoa's apis here because they rely on setting a region
|
||||
// and waiting. We already have waited and we just want to display the tooltip, so we
|
||||
// drop down to the Carbon help manager routines.
|
||||
//
|
||||
// |where| is relative to the browser view in QD coordinates (top left is (0,0))
|
||||
// and must be converted to global QD coordinates for the carbon help manager.
|
||||
//
|
||||
- (void)onShowTooltip:(NSPoint)where withText:(NSString*)text
|
||||
{
|
||||
NSPoint point = [[self window] convertBaseToScreen:[self convertPoint: where toView:nil]];
|
||||
[mToolTip showToolTipAtPoint: point withString: text];
|
||||
}
|
||||
|
||||
- (void)onHideTooltip
|
||||
{
|
||||
[mToolTip closeToolTip];
|
||||
}
|
||||
|
||||
// Called when a context menu should be shown.
|
||||
- (void)onShowContextMenu:(int)flags domEvent:(nsIDOMEvent*)aEvent domNode:(nsIDOMNode*)aNode
|
||||
{
|
||||
[mWindowController onShowContextMenu: flags domEvent: aEvent domNode: aNode];
|
||||
}
|
||||
|
||||
-(NSMenu*)getContextMenu
|
||||
{
|
||||
return [mWindowController getContextMenu];
|
||||
}
|
||||
|
||||
-(NSWindow*)getNativeWindow
|
||||
{
|
||||
NSWindow* window = [self window];
|
||||
if (window)
|
||||
return window;
|
||||
|
||||
if (mWindow)
|
||||
return mWindow;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAcceptDragFromSource:(id)dragSource
|
||||
{
|
||||
if ((dragSource == self) || (dragSource == mTabItem) || (dragSource == [mWindowController proxyIconView]))
|
||||
return NO;
|
||||
|
||||
if ([mTabItem isMemberOfClass:[BrowserTabViewItem class]] && (dragSource == [(BrowserTabViewItem*)mTabItem tabItemContentsView]))
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
//
|
||||
// closeBrowserWindow
|
||||
//
|
||||
// Gecko wants us to close the browser associated with this gecko instance. However,
|
||||
// we're just one tab in the window so we don't really have the power to do this.
|
||||
// Let the window controller have final say.
|
||||
//
|
||||
- (void)closeBrowserWindow
|
||||
{
|
||||
[mWindowController closeBrowserWindow:self];
|
||||
}
|
||||
|
||||
- (void)getTitle:(NSString **)outTitle andHref:(NSString**)outHrefString
|
||||
{
|
||||
*outTitle = *outHrefString = nil;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window = getter_AddRefs([mBrowserView getContentWindow]);
|
||||
if (!window) return;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> htmlDoc;
|
||||
window->GetDocument(getter_AddRefs(htmlDoc));
|
||||
nsCOMPtr<nsIDocument> pageDoc(do_QueryInterface(htmlDoc));
|
||||
if (pageDoc)
|
||||
{
|
||||
nsCOMPtr<nsIURI> url;
|
||||
pageDoc->GetDocumentURL(getter_AddRefs(url));
|
||||
nsCAutoString spec;
|
||||
url->GetSpec(spec);
|
||||
*outHrefString = [NSString stringWithUTF8String:spec.get()];
|
||||
}
|
||||
|
||||
nsAutoString titleString;
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDocument(do_QueryInterface(htmlDoc));
|
||||
if (htmlDocument)
|
||||
htmlDocument->GetTitle(titleString);
|
||||
if (!titleString.IsEmpty())
|
||||
*outTitle = [NSString stringWith_nsAString:titleString];
|
||||
else if (*outHrefString)
|
||||
*outTitle = [NSString stringWithString:*outHrefString];
|
||||
}
|
||||
|
||||
-(void)setIsBookmarksImport:(BOOL)aIsImport
|
||||
{
|
||||
mIsBookmarksImport = aIsImport;
|
||||
}
|
||||
|
||||
- (void)offlineModeChanged: (NSNotification*)aNotification
|
||||
{
|
||||
nsCOMPtr<nsIIOService> ioService(do_GetService(ioServiceContractID));
|
||||
if (!ioService)
|
||||
return;
|
||||
PRBool offline = PR_FALSE;
|
||||
ioService->GetOffline(&offline);
|
||||
mOffline = offline;
|
||||
|
||||
if (mOffline) {
|
||||
NSString* newTitle = [[[mWindowController window] title] stringByAppendingString: @" [Working Offline]"];
|
||||
[[mWindowController window] setTitle: newTitle];
|
||||
}
|
||||
else {
|
||||
NSArray* titleItems = [[[mWindowController window] title] componentsSeparatedByString:@" [Working Offline]"];
|
||||
[[mWindowController window] setTitle: [titleItems objectAtIndex: 0]];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// sizeBrowserTo
|
||||
//
|
||||
// Sizes window so that browser has dimensions given by |dimensions|
|
||||
//
|
||||
- (void)sizeBrowserTo:(NSSize)dimensions
|
||||
{
|
||||
NSRect bounds = [self bounds];
|
||||
float dx = dimensions.width - bounds.size.width;
|
||||
float dy = dimensions.height - bounds.size.height;
|
||||
|
||||
NSRect frame = [[self window] frame];
|
||||
NSPoint topLeft = NSMakePoint(NSMinX(frame), NSMaxY(frame));
|
||||
frame.size.width += dx;
|
||||
frame.size.height += dy;
|
||||
|
||||
// if we just call setFrame, it will change the top-left corner of the
|
||||
// window as it pulls the extra space from the top and right sides of the window,
|
||||
// which is not at all what the website desired. We must preserve
|
||||
// topleft of the window and reset it after we resize.
|
||||
[[self window] setFrame:frame display:YES];
|
||||
[[self window] setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
|
||||
- (CHBrowserView*)createBrowserWindow:(unsigned int)aMask
|
||||
{
|
||||
nsCOMPtr<nsIPrefBranch> pref(do_GetService("@mozilla.org/preferences-service;1"));
|
||||
if (!pref)
|
||||
return NS_OK; // Something bad happened if we can't get prefs.
|
||||
|
||||
PRBool showBlocker;
|
||||
pref->GetBoolPref("browser.popups.showPopupBlocker", &showBlocker);
|
||||
|
||||
if (showBlocker) {
|
||||
nsCOMPtr<nsIDOMWindow> domWindow = getter_AddRefs([mBrowserView getContentWindow]);
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(domWindow));
|
||||
PRBool isUnrequested;
|
||||
piWindow->IsLoadingOrRunningTimeout(&isUnrequested);
|
||||
if (isUnrequested) {
|
||||
// A popup is being opened while the page is currently loading. Offer to block the
|
||||
// popup.
|
||||
nsAlertController* controller = CHBrowserService::GetAlertController();
|
||||
BOOL confirm = [controller confirm: [self window] title: @"Unrequested Popup Detected"
|
||||
text: [NSString stringWithFormat: NSLocalizedString(@"PopupBlockMsg", @""), NSLocalizedStringFromTable(@"CFBundleName", @"InfoPlist", nil)]];
|
||||
|
||||
// This is a one-time dialog.
|
||||
pref->SetBoolPref("browser.popups.showPopupBlocker", PR_FALSE);
|
||||
|
||||
if (confirm) {
|
||||
pref->SetBoolPref("dom.disable_open_during_load", PR_TRUE);
|
||||
pref->SetIntPref("dom.disable_open_click_delay", 1000);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrefService> prefService(do_QueryInterface(pref));
|
||||
prefService->SavePrefFile(nsnull);
|
||||
|
||||
if (confirm)
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
BrowserWindowController* controller = [[BrowserWindowController alloc] initWithWindowNibName: @"BrowserWindow"];
|
||||
[controller setChromeMask: aMask];
|
||||
[controller disableAutosave]; // The Web page opened this window, so we don't ever use its settings.
|
||||
[controller disableLoadPage]; // don't load about:blank initially since this is a script-opened window
|
||||
|
||||
[controller window]; // force window load. The window gets made visible by CHBrowserListener::SetVisibility
|
||||
|
||||
[[controller getBrowserWrapper] setPendingActive: YES];
|
||||
return [[controller getBrowserWrapper] getBrowserView];
|
||||
}
|
||||
|
||||
- (CHBrowserView*)getBrowserView
|
||||
{
|
||||
return mBrowserView;
|
||||
}
|
||||
|
||||
- (void)setPendingActive:(BOOL)active
|
||||
{
|
||||
mActivateOnLoad = active;
|
||||
}
|
||||
|
||||
- (void)setSiteIconImage:(NSImage*)inSiteIcon
|
||||
{
|
||||
[mSiteIconImage autorelease];
|
||||
mSiteIconImage = [inSiteIcon retain];
|
||||
}
|
||||
|
||||
- (void)setSiteIconURI:(NSString*)inSiteIconURI
|
||||
{
|
||||
[mSiteIconURI autorelease];
|
||||
mSiteIconURI = [inSiteIconURI retain];
|
||||
}
|
||||
|
||||
// A nil inSiteIcon image indicates that we should use the default icon
|
||||
// If inSiteIconURI is "about:blank", we don't show any icon
|
||||
- (void)updateSiteIconImage:(NSImage*)inSiteIcon withURI:(NSString *)inSiteIconURI
|
||||
{
|
||||
BOOL resetTabIcon = NO;
|
||||
BOOL tabIconDraggable = YES;
|
||||
NSImage* siteIcon = inSiteIcon;
|
||||
|
||||
if (![mSiteIconURI isEqualToString:inSiteIconURI])
|
||||
{
|
||||
if (!siteIcon)
|
||||
{
|
||||
if ([inSiteIconURI isEqualToString:@"about:blank"]) {
|
||||
siteIcon = [NSImage imageNamed:@"smallDocument"];
|
||||
tabIconDraggable = NO;
|
||||
} else
|
||||
siteIcon = [NSImage imageNamed:@"globe_ico"];
|
||||
}
|
||||
|
||||
[self setSiteIconImage: siteIcon];
|
||||
[self setSiteIconURI: inSiteIconURI];
|
||||
|
||||
// update the proxy icon
|
||||
if (mIsPrimary)
|
||||
[mWindowController updateSiteIcons:mSiteIconImage];
|
||||
|
||||
resetTabIcon = YES;
|
||||
}
|
||||
|
||||
// update the tab icon
|
||||
if ([mTabItem isMemberOfClass:[BrowserTabViewItem class]])
|
||||
{
|
||||
BrowserTabViewItem* tabItem = (BrowserTabViewItem*)mTabItem;
|
||||
if (resetTabIcon || ![tabItem tabIcon])
|
||||
[tabItem setTabIcon:mSiteIconImage isDraggable:tabIconDraggable];
|
||||
}
|
||||
|
||||
// make sure any bookmark items that use this favicon uri are updated
|
||||
if (inSiteIcon)
|
||||
[[BookmarksManager sharedBookmarksManager] updateProxyImage:inSiteIcon forSiteIcon:inSiteIconURI];
|
||||
}
|
||||
|
||||
- (void)registerNotificationListener
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self
|
||||
selector: @selector(imageLoadedNotification:)
|
||||
name: SiteIconLoadNotificationName
|
||||
object: self];
|
||||
|
||||
}
|
||||
|
||||
// called when [[SiteIconProvider sharedFavoriteIconProvider] loadFavoriteIcon] completes
|
||||
- (void)imageLoadedNotification:(NSNotification*)notification
|
||||
{
|
||||
NSDictionary* userInfo = [notification userInfo];
|
||||
if (userInfo)
|
||||
{
|
||||
NSImage* iconImage = [userInfo objectForKey:SiteIconLoadImageKey];
|
||||
NSString* siteIconURI = [userInfo objectForKey:SiteIconLoadURIKey];
|
||||
|
||||
// NSLog(@"BrowserWrapper imageLoadedNotification got image %@ and uri %@", iconImage, proxyImageURI);
|
||||
if (iconImage == nil)
|
||||
siteIconURI = @""; // go back to default image
|
||||
|
||||
[self updateSiteIconImage:iconImage withURI:siteIconURI];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// -isEmpty
|
||||
//
|
||||
// YES if the page currently loaded in the browser view is "about:blank", NO otherwise
|
||||
//
|
||||
- (BOOL) isEmpty
|
||||
{
|
||||
return [[[self getBrowserView] getCurrentURI] isEqualToString:@"about:blank"];
|
||||
}
|
||||
|
||||
@end
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIPromptService.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
class CocoaPromptService : public nsIPromptService
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,319 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
#import "RemoteDataProvider.h"
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsICacheSession.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsICachingChannel.h"
|
||||
|
||||
NSString* RemoteDataLoadRequestNotificationName = @"remoteload_notification_name";
|
||||
NSString* RemoteDataLoadRequestURIKey = @"remoteload_uri_key";
|
||||
NSString* RemoteDataLoadRequestDataKey = @"remoteload_data_key";
|
||||
NSString* RemoteDataLoadRequestUserDataKey = @"remoteload_user_data_key";
|
||||
NSString* RemoteDataLoadRequestResultKey = @"remoteload_result_key";
|
||||
|
||||
|
||||
// this has to retain the load listener, to ensure that the listener lives long
|
||||
// enough to receive notifications. We have to be careful to avoid ref cycles.
|
||||
class StreamLoaderContext : public nsISupports
|
||||
{
|
||||
public:
|
||||
StreamLoaderContext(id<RemoteLoadListener> inLoadListener, id inUserData, id inTarget, const nsAString& inURI)
|
||||
: mLoadListener(inLoadListener)
|
||||
, mTarget(inTarget)
|
||||
, mUserData(inUserData)
|
||||
, mURI(inURI)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
[mLoadListener retain];
|
||||
}
|
||||
|
||||
virtual ~StreamLoaderContext()
|
||||
{
|
||||
[mLoadListener release];
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
void LoadComplete(nsresult inLoadStatus, const void* inData, unsigned int inDataLength);
|
||||
const nsAString& GetURI() { return mURI; }
|
||||
|
||||
protected:
|
||||
|
||||
id<RemoteLoadListener> mLoadListener; // retained
|
||||
id mTarget; // not retained
|
||||
id mUserData; // not retained
|
||||
nsString mURI;
|
||||
|
||||
};
|
||||
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(StreamLoaderContext, nsISupports)
|
||||
|
||||
void StreamLoaderContext::LoadComplete(nsresult inLoadStatus, const void* inData, unsigned int inDataLength)
|
||||
{
|
||||
if (mLoadListener)
|
||||
{
|
||||
NSData* loadData = nil;
|
||||
if (NS_SUCCEEDED(inLoadStatus))
|
||||
loadData = [NSData dataWithBytes:inData length:inDataLength];
|
||||
|
||||
[mLoadListener doneRemoteLoad:[NSString stringWith_nsAString:mURI] forTarget:mTarget withUserData:mUserData data:loadData status:inLoadStatus];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
class RemoteURILoadManager : public nsIStreamLoaderObserver
|
||||
{
|
||||
public:
|
||||
|
||||
RemoteURILoadManager();
|
||||
virtual ~RemoteURILoadManager();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMLOADEROBSERVER
|
||||
|
||||
nsresult Init();
|
||||
nsresult RequestURILoad(const nsAString& inURI, id<RemoteLoadListener> loadListener, id userData, id target, PRBool allowNetworking);
|
||||
nsresult CancelAllRequests();
|
||||
|
||||
protected:
|
||||
|
||||
nsSupportsHashtable mStreamLoaderHash; // hash of active stream loads, keyed on URI
|
||||
nsCOMPtr<nsICacheSession> mCacheSession;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
||||
};
|
||||
|
||||
RemoteURILoadManager::RemoteURILoadManager()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
RemoteURILoadManager::~RemoteURILoadManager()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(RemoteURILoadManager, nsIStreamLoaderObserver)
|
||||
|
||||
NS_IMETHODIMP RemoteURILoadManager::OnStreamComplete(nsIStreamLoader *loader, nsISupports *ctxt, nsresult status, PRUint32 resultLength, const char *result)
|
||||
{
|
||||
StreamLoaderContext* loaderContext = NS_STATIC_CAST(StreamLoaderContext*, ctxt);
|
||||
if (loaderContext)
|
||||
{
|
||||
loaderContext->LoadComplete(status, (const void*)result, resultLength);
|
||||
|
||||
// remove the stream loader from the hash table
|
||||
nsStringKey uriKey(loaderContext->GetURI());
|
||||
PRBool removed = mStreamLoaderHash.Remove(&uriKey);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID);
|
||||
|
||||
nsresult RemoteURILoadManager::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICacheService> cacheService = do_GetService(kCacheServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = cacheService->CreateSession("HTTP", nsICache::STORE_ANYWHERE,
|
||||
nsICache::STREAM_BASED, getter_AddRefs(mCacheSession));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult RemoteURILoadManager::RequestURILoad(const nsAString& inURI, id<RemoteLoadListener> loadListener,
|
||||
id userData, id target, PRBool allowNetworking)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsStringKey uriKey(inURI);
|
||||
|
||||
// first make sure that there isn't another entry in the hash for this
|
||||
nsCOMPtr<nsISupports> foundStreamSupports = mStreamLoaderHash.Get(&uriKey);
|
||||
if (foundStreamSupports)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), inURI);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// create a load group, that we can use to cancel all the requests on quit
|
||||
if (!mLoadGroup)
|
||||
mLoadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
|
||||
|
||||
nsCOMPtr<nsISupports> loaderContext = new StreamLoaderContext(loadListener, userData, target, inURI);
|
||||
|
||||
nsLoadFlags loadFlags = (allowNetworking) ? nsIRequest::LOAD_NORMAL : nsIRequest::LOAD_FROM_CACHE;
|
||||
loadFlags |= nsIRequest::LOAD_BACKGROUND; // don't show progress or cookie dialogs
|
||||
if (!allowNetworking)
|
||||
loadFlags |= nsICachingChannel::LOAD_ONLY_FROM_CACHE;
|
||||
|
||||
// we have to make a channel ourselves for the streamloader, so that we can
|
||||
// do the nsICachingChannel stuff.
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel), uri, nsnull, mLoadGroup,
|
||||
nsnull, loadFlags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIStreamLoader> streamLoader;
|
||||
rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), channel, this, loaderContext) ; // , mLoadGroup, nsnull, loadFlags);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
#if DEBUG
|
||||
NSLog(@"NS_NewStreamLoader for favicon failed");
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
// put the stream loader into the hash table
|
||||
nsCOMPtr<nsISupports> streamLoaderAsSupports = do_QueryInterface(streamLoader);
|
||||
mStreamLoaderHash.Put(&uriKey, streamLoaderAsSupports);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RemoteURILoadManager::CancelAllRequests()
|
||||
{
|
||||
if (mLoadGroup)
|
||||
mLoadGroup->Cancel(NS_BINDING_ABORTED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
@implementation RemoteDataProvider
|
||||
|
||||
|
||||
+ (RemoteDataProvider*)sharedRemoteDataProvider
|
||||
{
|
||||
static RemoteDataProvider* sIconProvider = nil;
|
||||
if (!sIconProvider)
|
||||
{
|
||||
sIconProvider = [[RemoteDataProvider alloc] init];
|
||||
|
||||
// we probably need to register for NSApplicationWillTerminateNotification notifications
|
||||
// and delete this then.
|
||||
}
|
||||
|
||||
return sIconProvider;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
mLoadManager = new RemoteURILoadManager;
|
||||
NS_ADDREF(mLoadManager);
|
||||
nsresult rv = mLoadManager->Init();
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_RELEASE(mLoadManager);
|
||||
mLoadManager = nil;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NS_IF_RELEASE(mLoadManager);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL)loadURI:(NSString*)inURI forTarget:(id)target withListener:(id<RemoteLoadListener>)inListener
|
||||
withUserData:(id)userData allowNetworking:(BOOL)inNetworkOK
|
||||
{
|
||||
if (mLoadManager && [inURI length] > 0)
|
||||
{
|
||||
nsAutoString uriString;
|
||||
[inURI assignTo_nsAString:uriString];
|
||||
|
||||
nsresult rv = mLoadManager->RequestURILoad(uriString, inListener, userData, target, (PRBool)inNetworkOK);
|
||||
if (NS_FAILED(rv))
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)postURILoadRequest:(NSString*)inURI forTarget:(id)target withUserData:(id)userData allowNetworking:(BOOL)inNetworkOK
|
||||
{
|
||||
return [self loadURI:inURI forTarget:target withListener:self withUserData:userData allowNetworking:inNetworkOK];
|
||||
}
|
||||
|
||||
|
||||
- (void)cancelOutstandingRequests
|
||||
{
|
||||
if (mLoadManager)
|
||||
mLoadManager->CancelAllRequests();
|
||||
}
|
||||
|
||||
|
||||
// our own load listener callback
|
||||
- (void)doneRemoteLoad:(NSString*)inURI forTarget:(id)target withUserData:(id)userData data:(NSData*)data status:(nsresult)status
|
||||
{
|
||||
NSDictionary* notificationData = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
inURI, RemoteDataLoadRequestURIKey,
|
||||
data, RemoteDataLoadRequestDataKey,
|
||||
userData, RemoteDataLoadRequestUserDataKey,
|
||||
[NSNumber numberWithInt:status], RemoteDataLoadRequestResultKey,
|
||||
nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName: RemoteDataLoadRequestNotificationName
|
||||
object:target userInfo:notificationData];
|
||||
}
|
||||
|
||||
@end
|
|
@ -52,12 +52,12 @@ public:
|
|||
virtual ~SecurityDialogs();
|
||||
|
||||
NS_DECL_ISUPPORTS;
|
||||
NS_DECL_NSIBADCERTLISTENER
|
||||
NS_DECL_NSISECURITYWARNINGDIALOGS
|
||||
NS_DECL_NSIBADCERTLISTENER;
|
||||
NS_DECL_NSISECURITYWARNINGDIALOGS;
|
||||
|
||||
private:
|
||||
nsresult EnsureSecurityStringBundle();
|
||||
|
||||
|
||||
nsresult AlertDialog(nsIInterfaceRequestor* ctx, const char* prefName,
|
||||
const PRUnichar* messageName,
|
||||
const PRUnichar* showAgainName);
|
||||
|
|
|
@ -57,12 +57,11 @@ SecurityDialogs::~SecurityDialogs()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(SecurityDialogs, nsIBadCertListener, nsISecurityWarningDialogs)
|
||||
NS_IMPL_ISUPPORTS2(SecurityDialogs, nsIBadCertListener, nsISecurityWarningDialogs);
|
||||
|
||||
// nsIBadCertListener implementation
|
||||
/* boolean confirmUnknownIssuer (in nsIInterfaceRequestor socketInfo,
|
||||
in nsIX509Cert cert,
|
||||
out short certAddType); */
|
||||
in nsIX509Cert cert, out addType); */
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmUnknownIssuer(nsIInterfaceRequestor *socketInfo,
|
||||
nsIX509Cert *cert, PRInt16 *outAddType,
|
||||
|
@ -148,9 +147,11 @@ SecurityDialogs::NotifyCrlNextupdate(nsIInterfaceRequestor *socketInfo,
|
|||
#define MIXEDCONTENT_PREF "security.warn_viewing_mixed"
|
||||
#define INSECURE_SUBMIT_PREF "security.warn_submit_insecure"
|
||||
|
||||
// XXXbryner should we make these real confirmation dialogs?
|
||||
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmEnteringSecure(nsIInterfaceRequestor *ctx,
|
||||
PRBool *canceled)
|
||||
PRBool *_retval)
|
||||
{
|
||||
// I don't think any user cares they're entering a secure site.
|
||||
#if 0
|
||||
|
@ -159,15 +160,15 @@ SecurityDialogs::ConfirmEnteringSecure(nsIInterfaceRequestor *ctx,
|
|||
NS_LITERAL_STRING("EnterSecureShowAgain").get());
|
||||
#endif
|
||||
|
||||
*canceled = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmEnteringWeak(nsIInterfaceRequestor *ctx,
|
||||
PRBool *canceled)
|
||||
PRBool *_retval)
|
||||
{
|
||||
*canceled = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return AlertDialog(ctx, WEAK_SITE_PREF,
|
||||
NS_LITERAL_STRING("WeakSecureMessage").get(),
|
||||
NS_LITERAL_STRING("WeakSecureShowAgain").get());
|
||||
|
@ -175,9 +176,9 @@ SecurityDialogs::ConfirmEnteringWeak(nsIInterfaceRequestor *ctx,
|
|||
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmLeavingSecure(nsIInterfaceRequestor *ctx,
|
||||
PRBool *canceled)
|
||||
PRBool *_retval)
|
||||
{
|
||||
*canceled = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return AlertDialog(ctx, LEAVE_SITE_PREF,
|
||||
NS_LITERAL_STRING("LeaveSecureMessage").get(),
|
||||
NS_LITERAL_STRING("LeaveSecureShowAgain").get());
|
||||
|
@ -185,9 +186,9 @@ SecurityDialogs::ConfirmLeavingSecure(nsIInterfaceRequestor *ctx,
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
SecurityDialogs::ConfirmMixedMode(nsIInterfaceRequestor *ctx, PRBool *canceled)
|
||||
SecurityDialogs::ConfirmMixedMode(nsIInterfaceRequestor *ctx, PRBool *_retval)
|
||||
{
|
||||
*canceled = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return AlertDialog(ctx, MIXEDCONTENT_PREF,
|
||||
NS_LITERAL_STRING("MixedContentMessage").get(),
|
||||
NS_LITERAL_STRING("MixedContentShowAgain").get());
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface nsAlertController : NSObject
|
||||
{
|
||||
IBOutlet id alertCheckPanel;
|
||||
IBOutlet id alertCheckPanelCheck;
|
||||
IBOutlet id alertCheckPanelText;
|
||||
IBOutlet id alertPanel;
|
||||
IBOutlet id alertPanelText;
|
||||
IBOutlet id confirmCheckPanel;
|
||||
IBOutlet id confirmCheckPanelCheck;
|
||||
IBOutlet id confirmCheckPanelText;
|
||||
IBOutlet id confirmCheckPanelButton1;
|
||||
IBOutlet id confirmCheckPanelButton2;
|
||||
IBOutlet id confirmPanel;
|
||||
IBOutlet id confirmPanelText;
|
||||
IBOutlet id confirmPanelButton1;
|
||||
IBOutlet id confirmPanelButton2;
|
||||
IBOutlet id promptPanel;
|
||||
IBOutlet id promptPanelCheck;
|
||||
IBOutlet id promptPanelText;
|
||||
IBOutlet id promptPanelInput;
|
||||
IBOutlet id passwordPanel;
|
||||
IBOutlet id passwordPanelCheck;
|
||||
IBOutlet id passwordPanelText;
|
||||
IBOutlet id passwordPanelInput;
|
||||
IBOutlet id postToInsecureFromSecurePanel;
|
||||
IBOutlet id securityMismatchPanel;
|
||||
IBOutlet id expiredCertPanel;
|
||||
IBOutlet id securityUnknownPanel;
|
||||
IBOutlet id usernamePanel;
|
||||
IBOutlet id usernamePanelCheck;
|
||||
IBOutlet id usernamePanelText;
|
||||
IBOutlet id usernamePanelPassword;
|
||||
IBOutlet id usernamePanelUserName;
|
||||
IBOutlet id owner;
|
||||
}
|
||||
- (IBAction)hitButton1:(id)sender;
|
||||
- (IBAction)hitButton2:(id)sender;
|
||||
- (IBAction)hitButton3:(id)sender;
|
||||
|
||||
- (void)awakeFromNib;
|
||||
- (void)alert:(NSWindow*)parent title:(NSString*)title text:(NSString*)text;
|
||||
- (void)alertCheck:(NSWindow*)parent title:(NSString*)title text:(NSString*)text checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue;
|
||||
|
||||
- (BOOL)confirm:(NSWindow*)parent title:(NSString*)title text:(NSString*)text;
|
||||
- (BOOL)confirmCheck:(NSWindow*)parent title:(NSString*)title text:(NSString*)text checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue;
|
||||
|
||||
- (int)confirmEx:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
button1:(NSString*)btn1 button2:(NSString*)btn2 button3:(NSString*)btn3;
|
||||
- (int)confirmCheckEx:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
button1:(NSString*)btn1 button2:(NSString*)btn2 button3:(NSString*)btn3
|
||||
checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue;
|
||||
|
||||
- (BOOL)prompt:(NSWindow*)parent title:(NSString*)title text:(NSString*)text promptText:(NSMutableString*)promptText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck;
|
||||
- (BOOL)promptUserNameAndPassword:(NSWindow*)parent title:(NSString*)title text:(NSString*)text userNameText:(NSMutableString*)userNameText passwordText:(NSMutableString*)passwordText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck;
|
||||
- (BOOL)promptPassword:(NSWindow*)parent title:(NSString*)title text:(NSString*)text passwordText:(NSMutableString*)passwordText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck;
|
||||
|
||||
- (BOOL)postToInsecureFromSecure:(NSWindow*)parent;
|
||||
|
||||
- (BOOL)badCert:(NSWindow*)parent;
|
||||
- (BOOL)expiredCert:(NSWindow*)parent;
|
||||
- (int)unknownCert:(NSWindow*)parent;
|
||||
|
||||
@end
|
|
@ -1,308 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "nsAlertController.h"
|
||||
#import "CHBrowserService.h"
|
||||
|
||||
#include "nsIBadCertListener.h"
|
||||
|
||||
enum { kOKButton = 0, kCancelButton = 1, kOtherButton = 2 };
|
||||
|
||||
@implementation nsAlertController
|
||||
|
||||
- (IBAction)hitButton1:(id)sender
|
||||
{
|
||||
[NSApp stopModalWithCode:kOKButton];
|
||||
}
|
||||
|
||||
- (IBAction)hitButton2:(id)sender
|
||||
{
|
||||
[NSApp stopModalWithCode:kCancelButton];
|
||||
}
|
||||
|
||||
- (IBAction)hitButton3:(id)sender
|
||||
{
|
||||
[NSApp stopModalWithCode:kOtherButton];
|
||||
}
|
||||
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
CHBrowserService::SetAlertController(self);
|
||||
}
|
||||
|
||||
- (void)alert:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
{
|
||||
[alertPanelText setStringValue:text];
|
||||
[alertPanel setTitle:title];
|
||||
|
||||
[NSApp runModalForWindow:alertPanel relativeToWindow:parent];
|
||||
|
||||
[alertPanel close];
|
||||
}
|
||||
|
||||
- (void)alertCheck:(NSWindow*)parent title:(NSString*)title text:(NSString*)text checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue
|
||||
{
|
||||
[alertCheckPanelText setStringValue:text];
|
||||
[alertCheckPanel setTitle:title];
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[alertCheckPanelCheck setState:state];
|
||||
[alertCheckPanelCheck setTitle:checkMsg];
|
||||
|
||||
[NSApp runModalForWindow:alertCheckPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([alertCheckPanelCheck state] == NSOnState);
|
||||
[alertCheckPanel close];
|
||||
}
|
||||
|
||||
- (BOOL)confirm:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
{
|
||||
[confirmPanelText setStringValue:text];
|
||||
[confirmPanel setTitle:title];
|
||||
|
||||
int result = [NSApp runModalForWindow:confirmPanel relativeToWindow:parent];
|
||||
|
||||
[confirmPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (BOOL)confirmCheck:(NSWindow*)parent title:(NSString*)title text:(NSString*)text checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue
|
||||
{
|
||||
[confirmCheckPanelText setStringValue:text];
|
||||
[confirmCheckPanel setTitle:title];
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[confirmCheckPanelCheck setState:state];
|
||||
[confirmCheckPanelCheck setTitle:checkMsg];
|
||||
|
||||
int result = [NSApp runModalForWindow:confirmCheckPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([confirmCheckPanelCheck state] == NSOnState);
|
||||
[confirmCheckPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (int)confirmEx:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
button1:(NSString*)btn1 button2:(NSString*)btn2 button3:(NSString*)btn3
|
||||
{
|
||||
[confirmPanelText setStringValue:text];
|
||||
[confirmPanel setTitle:title];
|
||||
|
||||
[confirmPanelButton1 setTitle:btn1];
|
||||
[confirmPanelButton2 setTitle:btn2];
|
||||
|
||||
int result = [NSApp runModalForWindow:confirmPanel relativeToWindow:parent];
|
||||
|
||||
[confirmPanel close];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (int)confirmCheckEx:(NSWindow*)parent title:(NSString*)title text:(NSString*)text
|
||||
button1:(NSString*)btn1 button2:(NSString*)btn2 button3:(NSString*)btn3
|
||||
checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue
|
||||
{
|
||||
[confirmCheckPanelText setStringValue:text];
|
||||
[confirmCheckPanel setTitle:title];
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[confirmCheckPanelCheck setState:state];
|
||||
[confirmCheckPanelCheck setTitle:checkMsg];
|
||||
|
||||
[confirmCheckPanelButton1 setTitle:btn1];
|
||||
[confirmCheckPanelButton2 setTitle:btn2];
|
||||
|
||||
int result = [NSApp runModalForWindow:confirmCheckPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([confirmCheckPanelCheck state] == NSOnState);
|
||||
[confirmCheckPanel close];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)prompt:(NSWindow*)parent title:(NSString*)title text:(NSString*)text promptText:(NSMutableString*)promptText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck
|
||||
{
|
||||
[promptPanelText setStringValue:text];
|
||||
[promptPanel setTitle:title];
|
||||
if (doCheck) {
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[promptPanelCheck setState:state];
|
||||
[promptPanelCheck setTransparent:NO];
|
||||
}
|
||||
else {
|
||||
[promptPanelCheck setTransparent:YES];
|
||||
}
|
||||
[promptPanelCheck setTitle:checkMsg];
|
||||
[promptPanelInput setStringValue:promptText];
|
||||
|
||||
int result = [NSApp runModalForWindow:promptPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([promptPanelCheck state] == NSOnState);
|
||||
|
||||
NSString* value = [promptPanelInput stringValue];
|
||||
PRUint32 length = [promptText length];
|
||||
if (length) {
|
||||
NSRange all;
|
||||
all.location = 0;
|
||||
all.length = [promptText length];
|
||||
[promptText deleteCharactersInRange:all];
|
||||
}
|
||||
[promptText appendString:value];
|
||||
|
||||
[promptPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (BOOL)promptUserNameAndPassword:(NSWindow*)parent title:(NSString*)title text:(NSString*)text userNameText:(NSMutableString*)userNameText passwordText:(NSMutableString*)passwordText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck
|
||||
{
|
||||
[usernamePanelText setStringValue:text];
|
||||
[usernamePanel setTitle:title];
|
||||
if (doCheck) {
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[usernamePanelCheck setState:state];
|
||||
[usernamePanelCheck setTransparent:NO];
|
||||
}
|
||||
else {
|
||||
[usernamePanelCheck setTransparent:YES];
|
||||
}
|
||||
[usernamePanelCheck setTitle:checkMsg];
|
||||
[usernamePanelPassword setStringValue:passwordText];
|
||||
[usernamePanelUserName setStringValue:userNameText];
|
||||
|
||||
int result = [NSApp runModalForWindow:usernamePanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([usernamePanelCheck state] == NSOnState);
|
||||
|
||||
NSString* value = [usernamePanelUserName stringValue];
|
||||
PRUint32 length = [userNameText length];
|
||||
if (length) {
|
||||
NSRange all;
|
||||
all.location = 0;
|
||||
all.length = [userNameText length];
|
||||
[userNameText deleteCharactersInRange:all];
|
||||
}
|
||||
[userNameText appendString:value];
|
||||
|
||||
value = [usernamePanelPassword stringValue];
|
||||
length = [passwordText length];
|
||||
if (length) {
|
||||
NSRange all;
|
||||
all.location = 0;
|
||||
all.length = [passwordText length];
|
||||
[passwordText deleteCharactersInRange:all];
|
||||
}
|
||||
[passwordText appendString:value];
|
||||
|
||||
[usernamePanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (BOOL)promptPassword:(NSWindow*)parent title:(NSString*)title text:(NSString*)text passwordText:(NSMutableString*)passwordText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck
|
||||
{
|
||||
[passwordPanelText setStringValue:text];
|
||||
[passwordPanel setTitle:title];
|
||||
if (doCheck) {
|
||||
int state = (*checkValue ? NSOnState : NSOffState);
|
||||
[passwordPanelCheck setState:state];
|
||||
[passwordPanelCheck setTransparent:NO];
|
||||
}
|
||||
else {
|
||||
[passwordPanelCheck setTransparent:YES];
|
||||
}
|
||||
[passwordPanelCheck setTitle:checkMsg];
|
||||
[passwordPanelInput setStringValue:passwordText];
|
||||
|
||||
int result = [NSApp runModalForWindow:passwordPanel relativeToWindow:parent];
|
||||
|
||||
*checkValue = ([passwordPanelCheck state] == NSOnState);
|
||||
|
||||
NSString* value = [passwordPanelInput stringValue];
|
||||
PRUint32 length = [passwordText length];
|
||||
if (length) {
|
||||
NSRange all;
|
||||
all.location = 0;
|
||||
all.length = [passwordText length];
|
||||
[passwordText deleteCharactersInRange:all];
|
||||
}
|
||||
[passwordText appendString:value];
|
||||
|
||||
[passwordPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)postToInsecureFromSecure:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:postToInsecureFromSecurePanel relativeToWindow:parent];
|
||||
[postToInsecureFromSecurePanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)badCert:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:securityMismatchPanel relativeToWindow:parent];
|
||||
[securityMismatchPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (BOOL)expiredCert:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:expiredCertPanel relativeToWindow:parent];
|
||||
[expiredCertPanel close];
|
||||
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
|
||||
- (int)unknownCert:(NSWindow*)parent
|
||||
{
|
||||
// this dialog is a little backward, with "Stop" returning 0, and the default returning
|
||||
// 1. That's just how nsIBadCertListener defines its constants. *shrug*
|
||||
int result = [NSApp runModalForWindow:securityUnknownPanel relativeToWindow:parent];
|
||||
[securityUnknownPanel close];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,354 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Calum Robinson <calumr@mac.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "NSView+Utils.h"
|
||||
|
||||
#import "ProgressDlgController.h"
|
||||
|
||||
#import "ProgressViewController.h"
|
||||
#import "PreferenceManager.h"
|
||||
|
||||
static NSString *ProgressWindowFrameSaveName = @"ProgressWindow";
|
||||
|
||||
|
||||
|
||||
@interface ProgressDlgController(PrivateProgressDlgController)
|
||||
|
||||
- (void)resizeWindowToFit;
|
||||
- (void)rebuildViews;
|
||||
- (NSSize)windowSizeForStackSize:(NSSize)stackSize;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation ProgressDlgController
|
||||
|
||||
static id gSharedProgressController = nil;
|
||||
|
||||
+ (ProgressDlgController *)sharedDownloadController;
|
||||
{
|
||||
if (gSharedProgressController == nil)
|
||||
gSharedProgressController = [[ProgressDlgController alloc] init];
|
||||
|
||||
return gSharedProgressController;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self == [super initWithWindowNibName:@"ProgressDialog"]))
|
||||
{
|
||||
// Register for notifications when the stack view changes size
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(stackViewResized:)
|
||||
name:StackViewResizedNotificationName
|
||||
object:nil];
|
||||
|
||||
mProgressViewControllers = [[NSMutableArray alloc] init];
|
||||
|
||||
mDefaultWindowSize = [[self window] frame].size;
|
||||
// it would be nice if we could get the frame from the name, and then
|
||||
// mess with it before setting it.
|
||||
[[self window] setFrameUsingName:ProgressWindowFrameSaveName];
|
||||
// set the window to its default height
|
||||
NSRect windowFrame = [[self window] frame];
|
||||
windowFrame.size.height = mDefaultWindowSize.height;
|
||||
[[self window] setFrame:windowFrame display:NO];
|
||||
|
||||
// We provide the views for the stack view, from mProgressViewControllers
|
||||
[mStackView setDataSource:self];
|
||||
|
||||
[mScrollView setDrawsBackground:NO];
|
||||
[mNoDownloadsText retain]; // so we can remove it from its superview
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (self == gSharedProgressController)
|
||||
gSharedProgressController = nil;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[mProgressViewControllers release];
|
||||
[mNoDownloadsText release];
|
||||
[self killDownloadTimer];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)didStartDownload:(id <CHDownloadProgressDisplay>)progressDisplay
|
||||
{
|
||||
[self showWindow:nil]; // make sure the window is visible
|
||||
|
||||
[self rebuildViews];
|
||||
[self setupDownloadTimer];
|
||||
}
|
||||
|
||||
- (void)didEndDownload:(id <CHDownloadProgressDisplay>)progressDisplay
|
||||
{
|
||||
[self rebuildViews]; // to swap in the completed view
|
||||
}
|
||||
|
||||
- (void)removeDownload:(id <CHDownloadProgressDisplay>)progressDisplay
|
||||
{
|
||||
[mProgressViewControllers removeObject:progressDisplay];
|
||||
|
||||
if ([mProgressViewControllers count] == 0)
|
||||
{
|
||||
// Stop doing stuff if there aren't any downloads going on
|
||||
[self killDownloadTimer];
|
||||
}
|
||||
|
||||
[self rebuildViews];
|
||||
}
|
||||
|
||||
- (void)stackViewResized:(NSNotification *)notification
|
||||
{
|
||||
NSDictionary* userInfo = [notification userInfo];
|
||||
NSSize oldStackSize = [[userInfo objectForKey:@"oldsize"] sizeValue];
|
||||
|
||||
// this code is used to auto-resize the downloads window when
|
||||
// its contents change size, if the window is in its standard, "zoomed"
|
||||
// state. This allows the user to choose between auto-resizing behavior,
|
||||
// by leaving the window alone, or their own size, by resizing it.
|
||||
|
||||
// get the size the window would have been if it had been in the
|
||||
// standard state, given the old size of the contents
|
||||
NSSize oldZoomedWindowSize = [self windowSizeForStackSize:oldStackSize];
|
||||
NSSize curWindowSize = [[self window] frame].size;
|
||||
|
||||
// only resize if the window matches the stack size
|
||||
if (CHCloseSizes(oldZoomedWindowSize, curWindowSize, 4.0))
|
||||
[self resizeWindowToFit];
|
||||
}
|
||||
|
||||
// given the dimensions of our stack view, return the dimensions of the window,
|
||||
// assuming the window is zoomed to show as much of the contents as possible.
|
||||
- (NSSize)windowSizeForStackSize:(NSSize)stackSize
|
||||
{
|
||||
NSSize actualScrollFrame = [mScrollView frame].size;
|
||||
NSSize scrollFrameSize = [NSScrollView frameSizeForContentSize:stackSize
|
||||
hasHorizontalScroller:NO hasVerticalScroller:YES borderType:NSNoBorder];
|
||||
|
||||
// frameSizeForContentSize seems to return a width 1 pixel too narrow
|
||||
scrollFrameSize.width += 1;
|
||||
|
||||
NSRect contentRect = [[[self window] contentView] frame];
|
||||
contentRect.size.width += scrollFrameSize.width - actualScrollFrame.width;
|
||||
contentRect.size.height += scrollFrameSize.height - actualScrollFrame.height;
|
||||
contentRect.origin = [[self window] convertBaseToScreen:contentRect.origin]; // convert to screen
|
||||
|
||||
NSRect advisoryWindowFrame = [NSWindow frameRectForContentRect:contentRect styleMask:[[self window] styleMask]];
|
||||
NSRect constrainedRect = [[self window] constrainFrameRect:advisoryWindowFrame toScreen:[[self window] screen]];
|
||||
return constrainedRect.size;
|
||||
}
|
||||
|
||||
- (void)resizeWindowToFit
|
||||
{
|
||||
if ([mProgressViewControllers count] > 0)
|
||||
{
|
||||
NSSize scrollFrameSize = [NSScrollView frameSizeForContentSize:[mStackView bounds].size
|
||||
hasHorizontalScroller:NO hasVerticalScroller:YES borderType:NSNoBorder];
|
||||
NSSize curScrollFrameSize = [mScrollView frame].size;
|
||||
|
||||
NSRect windowFrame = [[self window] frame];
|
||||
|
||||
float frameDelta = (scrollFrameSize.height - curScrollFrameSize.height);
|
||||
windowFrame.size.height += frameDelta;
|
||||
windowFrame.origin.y -= frameDelta; // maintain top
|
||||
|
||||
[[self window] setFrame:windowFrame display:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)rebuildViews
|
||||
{
|
||||
[mStackView reloadSubviews];
|
||||
|
||||
if ([mProgressViewControllers count] == 0)
|
||||
{
|
||||
[[[self window] contentView] addSubview:mNoDownloadsText];
|
||||
}
|
||||
else
|
||||
{
|
||||
[mNoDownloadsText removeFromSuperview];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (int)numDownloadsInProgress
|
||||
{
|
||||
unsigned int numViews = [mProgressViewControllers count];
|
||||
int numActive = 0;
|
||||
|
||||
for (unsigned int i = 0; i < numViews; i++)
|
||||
{
|
||||
if ([[mProgressViewControllers objectAtIndex:i] isActive])
|
||||
++numActive;
|
||||
}
|
||||
return numActive;
|
||||
}
|
||||
|
||||
-(void)autosaveWindowFrame
|
||||
{
|
||||
[[self window] saveFrameUsingName:ProgressWindowFrameSaveName];
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
[self autosaveWindowFrame];
|
||||
}
|
||||
|
||||
- (void)killDownloadTimer
|
||||
{
|
||||
if (mDownloadTimer)
|
||||
{
|
||||
[mDownloadTimer invalidate];
|
||||
[mDownloadTimer release];
|
||||
mDownloadTimer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupDownloadTimer
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
|
||||
mDownloadTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0
|
||||
target:self
|
||||
selector:@selector(setDownloadProgress:)
|
||||
userInfo:nil
|
||||
repeats:YES] retain];
|
||||
}
|
||||
|
||||
// Called by our timer to refresh all the download stats
|
||||
- (void)setDownloadProgress:(NSTimer *)aTimer
|
||||
{
|
||||
[mProgressViewControllers makeObjectsPerformSelector:@selector(refreshDownloadInfo)];
|
||||
// if the window is minimized, we want to update the dock image here. But how?
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)allowTerminate
|
||||
{
|
||||
if ([self numDownloadsInProgress] > 0)
|
||||
{
|
||||
// make sure the window is visible
|
||||
[self showWindow:self];
|
||||
|
||||
NSString *alert = NSLocalizedString(@"QuitWithDownloadsMsg", @"Really Quit?");
|
||||
NSString *message = NSLocalizedString(@"QuitWithDownloadsExpl", @"");
|
||||
NSString *okButton = NSLocalizedString(@"QuitWithdownloadsButtonDefault",@"Cancel");
|
||||
NSString *altButton = NSLocalizedString(@"QuitWithdownloadsButtonAlt",@"Quit");
|
||||
|
||||
// while the panel is up, download dialogs won't update (no timers firing) but
|
||||
// downloads continue (PLEvents being processed)
|
||||
id panel = NSGetAlertPanel(alert, message, okButton, altButton, nil, message);
|
||||
|
||||
[NSApp beginSheet:panel
|
||||
modalForWindow:[self window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:NULL];
|
||||
int sheetResult = [NSApp runModalForWindow: panel];
|
||||
[NSApp endSheet: panel];
|
||||
[panel orderOut: self];
|
||||
NSReleaseAlertPanel(panel);
|
||||
|
||||
return (sheetResult == NSAlertDefaultReturn) ? NSTerminateCancel : NSTerminateNow;
|
||||
}
|
||||
|
||||
return NSTerminateNow;
|
||||
}
|
||||
|
||||
- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
|
||||
{
|
||||
[NSApp stopModalWithCode:returnCode];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// implement to zoom to a size that just fits the contents
|
||||
- (NSRect)windowWillUseStandardFrame:(NSWindow *)sender defaultFrame:(NSRect)defaultFrame
|
||||
{
|
||||
NSSize scrollFrameSize = [NSScrollView frameSizeForContentSize:[mStackView bounds].size
|
||||
hasHorizontalScroller:NO hasVerticalScroller:YES borderType:NSNoBorder];
|
||||
|
||||
NSSize curScrollFrameSize = [mScrollView frame].size;
|
||||
float frameDelta = (scrollFrameSize.height - curScrollFrameSize.height);
|
||||
|
||||
NSRect windowFrame = [[self window] frame];
|
||||
windowFrame.size.height += frameDelta;
|
||||
windowFrame.origin.y -= frameDelta; // maintain top
|
||||
|
||||
windowFrame.size.width = mDefaultWindowSize.width;
|
||||
// cocoa will ensure that the window fits onscreen for us
|
||||
return windowFrame;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*
|
||||
CHStackView datasource methods
|
||||
*/
|
||||
|
||||
- (int)subviewsForStackView:(CHStackView *)stackView
|
||||
{
|
||||
return [mProgressViewControllers count];
|
||||
}
|
||||
|
||||
- (NSView *)viewForStackView:(CHStackView *)aResizingView atIndex:(int)index
|
||||
{
|
||||
return [[mProgressViewControllers objectAtIndex:index] view];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*
|
||||
Just create a progress view, but don't display it (otherwise the URL fields etc.
|
||||
are just blank)
|
||||
*/
|
||||
- (id <CHDownloadProgressDisplay>)createProgressDisplay
|
||||
{
|
||||
ProgressViewController *newController = [[ProgressViewController alloc] init];
|
||||
[newController setProgressWindowController:self];
|
||||
[mProgressViewControllers addObject:newController];
|
||||
|
||||
return newController;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,544 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Calum Robinson <calumr@mac.com>
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
#import "NSView+Utils.h"
|
||||
|
||||
#import "ProgressViewController.h"
|
||||
#import "ProgressDlgController.h"
|
||||
#import "PreferenceManager.h"
|
||||
|
||||
enum
|
||||
{
|
||||
kLabelTagFilename = 1000,
|
||||
kLabelTagProgress,
|
||||
kLabelTagSource,
|
||||
kLabelTagDestination,
|
||||
kLabelTagTimeRemaining,
|
||||
kLabelTagStatus, // 1005
|
||||
kLabelTagTimeRemainingLabel
|
||||
};
|
||||
|
||||
|
||||
// Notification sent when user holds option key and expands/contracts a progress view
|
||||
static NSString *ProgressViewsShouldResize = @"ProgressViewsShouldResize";
|
||||
|
||||
@interface ProgressViewController(ProgressViewControllerPrivate)
|
||||
|
||||
- (void)viewDidLoad;
|
||||
- (void)refreshDownloadInfo;
|
||||
- (void)moveProgressBarToCurrentView;
|
||||
- (void)updateButtons;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ProgressViewController
|
||||
|
||||
+ (NSString *)formatTime:(int)seconds
|
||||
{
|
||||
NSMutableString *theTime = [NSMutableString stringWithCapacity:8];
|
||||
|
||||
NSString *padZero = [NSString stringWithString:@"0"];
|
||||
//write out new elapsed time
|
||||
if (seconds >= 3600)
|
||||
{
|
||||
[theTime appendFormat:@"%d:",(seconds / 3600)];
|
||||
seconds = seconds % 3600;
|
||||
}
|
||||
|
||||
NSString *elapsedMin = [NSString stringWithFormat:@"%d:",(seconds / 60)];
|
||||
if ([elapsedMin length] == 2)
|
||||
[theTime appendString:[padZero stringByAppendingString:elapsedMin]];
|
||||
else
|
||||
[theTime appendString:elapsedMin];
|
||||
|
||||
seconds = seconds % 60;
|
||||
NSString *elapsedSec = [NSString stringWithFormat:@"%d",seconds];
|
||||
|
||||
if ([elapsedSec length] == 2)
|
||||
[theTime appendString:elapsedSec];
|
||||
else
|
||||
[theTime appendString:[padZero stringByAppendingString:elapsedSec]];
|
||||
|
||||
return theTime;
|
||||
}
|
||||
|
||||
// fuzzy time gives back strings like "about 5 seconds"
|
||||
+ (NSString *)formatFuzzyTime:(int)seconds
|
||||
{
|
||||
// check for seconds first
|
||||
if (seconds < 60) {
|
||||
if (seconds < 7)
|
||||
return [NSString stringWithFormat:NSLocalizedString(@"UnderSec", @"Under %d seconds"), 5];
|
||||
if (seconds < 13)
|
||||
return [NSString stringWithFormat:NSLocalizedString(@"UnderSec", @"Under %d seconds"), 10];
|
||||
return [NSString stringWithFormat:NSLocalizedString(@"UnderMin", @"Under a minute")];
|
||||
}
|
||||
// seconds becomes minutes and we keep checking.
|
||||
seconds = seconds/60;
|
||||
if (seconds < 60) {
|
||||
if (seconds < 2)
|
||||
return [NSString stringWithFormat:NSLocalizedString(@"AboutMin",@"About a minute")];
|
||||
// OK, tell the good people how much time we have left.
|
||||
return [NSString stringWithFormat:NSLocalizedString(@"AboutMins",@"About %d minutes"), seconds];
|
||||
}
|
||||
//this download will never seemingly never end. now seconds become hours.
|
||||
seconds = seconds/60;
|
||||
if (seconds < 2)
|
||||
return [NSString stringWithFormat:NSLocalizedString(@"AboutHour", @"Over an hour")];
|
||||
return [NSString stringWithFormat:NSLocalizedString(@"AboutHours", @"Over %d hours"), seconds];
|
||||
}
|
||||
|
||||
+ (NSString *)formatBytes:(float)bytes
|
||||
{
|
||||
// if bytes are negative, we return question marks.
|
||||
if (bytes < 0)
|
||||
return [NSString stringWithString:@"?"];
|
||||
// bytes first.
|
||||
if (bytes < 1024)
|
||||
return [NSString stringWithFormat:@"%.1f bytes",bytes];
|
||||
// kb
|
||||
bytes = bytes/1024;
|
||||
if (bytes < 1024)
|
||||
return [NSString stringWithFormat:@"%.1f KB",bytes];
|
||||
// mb
|
||||
bytes = bytes/1024;
|
||||
if (bytes < 1024)
|
||||
return [NSString stringWithFormat:@"%.1f MB",bytes];
|
||||
// gb
|
||||
bytes = bytes/1024;
|
||||
return [NSString stringWithFormat:@"%.1f GB",bytes];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
[NSBundle loadNibNamed:@"ProgressView" owner:self];
|
||||
|
||||
[self viewDidLoad];
|
||||
|
||||
// Register for notifications when one of the progress views is expanded/contracted
|
||||
// whilst holding the option button
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(changeCollapsedStateNotification:)
|
||||
name:ProgressViewsShouldResize
|
||||
object:nil];
|
||||
|
||||
[mExpandedRevealButton setEnabled:NO];
|
||||
[mExpandedOpenButton setEnabled:NO];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:ProgressViewsShouldResize
|
||||
object:nil];
|
||||
|
||||
// if we get here because we're quitting, the listener will still be alive
|
||||
// yet we're going away. As a result, we need to tell the d/l listener to
|
||||
// forget it ever met us and necko will clean it up on its own.
|
||||
if (mDownloader)
|
||||
mDownloader->DetachDownloadDisplay();
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
|
||||
[mStartTime release];
|
||||
[mSourceURL release];
|
||||
[mDestPath release];
|
||||
[mProgressBar release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// Save the expand/contract view pref (called when the user clicks the dislosure triangle)
|
||||
- (void)setCompactViewPref
|
||||
{
|
||||
[[PreferenceManager sharedInstance] setPref:"browser.download.compactView" toBoolean:mViewIsCompact];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
mViewIsCompact = [[PreferenceManager sharedInstance] getBooleanPref:"browser.download.compactView" withSuccess:NULL];
|
||||
[mProgressBar retain]; // make sure it survives being moved between views
|
||||
|
||||
if (mViewIsCompact)
|
||||
[self moveProgressBarToCurrentView];
|
||||
|
||||
// this isn't necessarily better. Need to profile.
|
||||
[mProgressBar setUsesThreadedAnimation:YES];
|
||||
}
|
||||
|
||||
- (NSView *)view
|
||||
{
|
||||
if (mViewIsCompact)
|
||||
return (mDownloadDone ? mCompletedViewCompact : mProgressViewCompact);
|
||||
else
|
||||
return (mDownloadDone ? mCompletedView : mProgressView);
|
||||
}
|
||||
|
||||
- (IBAction)toggleDisclosure:(id)sender
|
||||
{
|
||||
mViewIsCompact = !mViewIsCompact;
|
||||
|
||||
[self moveProgressBarToCurrentView];
|
||||
|
||||
// Is option/alt held down?
|
||||
if ([[[sender window] currentEvent] modifierFlags] & NSAlternateKeyMask)
|
||||
{
|
||||
// Get all progress views to look the same as self
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:ProgressViewsShouldResize
|
||||
object:[NSNumber numberWithBool:mViewIsCompact]];
|
||||
}
|
||||
|
||||
// Set the pref only when the user clicks the disclosure triangle
|
||||
[self setCompactViewPref];
|
||||
|
||||
// Re-calculate the new view & window sizes
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:StackViewReloadNotificationName
|
||||
object:self];
|
||||
[self refreshDownloadInfo];
|
||||
}
|
||||
|
||||
- (void)changeCollapsedStateNotification:(NSNotification *)notification
|
||||
{
|
||||
// note that this will get called on the view that is being clicked, as well
|
||||
// as the other views. Don't do redundant work here, like redrawing.
|
||||
mViewIsCompact = [[notification object] boolValue];
|
||||
// Don't call [enclosingStackView reloadSubviews]; here, because it will be done
|
||||
// by the original view that was option-clicked, not us
|
||||
}
|
||||
|
||||
-(void)cancel
|
||||
{
|
||||
mUserCancelled = YES;
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->CancelDownload();
|
||||
|
||||
// clean up downloaded file. - do it here or in CancelDownload?
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
if ([fileManager isDeletableFileAtPath:mDestPath])
|
||||
{
|
||||
// if we delete it, fantastic. if not, oh well. better to move to trash instead?
|
||||
[fileManager removeFileAtPath:mDestPath handler:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)close:(id)sender
|
||||
{
|
||||
if (!mDownloadDone)
|
||||
{
|
||||
mRemoveWhenDone = YES;
|
||||
[self cancel];
|
||||
}
|
||||
else
|
||||
{
|
||||
[mProgressWindowController removeDownload:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)stop:(id)sender
|
||||
{
|
||||
[self cancel];
|
||||
}
|
||||
|
||||
- (IBAction)reveal:(id)sender
|
||||
{
|
||||
if ([[NSWorkspace sharedWorkspace] selectFile:mDestPath
|
||||
inFileViewerRootedAtPath:[mDestPath stringByDeletingLastPathComponent]])
|
||||
return;
|
||||
// hmmm. it didn't work. that's odd. need localized error messages. for now, just beep.
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
- (IBAction)open:(id)sender
|
||||
{
|
||||
if ([[NSWorkspace sharedWorkspace] openFile:mDestPath])
|
||||
return;
|
||||
// hmmm. it didn't work. that's odd. need localized error message. for now, just beep.
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
// Called just before the view will be shown to the user
|
||||
- (void)downloadDidStart
|
||||
{
|
||||
mStartTime = [[NSDate alloc] init];
|
||||
// [mProgressBar startAnimation:self]; // moved to onStartDownload
|
||||
[self refreshDownloadInfo];
|
||||
}
|
||||
|
||||
- (void)downloadDidEnd
|
||||
{
|
||||
mDownloadDone = YES;
|
||||
mDownloadTime = -[mStartTime timeIntervalSinceNow];
|
||||
[mProgressBar stopAnimation:self];
|
||||
|
||||
[mExpandedCancelButton setEnabled:NO];
|
||||
[self refreshDownloadInfo];
|
||||
}
|
||||
|
||||
// this handles lots of things.
|
||||
- (void)refreshDownloadInfo
|
||||
{
|
||||
NSView* curView = [self view];
|
||||
|
||||
NSString* filename = [mSourceURL lastPathComponent];
|
||||
NSString *destPath = [mDestPath stringByAbbreviatingWithTildeInPath];
|
||||
NSString* tooltipFormat = NSLocalizedString(mDownloadDone ? @"DownloadedTooltipFormat" : @"DownloadingTooltipFormat", @"");
|
||||
|
||||
id filenameLabel = [curView viewWithTag:kLabelTagFilename];
|
||||
[filenameLabel setStringValue:filename];
|
||||
[filenameLabel setToolTip:[NSString stringWithFormat:tooltipFormat, [mSourceURL lastPathComponent], mSourceURL, destPath]];
|
||||
|
||||
id destLabel = [curView viewWithTag:kLabelTagDestination];
|
||||
[destLabel setStringValue:destPath];
|
||||
|
||||
id locationLabel = [curView viewWithTag:kLabelTagSource];
|
||||
[locationLabel setStringValue:mSourceURL];
|
||||
|
||||
if (mDownloadDone)
|
||||
{
|
||||
id statusLabel = [curView viewWithTag:kLabelTagStatus];
|
||||
if (statusLabel)
|
||||
{
|
||||
NSString* statusString;
|
||||
if (mUserCancelled)
|
||||
statusString = NSLocalizedString(@"DownloadCancelled", @"Cancelled");
|
||||
else if (mDownloadingError)
|
||||
statusString = NSLocalizedString(@"DownloadInterrupted", @"Interrupted");
|
||||
else
|
||||
statusString = NSLocalizedString(@"DownloadCompleted", @"Completed");
|
||||
|
||||
[statusLabel setStringValue: statusString];
|
||||
}
|
||||
|
||||
// set progress label
|
||||
id progressLabel = [curView viewWithTag:kLabelTagProgress];
|
||||
if (progressLabel)
|
||||
{
|
||||
float byteSec = mCurrentProgress / mDownloadTime;
|
||||
// show how much we downloaded, become some types of disconnects make us think
|
||||
// we finished successfully
|
||||
[progressLabel setStringValue:[NSString stringWithFormat:
|
||||
NSLocalizedString(@"DownloadDoneStatusString", @"%@ of %@ done (at %@/sec)"),
|
||||
[[self class] formatBytes:mCurrentProgress],
|
||||
[[self class] formatBytes:mDownloadSize],
|
||||
[[self class] formatBytes:byteSec]]];
|
||||
}
|
||||
|
||||
id timeLabel = [curView viewWithTag:kLabelTagTimeRemaining];
|
||||
if (timeLabel)
|
||||
[timeLabel setStringValue:[[self class] formatTime:(int)mDownloadTime]];
|
||||
|
||||
id timeLabelLabel = [curView viewWithTag:kLabelTagTimeRemainingLabel];
|
||||
if (timeLabelLabel)
|
||||
[timeLabelLabel setStringValue:NSLocalizedString(@"DownloadRemainingLabelDone", @"Time elapsed:")];
|
||||
|
||||
[self updateButtons];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSTimeInterval elapsedTime = -[mStartTime timeIntervalSinceNow];
|
||||
|
||||
// update status field
|
||||
id progressLabel = [curView viewWithTag:kLabelTagProgress];
|
||||
if (progressLabel)
|
||||
{
|
||||
NSString *statusLabelString = NSLocalizedString(@"DownloadStatusString", @"%@ of %@ total (at %@/sec)");
|
||||
float byteSec = mCurrentProgress / elapsedTime;
|
||||
[progressLabel setStringValue:[NSString stringWithFormat:statusLabelString,
|
||||
[[self class] formatBytes:mCurrentProgress],
|
||||
(mDownloadSize > 0 ? [[self class] formatBytes:mDownloadSize] : @"?"),
|
||||
[[self class] formatBytes:byteSec]]];
|
||||
}
|
||||
|
||||
id timeLabel = [curView viewWithTag:kLabelTagTimeRemaining];
|
||||
if (timeLabel)
|
||||
{
|
||||
if (mDownloadSize > 0)
|
||||
{
|
||||
int secToGo = (int)ceil((elapsedTime * mDownloadSize / mCurrentProgress) - elapsedTime);
|
||||
[timeLabel setStringValue:[[self class] formatFuzzyTime:secToGo]];
|
||||
}
|
||||
else // mDownloadSize is undetermined. Set remaining time to question marks.
|
||||
{
|
||||
NSString *calculatingString = NSLocalizedString(@"DownloadCalculatingString", @"Unknown");
|
||||
[timeLabel setStringValue:calculatingString];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateButtons
|
||||
{
|
||||
// note: this will stat every time, which will be expensive! We could use
|
||||
// FNNotify/FNSubscribe to avoid this (writing a Cocoa wrapper around it).
|
||||
if (mDownloadDone && !mDownloadingError)
|
||||
{
|
||||
BOOL destFileExists = [[NSFileManager defaultManager] fileExistsAtPath:mDestPath];
|
||||
[mExpandedRevealButton setEnabled:destFileExists];
|
||||
[mExpandedOpenButton setEnabled:destFileExists];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)moveProgressBarToCurrentView
|
||||
{
|
||||
[mProgressBar moveToView:(mViewIsCompact ? mProgressViewCompact : mProgressView) resize:YES];
|
||||
[mProgressBar startAnimation:self]; // this is necessary to keep it animating for some reason
|
||||
}
|
||||
|
||||
- (void)setProgressWindowController:(ProgressDlgController*)progressWindowController
|
||||
{
|
||||
mProgressWindowController = progressWindowController;
|
||||
}
|
||||
|
||||
- (BOOL)isActive
|
||||
{
|
||||
return !mDownloadDone;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)onStartDownload:(BOOL)isFileSave
|
||||
{
|
||||
mIsFileSave = isFileSave;
|
||||
[self downloadDidStart];
|
||||
[mProgressWindowController didStartDownload:self];
|
||||
|
||||
// need to do this after the view as been put in the window, otherwise it doesn't work
|
||||
[mProgressBar startAnimation:self];
|
||||
}
|
||||
|
||||
- (void)onEndDownload:(BOOL)completedOK
|
||||
{
|
||||
mDownloadingError = !completedOK;
|
||||
|
||||
[self downloadDidEnd];
|
||||
[mProgressWindowController didEndDownload:self];
|
||||
if (mRemoveWhenDone)
|
||||
[mProgressWindowController removeDownload:self];
|
||||
}
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress
|
||||
{
|
||||
mCurrentProgress = aCurProgress; // fall back for stat calcs
|
||||
mDownloadSize = aMaxProgress;
|
||||
|
||||
if (![mProgressBar isIndeterminate]) //most likely - just update value
|
||||
{
|
||||
if (aCurProgress == aMaxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
}
|
||||
else if (aMaxProgress > 0) // ok, we're starting up with good max & cur values
|
||||
{
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void)setDownloadListener:(CHDownloader*)aDownloader
|
||||
{
|
||||
if (mDownloader != aDownloader)
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
|
||||
NS_IF_ADDREF(mDownloader = aDownloader);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
This is kind of a hack. It should probably be done somewhere else so Mozilla can have
|
||||
it too, but until Apple fixes the problems with the setting of comments without
|
||||
reverting to Applescript, I have left it in.
|
||||
|
||||
Turned off for now, until we find a better way to do this. Won't Carbon APIs work?
|
||||
*/
|
||||
- (void)tryToSetFinderComments
|
||||
{
|
||||
if (mDestPath && mSourceURL)
|
||||
{
|
||||
CFURLRef fileURL = CFURLCreateWithFileSystemPath( NULL,
|
||||
(CFStringRef)mDestPath,
|
||||
kCFURLPOSIXPathStyle,
|
||||
NO);
|
||||
|
||||
NSString *hfsPath = (NSString *)CFURLCopyFileSystemPath(fileURL,
|
||||
kCFURLHFSPathStyle);
|
||||
|
||||
CFRelease(fileURL);
|
||||
|
||||
NSAppleScript *setCommentScript = [[NSAppleScript alloc] initWithSource:
|
||||
[NSString stringWithFormat:@"tell application \"Finder\" to set comment of file \"%@\" to \"%@\"", hfsPath, mSourceURL]];
|
||||
NSDictionary *errorInfo = NULL;
|
||||
|
||||
[setCommentScript executeAndReturnError:&errorInfo];
|
||||
|
||||
if (errorInfo)
|
||||
{
|
||||
NSLog(@"Get error when running AppleScript to set comments for '%@':\n %@",
|
||||
mDestPath,
|
||||
[errorInfo objectForKey:NSAppleScriptErrorMessage]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)setSourceURL:(NSString*)aSourceURL
|
||||
{
|
||||
[mSourceURL autorelease];
|
||||
mSourceURL = [aSourceURL copy];
|
||||
|
||||
//[self tryToSetFinderComments];
|
||||
}
|
||||
|
||||
- (void)setDestinationPath:(NSString*)aDestPath
|
||||
{
|
||||
[mDestPath autorelease];
|
||||
mDestPath = [aDestPath copy];
|
||||
//[self tryToSetFinderComments];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,394 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* David Hyatt <hyatt@netscape.com>
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
#import "ChimeraUIConstants.h"
|
||||
|
||||
#include "SaveHeaderSniffer.h"
|
||||
|
||||
#include "netCore.h"
|
||||
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIMIMEInfo.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDownload.h"
|
||||
|
||||
const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
|
||||
|
||||
nsHeaderSniffer::nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsAString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView)
|
||||
: mPersist(aPersist)
|
||||
, mTmpFile(aFile)
|
||||
, mURL(aURL)
|
||||
, mDocument(aDocument)
|
||||
, mPostData(aPostData)
|
||||
, mDefaultFilename(aSuggestedFilename)
|
||||
, mBypassCache(aBypassCache)
|
||||
, mFilterView(aFilterView)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsHeaderSniffer::~nsHeaderSniffer()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_START)
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowserPersist> kungFuDeathGrip(mPersist); // be sure to keep it alive while we save
|
||||
// since it owns us as a listener
|
||||
nsCOMPtr<nsIWebProgressListener> kungFuSuicideGrip(this); // and keep ourslves alive
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest, &rv);
|
||||
if (!channel) return rv;
|
||||
channel->GetContentType(mContentType);
|
||||
|
||||
nsCOMPtr<nsIURI> origURI;
|
||||
channel->GetOriginalURI(getter_AddRefs(origURI));
|
||||
|
||||
// Get the content-disposition if we're an HTTP channel.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel)
|
||||
httpChannel->GetResponseHeader(nsCAutoString("content-disposition"), mContentDisposition);
|
||||
|
||||
mPersist->CancelSave();
|
||||
PRBool exists;
|
||||
mTmpFile->Exists(&exists);
|
||||
if (exists)
|
||||
mTmpFile->Remove(PR_FALSE);
|
||||
|
||||
rv = PerformSave(origURI);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
// put up some UI
|
||||
NSLog(@"Error saving web page");
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
nsresult nsHeaderSniffer::PerformSave(nsIURI* inOriginalURI)
|
||||
{
|
||||
nsresult rv;
|
||||
// Are we an HTML document? If so, we will want to append an accessory view to
|
||||
// the save dialog to provide the user with the option of doing a complete
|
||||
// save vs. a single file save.
|
||||
#if 0
|
||||
// The MOZILLA_1_0_BRANCH source Chimera is currently based on can't handle saving an XML
|
||||
// document other than as source so only offer the format popup if it's a text/html content.
|
||||
// Leaving this code here #ifdef'd out for when we get to a more recent
|
||||
// version of the Mozilla source tree.
|
||||
PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
|
||||
mContentType.Equals("text/html") ||
|
||||
mContentType.Equals("application/xhtml+xml"));
|
||||
#endif
|
||||
PRBool isHTML = (mDocument && mContentType.Equals("text/html"));
|
||||
|
||||
// Next find out the directory that we should start in.
|
||||
nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1", &rv));
|
||||
if (!prefs)
|
||||
return rv;
|
||||
nsCOMPtr<nsIPrefBranch> dirBranch;
|
||||
prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
|
||||
PRInt32 filterIndex = eSaveFormatHTMLComplete;
|
||||
if (dirBranch) {
|
||||
nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
|
||||
if (NS_FAILED(rv))
|
||||
filterIndex = eSaveFormatHTMLComplete;
|
||||
}
|
||||
|
||||
NSPopUpButton* filterList = [mFilterView viewWithTag:kSaveFormatPopupTag];
|
||||
if (filterList)
|
||||
[filterList selectItemAtIndex: filterIndex];
|
||||
|
||||
// We need to figure out what file name to use.
|
||||
nsAutoString defaultFileName;
|
||||
if (!mContentDisposition.IsEmpty()) {
|
||||
// (1) Use the HTTP header suggestion.
|
||||
PRInt32 index = mContentDisposition.Find("filename=");
|
||||
if (index >= 0) {
|
||||
// Take the substring following the prefix.
|
||||
index += 9;
|
||||
nsCAutoString filename;
|
||||
mContentDisposition.Right(filename, mContentDisposition.Length() - index);
|
||||
defaultFileName = NS_ConvertUTF8toUCS2(filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
|
||||
if (url)
|
||||
{
|
||||
nsCAutoString urlFileName;
|
||||
url->GetFileName(urlFileName); // (2) For file URLs, use the file name.
|
||||
defaultFileName = NS_ConvertUTF8toUCS2(urlFileName);
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mDocument && isHTML) {
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
||||
nsAutoString title;
|
||||
if (htmlDoc)
|
||||
htmlDoc->GetTitle(title); // (3) Use the title of the document.
|
||||
defaultFileName = title;
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
// (4) Use the caller provided name.
|
||||
defaultFileName = mDefaultFilename;
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mURL) {
|
||||
// (5) Use the host.
|
||||
nsCAutoString hostName;
|
||||
mURL->GetHost(hostName);
|
||||
defaultFileName = NS_ConvertUTF8toUCS2(hostName);
|
||||
}
|
||||
|
||||
// One last case to handle about:blank and other fruity untitled pages.
|
||||
if (defaultFileName.IsEmpty())
|
||||
defaultFileName = NS_LITERAL_STRING("untitled"); // XXX localize
|
||||
|
||||
// Validate the file name to ensure legality.
|
||||
for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
|
||||
if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
|
||||
defaultFileName.SetCharAt(' ', i);
|
||||
|
||||
// Make sure the appropriate extension is appended to the suggested file name.
|
||||
nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
|
||||
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI, &rv));
|
||||
if (!fileURL)
|
||||
return rv;
|
||||
fileURL->SetFilePath(NS_ConvertUCS2toUTF8(defaultFileName));
|
||||
|
||||
nsCAutoString fileExtension;
|
||||
fileURL->GetFileExtension(fileExtension);
|
||||
|
||||
PRBool setExtension = PR_FALSE;
|
||||
if (mContentType.Equals("text/html")) {
|
||||
if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
|
||||
defaultFileName.AppendWithConversion(".html");
|
||||
setExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setExtension && fileExtension.IsEmpty()) {
|
||||
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv));
|
||||
if (!mimeService)
|
||||
return rv;
|
||||
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
||||
rv = mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
|
||||
if (!mimeInfo)
|
||||
return rv;
|
||||
|
||||
PRUint32 extCount = 0;
|
||||
char** extList = nsnull;
|
||||
mimeInfo->GetFileExtensions(&extCount, &extList);
|
||||
if (extCount > 0 && extList) {
|
||||
defaultFileName += PRUnichar('.');
|
||||
defaultFileName.AppendWithConversion(extList[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Now it's time to pose the save dialog.
|
||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||
NSString* file = nil;
|
||||
if (!defaultFileName.IsEmpty())
|
||||
file = [NSString stringWith_nsAString:defaultFileName];
|
||||
|
||||
if (isHTML)
|
||||
[savePanel setAccessoryView: mFilterView];
|
||||
|
||||
if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
|
||||
return NS_OK;
|
||||
|
||||
// Update the filter index.
|
||||
if (isHTML && filterList) {
|
||||
filterIndex = [filterList indexOfSelectedItem];
|
||||
dirBranch->SetIntPref("save_converter_index", filterIndex);
|
||||
}
|
||||
|
||||
// Convert the content type to text/plain if it was selected in the filter.
|
||||
if (isHTML && filterIndex == eSaveFormatPlainText)
|
||||
mContentType = "text/plain";
|
||||
|
||||
nsCOMPtr<nsISupports> sourceData;
|
||||
if (isHTML && filterIndex != eSaveFormatHTMLSource)
|
||||
sourceData = do_QueryInterface(mDocument);
|
||||
else
|
||||
sourceData = do_QueryInterface(mURL);
|
||||
|
||||
nsAutoString dstString;
|
||||
[[savePanel filename] assignTo_nsAString:dstString];
|
||||
|
||||
return InitiateDownload(sourceData, dstString, inOriginalURI);
|
||||
}
|
||||
|
||||
// inOriginalURI is always a URI. inSourceData can be an nsIURI or an nsIDOMDocument, depending
|
||||
// on what we're saving. It's that way for nsIWebBrowserPersist.
|
||||
nsresult nsHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsString& inFileName, nsIURI* inOriginalURI)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> webPersist = do_CreateInstance(persistContractID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIURI> sourceURI = do_QueryInterface(inSourceData);
|
||||
|
||||
nsCOMPtr<nsILocalFile> destFile;
|
||||
rv = NS_NewLocalFile(inFileName, PR_FALSE, getter_AddRefs(destFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRInt64 timeNow = PR_Now();
|
||||
|
||||
nsCOMPtr<nsIDownload> downloader = do_CreateInstance(NS_DOWNLOAD_CONTRACTID);
|
||||
// dlListener attaches to its progress dialog here, which gains ownership
|
||||
rv = downloader->Init(inOriginalURI, destFile, inFileName.get(), nsnull, timeNow, webPersist);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
webPersist->SetPersistFlags(flags);
|
||||
|
||||
if (sourceURI)
|
||||
{ // Tell web persist we want no decoding on this data
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION;
|
||||
webPersist->SetPersistFlags(flags);
|
||||
rv = webPersist->SaveURI(sourceURI, mPostData, destFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIDOMHTMLDocument> domDoc = do_QueryInterface(inSourceData, &rv);
|
||||
if (!domDoc) return rv; // should never happen
|
||||
|
||||
PRInt32 encodingFlags = 0;
|
||||
nsCOMPtr<nsILocalFile> filesFolder;
|
||||
|
||||
if (!mContentType.Equals("text/plain")) {
|
||||
// Create a local directory in the same dir as our file. It
|
||||
// will hold our associated files.
|
||||
filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
nsAutoString unicodePath;
|
||||
destFile->GetPath(unicodePath);
|
||||
filesFolder->InitWithPath(unicodePath);
|
||||
|
||||
nsAutoString leafName;
|
||||
filesFolder->GetLeafName(leafName);
|
||||
nsAutoString nameMinusExt(leafName);
|
||||
PRInt32 index = nameMinusExt.RFind(".");
|
||||
if (index >= 0)
|
||||
nameMinusExt.Left(nameMinusExt, index);
|
||||
nameMinusExt += NS_LITERAL_STRING(" Files"); // XXXdwh needs to be localizable!
|
||||
filesFolder->SetLeafName(nameMinusExt);
|
||||
PRBool exists = PR_FALSE;
|
||||
filesFolder->Exists(&exists);
|
||||
if (!exists) {
|
||||
rv = filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
|
||||
}
|
||||
rv = webPersist->SaveDocument(domDoc, destFile, filesFolder, mContentType.get(), encodingFlags, 80);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
|
@ -1,389 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
* Calum Robinson <calumr@mac.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIURL.h"
|
||||
#include "netCore.h"
|
||||
|
||||
nsDownloadListener::nsDownloadListener()
|
||||
: mDownloadStatus(NS_OK)
|
||||
, mBypassCache(PR_FALSE)
|
||||
, mNetworkTransfer(PR_FALSE)
|
||||
, mGotFirstStateChange(PR_FALSE)
|
||||
, mUserCanceled(PR_FALSE)
|
||||
, mSentCancel(PR_FALSE)
|
||||
{
|
||||
mStartTime = LL_ZERO;
|
||||
}
|
||||
|
||||
nsDownloadListener::~nsDownloadListener()
|
||||
{
|
||||
// if we go away before the timer fires, cancel it
|
||||
if (mEndRefreshTimer)
|
||||
mEndRefreshTimer->Cancel();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED3(nsDownloadListener, CHDownloader, nsIDownload, nsIWebProgressListener, nsITimerCallback)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName,
|
||||
nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
|
||||
{
|
||||
CreateDownloadDisplay(); // call the base class to make the download UI
|
||||
|
||||
if (aPersist) // only true for File->Save As.
|
||||
{
|
||||
mWebPersist = aPersist;
|
||||
mWebPersist->SetProgressListener(this); // we form a cycle here, since we're a listener.
|
||||
// we'll break this cycle in DownloadDone()
|
||||
}
|
||||
|
||||
SetIsFileSave(aPersist != NULL);
|
||||
|
||||
mDestination = aTarget;
|
||||
mURI = aSource;
|
||||
mStartTime = startTime;
|
||||
|
||||
mHelperAppLauncher = nsnull;
|
||||
|
||||
InitDialog();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIURI source; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetSource(nsIURI * *aSource)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSource);
|
||||
NS_IF_ADDREF(*aSource = mURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsILocalFile target; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetTarget(nsILocalFile * *aTarget)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTarget);
|
||||
NS_IF_ADDREF(*aTarget = mDestination);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIWebBrowserPersist persist; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPersist);
|
||||
NS_IF_ADDREF(*aPersist = mWebPersist);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 percentComplete; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPercentComplete(PRInt32 *aPercentComplete)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute wstring displayName; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetDisplayName(PRUnichar * *aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::SetDisplayName(const PRUnichar * aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* readonly attribute long long startTime; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetStartTime(PRInt64 *aStartTime)
|
||||
{
|
||||
NS_ENSURE_ARG(aStartTime);
|
||||
*aStartTime = mStartTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIMIMEInfo MIMEInfo; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIWebProgressListener listener; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetListener(nsIWebProgressListener * *aListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aListener);
|
||||
NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::SetListener(nsIWebProgressListener * aListener)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIObserver observer; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetObserver(nsIObserver * *aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::SetObserver(nsIObserver * aObserver)
|
||||
{
|
||||
if (aObserver)
|
||||
mHelperAppLauncher = do_QueryInterface(aObserver);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
if (mUserCanceled && !mSentCancel)
|
||||
{
|
||||
if (mHelperAppLauncher)
|
||||
mHelperAppLauncher->Cancel();
|
||||
else if (aRequest)
|
||||
aRequest->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
mSentCancel = PR_TRUE;
|
||||
}
|
||||
|
||||
[mDownloadDisplay setProgressTo:aCurTotalProgress ofMax:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
DownloadDone(aStatus);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// nsITimerCallback implementation
|
||||
NS_IMETHODIMP nsDownloadListener::Notify(nsITimer *timer)
|
||||
{
|
||||
// resset the destination, since uniquifying the filename may have
|
||||
// changed it
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mDownloadDisplay setDestinationPath: [NSString stringWith_nsAString:pathStr]];
|
||||
|
||||
// cancelling should give us a failure status
|
||||
[mDownloadDisplay onEndDownload:(NS_SUCCEEDED(mDownloadStatus) && !mUserCanceled)];
|
||||
mEndRefreshTimer = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
// dialog has to be shown before the outlets get hooked up
|
||||
if (mURI)
|
||||
{
|
||||
nsCAutoString spec;
|
||||
|
||||
// we need to be careful not to show a password in the url
|
||||
nsCAutoString userPassword;
|
||||
mURI->GetUserPass(userPassword);
|
||||
if (!userPassword.IsEmpty())
|
||||
{
|
||||
// ugh, build it by hand
|
||||
nsCAutoString hostport, path;
|
||||
mURI->GetScheme(spec);
|
||||
mURI->GetHostPort(hostport);
|
||||
mURI->GetPath(path);
|
||||
|
||||
spec.Append("://");
|
||||
spec.Append(hostport);
|
||||
spec.Append(path);
|
||||
}
|
||||
else
|
||||
mURI->GetSpec(spec);
|
||||
|
||||
[mDownloadDisplay setSourceURL: [NSString stringWithUTF8String:spec.get()]];
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mDownloadDisplay setDestinationPath: [NSString stringWith_nsAString:pathStr]];
|
||||
|
||||
[mDownloadDisplay onStartDownload:IsFileSave()];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::PauseDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::ResumeDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
mUserCanceled = PR_TRUE;
|
||||
|
||||
if (mWebPersist && !mSentCancel)
|
||||
{
|
||||
mWebPersist->CancelSave();
|
||||
mSentCancel = PR_TRUE;
|
||||
}
|
||||
|
||||
// delete any files we've created...
|
||||
|
||||
// DownloadDone will get called (eventually)
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::DownloadDone(nsresult aStatus)
|
||||
{
|
||||
// break the reference cycle by removing ourselves as a listener
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->SetProgressListener(nsnull);
|
||||
mWebPersist = nsnull;
|
||||
}
|
||||
|
||||
mHelperAppLauncher = nsnull;
|
||||
mDownloadStatus = aStatus;
|
||||
|
||||
// hack alert!
|
||||
// Our destination file gets uniquified after the OnStop notification is sent
|
||||
// (in nsExternalAppHandler::ExecuteDesiredAction), so we never get a chance
|
||||
// to figure out the final filename. To work around this, set a timer to fire
|
||||
// in the near future, from which we'll send the done callback.
|
||||
mEndRefreshTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (mEndRefreshTimer)
|
||||
{
|
||||
nsresult rv = mEndRefreshTimer->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT); // defaults to 1-shot, normal priority
|
||||
if (NS_FAILED(rv))
|
||||
mEndRefreshTimer = NULL;
|
||||
}
|
||||
|
||||
if (!mEndRefreshTimer) // timer creation or init failed, so just do it now
|
||||
[mDownloadDisplay onEndDownload:(NS_SUCCEEDED(aStatus) && !mUserCanceled)];
|
||||
}
|
||||
|
||||
//
|
||||
// DetachDownloadDisplay
|
||||
//
|
||||
// there are times when the download dislpay UI goes away before the
|
||||
// listener (quit, for example). This alerts us that we should forget all
|
||||
// about having any UI.
|
||||
//
|
||||
void
|
||||
nsDownloadListener::DetachDownloadDisplay()
|
||||
{
|
||||
mDownloadDisplay = nil;
|
||||
}
|
||||
|
||||
#pragma mark -
|
|
@ -1,632 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
// Embedding includes
|
||||
#include "nsIWebBrowser.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
//#include "nsIWidget.h"
|
||||
|
||||
// XPCOM and String includes
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#import "CHBrowserView.h"
|
||||
|
||||
#include "CHBrowserListener.h"
|
||||
|
||||
|
||||
CHBrowserListener::CHBrowserListener(CHBrowserView* aView)
|
||||
: mView(aView), mContainer(nsnull), mIsModal(PR_FALSE), mChromeFlags(0)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mListeners = [[NSMutableArray alloc] init];
|
||||
}
|
||||
|
||||
CHBrowserListener::~CHBrowserListener()
|
||||
{
|
||||
[mListeners release];
|
||||
mView = nsnull;
|
||||
[mContainer release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS9(CHBrowserListener,
|
||||
nsIInterfaceRequestor,
|
||||
nsIWebBrowserChrome,
|
||||
nsIWindowCreator,
|
||||
nsIEmbeddingSiteWindow,
|
||||
nsIEmbeddingSiteWindow2,
|
||||
nsIWebProgressListener,
|
||||
nsISupportsWeakReference,
|
||||
nsIContextMenuListener,
|
||||
nsITooltipListener)
|
||||
|
||||
// Implementation of nsIInterfaceRequestor
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::GetInterface(const nsIID &aIID, void** aInstancePtr)
|
||||
{
|
||||
if (aIID.Equals(NS_GET_IID(nsIDOMWindow))) {
|
||||
nsCOMPtr<nsIWebBrowser> browser = dont_AddRef([mView getWebBrowser]);
|
||||
if (browser)
|
||||
return browser->GetContentDOMWindow((nsIDOMWindow **) aInstancePtr);
|
||||
}
|
||||
|
||||
return QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
// Implementation of nsIWindowCreator. The CocoaBrowserService forwards requests
|
||||
// for a new window that have a parent to us, and we take over from there.
|
||||
/* nsIWebBrowserChrome createChromeWindow (in nsIWebBrowserChrome parent, in PRUint32 chromeFlags); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::CreateChromeWindow(nsIWebBrowserChrome *parent,
|
||||
PRUint32 chromeFlags,
|
||||
nsIWebBrowserChrome **_retval)
|
||||
{
|
||||
if (parent != this) {
|
||||
#if DEBUG
|
||||
NSLog(@"Mismatch in CHBrowserListener::CreateChromeWindow. We should be the owning parent.");
|
||||
#endif
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CHBrowserView* childView = [mContainer createBrowserWindow: chromeFlags];
|
||||
if (!childView) {
|
||||
#if DEBUG
|
||||
NSLog(@"No CHBrowserView hooked up for a newly created window yet.");
|
||||
#endif
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CHBrowserListener* listener = [childView getCocoaBrowserListener];
|
||||
if (!listener) {
|
||||
#if DEBUG
|
||||
NSLog(@"Uh-oh! No listener yet for a newly created window (nsCocoaBrowserlistener)");
|
||||
return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
NSLog(@"Made a chrome window.");
|
||||
#endif
|
||||
|
||||
*_retval = listener;
|
||||
NS_IF_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIContextMenuListener
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::OnShowContextMenu(PRUint32 aContextFlags, nsIDOMEvent* aEvent, nsIDOMNode* aNode)
|
||||
{
|
||||
[mContainer onShowContextMenu: aContextFlags domEvent: aEvent domNode: aNode];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsITooltipListener
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::OnShowTooltip(PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText)
|
||||
{
|
||||
NSPoint where;
|
||||
where.x = aXCoords; where.y = aYCoords;
|
||||
[mContainer onShowTooltip:where withText:[NSString stringWithPRUnichars:aTipText]];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::OnHideTooltip()
|
||||
{
|
||||
[mContainer onHideTooltip];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebBrowserChrome
|
||||
/* void setStatus (in unsigned long statusType, in wstring status); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetStatus(PRUint32 statusType, const PRUnichar *status)
|
||||
{
|
||||
if (!mContainer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSString* str = nsnull;
|
||||
if (status && (*status != PRUnichar(0))) {
|
||||
str = [NSString stringWithPRUnichars:status];
|
||||
}
|
||||
|
||||
[mContainer setStatus:str ofType:(NSStatusType)statusType];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute nsIWebBrowser webBrowser; */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::GetWebBrowser(nsIWebBrowser * *aWebBrowser)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aWebBrowser);
|
||||
if (!mView) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
*aWebBrowser = [mView getWebBrowser];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetWebBrowser(nsIWebBrowser * aWebBrowser)
|
||||
{
|
||||
if (!mView) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
[mView setWebBrowser:aWebBrowser];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute unsigned long chromeFlags; */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::GetChromeFlags(PRUint32 *aChromeFlags)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChromeFlags);
|
||||
*aChromeFlags = mChromeFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetChromeFlags(PRUint32 aChromeFlags)
|
||||
{
|
||||
// XXX Do nothing with them for now
|
||||
mChromeFlags = aChromeFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void destroyBrowserWindow (); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::DestroyBrowserWindow()
|
||||
{
|
||||
#if 0
|
||||
// XXX Could send this up to the container, but for now,
|
||||
// we just destroy the enclosing window.
|
||||
NSWindow* window = [mView window];
|
||||
|
||||
if (window) {
|
||||
[window close];
|
||||
}
|
||||
#endif
|
||||
// tell the container we want to close the window and let it do the
|
||||
// right thing.
|
||||
[mContainer closeBrowserWindow];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void sizeBrowserTo (in long aCX, in long aCY); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
|
||||
{
|
||||
if (mContainer) {
|
||||
NSSize size;
|
||||
|
||||
size.width = (float)aCX;
|
||||
size.height = (float)aCY;
|
||||
|
||||
[mContainer sizeBrowserTo:size];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void showAsModal (); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::ShowAsModal()
|
||||
{
|
||||
if (!mView) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
|
||||
if (!window) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mIsModal = PR_TRUE;
|
||||
//int result = [NSApp runModalForWindow:window];
|
||||
mIsModal = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* boolean isWindowModal (); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::IsWindowModal(PRBool *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
*_retval = mIsModal;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void exitModalEventLoop (in nsresult aStatus); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::ExitModalEventLoop(nsresult aStatus)
|
||||
{
|
||||
// [NSApp stopModalWithCode:(int)aStatus];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIEmbeddingSiteWindow2
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::Blur()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIEmbeddingSiteWindow
|
||||
/* void setDimensions (in unsigned long flags, in long x, in long y, in long cx, in long cy); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetDimensions(PRUint32 flags, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy)
|
||||
{
|
||||
if (!mView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION)
|
||||
{
|
||||
NSPoint origin;
|
||||
origin.x = (float)x;
|
||||
origin.y = (float)y;
|
||||
|
||||
// websites assume the origin is the topleft of the window and that the screen origin
|
||||
// is "topleft" (quickdraw coordinates). As a result, we have to convert it.
|
||||
GDHandle screenDevice = ::GetMainDevice();
|
||||
Rect screenRect = (**screenDevice).gdRect;
|
||||
short screenHeight = screenRect.bottom - screenRect.top;
|
||||
origin.y = screenHeight - origin.y;
|
||||
|
||||
[window setFrameTopLeftPoint:origin];
|
||||
}
|
||||
|
||||
if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER)
|
||||
{
|
||||
NSRect frame = [window frame];
|
||||
|
||||
float newWidth = (float)cx;
|
||||
float newHeight = (float)cy;
|
||||
|
||||
// should we allow resizes larger than the screen, or smaller
|
||||
// than some min size here?
|
||||
|
||||
// keep the top of the window in the same place
|
||||
frame.origin.y += (frame.size.height - (float)cy);
|
||||
frame.size.width = (float)cx;
|
||||
frame.size.height = (float)cy;
|
||||
[window setFrame:frame display:YES];
|
||||
}
|
||||
else if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER)
|
||||
{
|
||||
NSSize size;
|
||||
size.width = (float)cx;
|
||||
size.height = (float)cy;
|
||||
[window setContentSize:size];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void getDimensions (in unsigned long flags, out long x, out long y, out long cx, out long cy); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::GetDimensions(PRUint32 flags, PRInt32 *x, PRInt32 *y, PRInt32 *cx, PRInt32 *cy)
|
||||
{
|
||||
if (!mView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NSRect frame = [window frame];
|
||||
if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) {
|
||||
if ( x )
|
||||
*x = (PRInt32)frame.origin.x;
|
||||
if ( y ) {
|
||||
// websites (and gecko) expect the |y| value to be in "quickdraw" coordinates
|
||||
// (topleft of window, origin is topleft of main device). Convert from cocoa ->
|
||||
// quickdraw coord system.
|
||||
GDHandle screenDevice = ::GetMainDevice();
|
||||
Rect screenRect = (**screenDevice).gdRect;
|
||||
short screenHeight = screenRect.bottom - screenRect.top;
|
||||
*y = screenHeight - (PRInt32)(frame.origin.y + frame.size.height);
|
||||
}
|
||||
}
|
||||
if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
|
||||
if ( cx )
|
||||
*cx = (PRInt32)frame.size.width;
|
||||
if ( cy )
|
||||
*cy = (PRInt32)frame.size.height;
|
||||
}
|
||||
else if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER) {
|
||||
NSView* contentView = [window contentView];
|
||||
NSRect contentFrame = [contentView frame];
|
||||
if ( cx )
|
||||
*cx = (PRInt32)contentFrame.size.width;
|
||||
if ( cy )
|
||||
*cy = (PRInt32)contentFrame.size.height;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void setFocus (); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetFocus()
|
||||
{
|
||||
NSWindow* window = [mView window];
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// if we're already the keyWindow, we certainly don't need to do it again. This
|
||||
// ends up fixing a problem where we try to bring ourselves to the front while we're
|
||||
// in the process of miniaturizing the window
|
||||
if ([window isVisible] && (window != [NSApp keyWindow]))
|
||||
{
|
||||
BOOL suppressed = NO;
|
||||
if ([window respondsToSelector:@selector(suppressMakeKeyFront)])
|
||||
suppressed = (BOOL)[window suppressMakeKeyFront];
|
||||
|
||||
if (!suppressed)
|
||||
[window makeKeyAndOrderFront:window];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute boolean visibility; */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::GetVisibility(PRBool *aVisibility)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aVisibility);
|
||||
|
||||
if (!mView) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
if (!window) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aVisibility = [window isVisible];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetVisibility(PRBool aVisibility)
|
||||
{
|
||||
NSWindow* window = [mView window];
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// we rely on this callback to show gecko-created windows
|
||||
if (aVisibility) // showing
|
||||
{
|
||||
BOOL suppressed = NO;
|
||||
if ([window respondsToSelector:@selector(suppressMakeKeyFront)])
|
||||
suppressed = [window suppressMakeKeyFront];
|
||||
|
||||
if (![window isVisible] && !suppressed)
|
||||
[window makeKeyAndOrderFront:nil];
|
||||
}
|
||||
else // hiding
|
||||
{
|
||||
if ([window isVisible])
|
||||
[window orderOut:nil];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute wstring title; */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::GetTitle(PRUnichar * *aTitle)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTitle);
|
||||
|
||||
if (!mContainer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSString* title = [mContainer title];
|
||||
if ([title length] > 0)
|
||||
*aTitle = [title createNewUnicodeBuffer];
|
||||
else
|
||||
*aTitle = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::SetTitle(const PRUnichar * aTitle)
|
||||
{
|
||||
NS_ENSURE_ARG(aTitle);
|
||||
|
||||
if (!mContainer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSString* str = [NSString stringWithPRUnichars:aTitle];
|
||||
[mContainer setTitle:str];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [noscript] readonly attribute voidPtr siteWindow; */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::GetSiteWindow(void * *aSiteWindow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSiteWindow);
|
||||
*aSiteWindow = nsnull;
|
||||
if (!mView) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NSWindow* window = [mView window];
|
||||
if (!window) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aSiteWindow = (void*)window;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implementation of nsIWebProgressListener
|
||||
//
|
||||
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest,
|
||||
PRUint32 aStateFlags, PRUint32 aStatus)
|
||||
{
|
||||
NSEnumerator* enumerator = [mListeners objectEnumerator];
|
||||
id<CHBrowserListener> obj;
|
||||
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) {
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_START) {
|
||||
while ((obj = [enumerator nextObject]))
|
||||
[obj onLoadingStarted];
|
||||
}
|
||||
else if (aStateFlags & nsIWebProgressListener::STATE_STOP) {
|
||||
while ((obj = [enumerator nextObject]))
|
||||
[obj onLoadingCompleted:(NS_SUCCEEDED(aStatus))];
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
NSEnumerator* enumerator = [mListeners objectEnumerator];
|
||||
id<CHBrowserListener> obj;
|
||||
while ((obj = [enumerator nextObject]))
|
||||
[obj onProgressChange:aCurTotalProgress outOf:aMaxTotalProgress];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
if (!location)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCAutoString spec;
|
||||
location->GetSpec(spec);
|
||||
NSString* str = [NSString stringWithCString:spec.get()];
|
||||
|
||||
NSEnumerator* enumerator = [mListeners objectEnumerator];
|
||||
id<CHBrowserListener> obj;
|
||||
while ((obj = [enumerator nextObject]))
|
||||
[obj onLocationChange:str];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
NSString* str = [NSString stringWithPRUnichars:aMessage];
|
||||
|
||||
NSEnumerator* enumerator = [mListeners objectEnumerator];
|
||||
id<CHBrowserListener> obj;
|
||||
while ((obj = [enumerator nextObject]))
|
||||
[obj onStatusChange: str];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
NSEnumerator* enumerator = [mListeners objectEnumerator];
|
||||
id<CHBrowserListener> obj;
|
||||
while ((obj = [enumerator nextObject]))
|
||||
[obj onSecurityStateChange: state];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CHBrowserListener::AddListener(id <CHBrowserListener> aListener)
|
||||
{
|
||||
[mListeners addObject:aListener];
|
||||
}
|
||||
|
||||
void
|
||||
CHBrowserListener::RemoveListener(id <CHBrowserListener> aListener)
|
||||
{
|
||||
[mListeners removeObject:aListener];
|
||||
}
|
||||
|
||||
void
|
||||
CHBrowserListener::SetContainer(id <CHBrowserContainer> aContainer)
|
||||
{
|
||||
[mContainer autorelease];
|
||||
mContainer = aContainer;
|
||||
[mContainer retain];
|
||||
}
|
||||
|
|
@ -1,304 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
#import "CHBrowserService.h"
|
||||
#import "CHBrowserView.h"
|
||||
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIComponentRegistrar.h"
|
||||
#include "nsEmbedAPI.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIExternalHelperAppService.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
NSString* TermEmbeddingNotificationName = @"TermEmbedding";
|
||||
NSString* XPCOMShutDownNotificationName = @"XPCOMShutDown";
|
||||
|
||||
nsAlertController* CHBrowserService::sController = nsnull;
|
||||
CHBrowserService* CHBrowserService::sSingleton = nsnull;
|
||||
PRUint32 CHBrowserService::sNumBrowsers = 0;
|
||||
PRBool CHBrowserService::sCanTerminate = PR_FALSE;
|
||||
|
||||
|
||||
// CHBrowserService implementation
|
||||
CHBrowserService::CHBrowserService()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
CHBrowserService::~CHBrowserService()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS3(CHBrowserService,
|
||||
nsIWindowCreator,
|
||||
nsIFactory,
|
||||
nsIHelperAppLauncherDialog)
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
CHBrowserService::InitEmbedding()
|
||||
{
|
||||
sNumBrowsers++;
|
||||
|
||||
if (sSingleton)
|
||||
return NS_OK;
|
||||
|
||||
sSingleton = new CHBrowserService();
|
||||
if (!sSingleton)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(sSingleton);
|
||||
|
||||
nsCOMPtr<nsIComponentRegistrar> cr;
|
||||
NS_GetComponentRegistrar(getter_AddRefs(cr));
|
||||
if ( !cr )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Register as the window creator
|
||||
nsCOMPtr<nsIWindowWatcher> watcher(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
|
||||
if (!watcher)
|
||||
return NS_ERROR_FAILURE;
|
||||
watcher->SetWindowCreator(sSingleton);
|
||||
|
||||
// replace the external helper app dialog with our own
|
||||
#define NS_HELPERAPPLAUNCHERDIALOG_CID \
|
||||
{0xf68578eb, 0x6ec2, 0x4169, {0xae, 0x19, 0x8c, 0x62, 0x43, 0xf0, 0xab, 0xe1}}
|
||||
static NS_DEFINE_CID(kHelperDlgCID, NS_HELPERAPPLAUNCHERDIALOG_CID);
|
||||
nsresult rv = cr->RegisterFactory(kHelperDlgCID, NS_IHELPERAPPLAUNCHERDLG_CLASSNAME, NS_IHELPERAPPLAUNCHERDLG_CONTRACTID,
|
||||
sSingleton);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
CHBrowserService::BrowserClosed()
|
||||
{
|
||||
sNumBrowsers--;
|
||||
if (sCanTerminate && sNumBrowsers == 0) {
|
||||
// The app is terminating *and* our count dropped to 0.
|
||||
ShutDown();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
CHBrowserService::TermEmbedding()
|
||||
{
|
||||
// phase 1 notification (we're trying to terminate)
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:TermEmbeddingNotificationName object:nil];
|
||||
|
||||
sCanTerminate = PR_TRUE;
|
||||
if (sNumBrowsers == 0) {
|
||||
ShutDown();
|
||||
}
|
||||
else {
|
||||
#if DEBUG
|
||||
NSLog(@"Cannot yet shut down embedding.");
|
||||
#endif
|
||||
// Otherwise we cannot yet terminate. We have to let the death of the browser views
|
||||
// induce termination.
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void CHBrowserService::ShutDown()
|
||||
{
|
||||
NS_ASSERTION(sCanTerminate, "Should be able to terminate here!");
|
||||
|
||||
// phase 2 notifcation (we really are about to terminate)
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XPCOMShutDownNotificationName object:nil];
|
||||
|
||||
NS_IF_RELEASE(sSingleton);
|
||||
NS_TermEmbedding();
|
||||
#if DEBUG
|
||||
NSLog(@"Shutting down embedding.");
|
||||
#endif
|
||||
}
|
||||
|
||||
#define NS_ALERT_NIB_NAME "alert"
|
||||
|
||||
nsAlertController*
|
||||
CHBrowserService::GetAlertController()
|
||||
{
|
||||
if (!sController) {
|
||||
NSBundle* bundle = [NSBundle bundleForClass:[CHBrowserView class]];
|
||||
[bundle loadNibFile:@NS_ALERT_NIB_NAME externalNameTable:nsnull withZone:[NSApp zone]];
|
||||
}
|
||||
return sController;
|
||||
}
|
||||
|
||||
void
|
||||
CHBrowserService::SetAlertController(nsAlertController* aController)
|
||||
{
|
||||
// XXX When should the controller be released?
|
||||
sController = aController;
|
||||
[sController retain];
|
||||
}
|
||||
|
||||
// nsIFactory implementation
|
||||
NS_IMETHODIMP
|
||||
CHBrowserService::CreateInstance(nsISupports *aOuter,
|
||||
const nsIID & aIID,
|
||||
void **aResult)
|
||||
{
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
/*
|
||||
if (aIID.Equals(NS_GET_IID(nsIHelperAppLauncherDialog)))
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
return sSingleton->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CHBrowserService::LockFactory(PRBool lock)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Implementation of nsIWindowCreator
|
||||
/* nsIWebBrowserChrome createChromeWindow (in nsIWebBrowserChrome parent, in PRUint32 chromeFlags); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserService::CreateChromeWindow(nsIWebBrowserChrome *parent,
|
||||
PRUint32 chromeFlags,
|
||||
nsIWebBrowserChrome **_retval)
|
||||
{
|
||||
if (!parent) {
|
||||
#if DEBUG
|
||||
NSLog(@"Attempt to create a new browser window with a null parent. Should not happen in Chimera.");
|
||||
#endif
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWindowCreator> browserChrome(do_QueryInterface(parent));
|
||||
return browserChrome->CreateChromeWindow(parent, chromeFlags, _retval);
|
||||
}
|
||||
|
||||
|
||||
// void show( in nsIHelperAppLauncher aLauncher, in nsISupports aContext );
|
||||
NS_IMETHODIMP
|
||||
CHBrowserService::Show(nsIHelperAppLauncher* inLauncher, nsISupports* inContext)
|
||||
{
|
||||
PRBool autoDownload = PR_FALSE;
|
||||
|
||||
// See if pref enabled to allow automatic download
|
||||
nsCOMPtr<nsIPref> prefService (do_GetService(NS_PREF_CONTRACTID));
|
||||
if (prefService) {
|
||||
prefService->GetBoolPref("browser.download.autoDownload", &autoDownload);
|
||||
}
|
||||
|
||||
if (autoDownload) {
|
||||
// Pref is enabled so just save the file to disk in download folder
|
||||
// If browser.download.autoDownload is set to true helper app will be called by uriloader
|
||||
// XXX fix me. When we add UI to enable this pref it needs to be clear it carries
|
||||
// a security risk
|
||||
return inLauncher->LaunchWithApplication(nsnull, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
// Pref not enabled so do it old way - prompt to save file to disk
|
||||
return inLauncher->SaveToDisk(nsnull, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CHBrowserService::PromptForSaveToFile(nsISupports *aWindowContext, const PRUnichar *aDefaultFile, const PRUnichar *aSuggestedFileExtension, nsILocalFile **_retval)
|
||||
{
|
||||
NSString* filename = [NSString stringWithPRUnichars:aDefaultFile];
|
||||
NSSavePanel *thePanel = [NSSavePanel savePanel];
|
||||
|
||||
// Note: although the docs for NSSavePanel specifically state "path and filename can be empty strings, but
|
||||
// cannot be nil" if you want the last used directory to persist between calls to display the save panel
|
||||
// use nil for the path given to runModalForDirectory
|
||||
int runResult = [thePanel runModalForDirectory: nil file:filename];
|
||||
if (runResult == NSOKButton) {
|
||||
// NSLog(@"Saving to %@", [thePanel filename]);
|
||||
NSString *theName = [thePanel filename];
|
||||
return NS_NewNativeLocalFile(nsDependentCString([theName fileSystemRepresentation]), PR_FALSE, _retval);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* void showProgressDialog (in nsIHelperAppLauncher aLauncher, in nsISupports aContext); */
|
||||
NS_IMETHODIMP
|
||||
CHBrowserService::ShowProgressDialog(nsIHelperAppLauncher *aLauncher, nsISupports *aContext)
|
||||
{
|
||||
NSLog(@"CHBrowserService::ShowProgressDialog");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// RegisterAppComponents
|
||||
//
|
||||
// Register application-provided Gecko components.
|
||||
//
|
||||
void
|
||||
CHBrowserService::RegisterAppComponents(const nsModuleComponentInfo* inComponents, const int inNumComponents)
|
||||
{
|
||||
nsCOMPtr<nsIComponentRegistrar> cr;
|
||||
NS_GetComponentRegistrar(getter_AddRefs(cr));
|
||||
if ( !cr )
|
||||
return;
|
||||
|
||||
for (int i = 0; i < inNumComponents; ++i) {
|
||||
nsCOMPtr<nsIGenericFactory> componentFactory;
|
||||
nsresult rv = NS_NewGenericFactory(getter_AddRefs(componentFactory), &(inComponents[i]));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ASSERTION(PR_FALSE, "Unable to create factory for component");
|
||||
continue;
|
||||
}
|
||||
|
||||
rv = cr->RegisterFactory(inComponents[i].mCID,
|
||||
inComponents[i].mDescription,
|
||||
inComponents[i].mContractID,
|
||||
componentFactory);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to register factory for component");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __nsCocoaBrowserView_h__
|
||||
#define __nsCocoaBrowserView_h__
|
||||
|
||||
#undef DARWIN
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class CHBrowserView;
|
||||
class CHBrowserListener;
|
||||
class nsIDOMWindow;
|
||||
class nsIWebBrowser;
|
||||
class nsIDOMNode;
|
||||
class nsIDOMEvent;
|
||||
class nsIWebBrowserFind;
|
||||
class nsIEventSink;
|
||||
class nsIDragHelperService;
|
||||
class nsIPrintSettings;
|
||||
|
||||
|
||||
// Protocol implemented by anyone interested in progress
|
||||
// related to a BrowserView. A listener should explicitly
|
||||
// register itself with the view using the addListener
|
||||
// method.
|
||||
@protocol CHBrowserListener
|
||||
|
||||
- (void)onLoadingStarted;
|
||||
- (void)onLoadingCompleted:(BOOL)succeeded;
|
||||
// Invoked regularly as data associated with a page streams
|
||||
// in. If the total number of bytes expected is unknown,
|
||||
// maxBytes is -1.
|
||||
- (void)onProgressChange:(int)currentBytes outOf:(int)maxBytes;
|
||||
- (void)onLocationChange:(NSString*)urlSpec;
|
||||
- (void)onStatusChange:(NSString*)aMessage;
|
||||
- (void)onSecurityStateChange:(unsigned long)newState;
|
||||
// Called when a context menu should be shown.
|
||||
- (void)onShowContextMenu:(int)flags domEvent:(nsIDOMEvent*)aEvent domNode:(nsIDOMNode*)aNode;
|
||||
// Called when a tooltip should be shown or hidden
|
||||
- (void)onShowTooltip:(NSPoint)where withText:(NSString*)text;
|
||||
- (void)onHideTooltip;
|
||||
|
||||
@end
|
||||
|
||||
typedef enum {
|
||||
NSStatusTypeScript = 0x0001,
|
||||
NSStatusTypeScriptDefault = 0x0002,
|
||||
NSStatusTypeLink = 0x0003,
|
||||
} NSStatusType;
|
||||
|
||||
@protocol CHBrowserContainer
|
||||
|
||||
- (void)setStatus:(NSString *)statusString ofType:(NSStatusType)type;
|
||||
- (NSString *)title;
|
||||
- (void)setTitle:(NSString *)title;
|
||||
// Set the dimensions of our NSView. The container might need to do
|
||||
// some adjustment, so the view doesn't do it directly.
|
||||
- (void)sizeBrowserTo:(NSSize)dimensions;
|
||||
// Create a new browser container window and return the contained view.
|
||||
- (CHBrowserView*)createBrowserWindow:(unsigned int)mask;
|
||||
|
||||
- (NSMenu*)getContextMenu;
|
||||
- (NSWindow*)getNativeWindow;
|
||||
|
||||
// Ask whether the browser should accept a drag from the given source.
|
||||
// Should return NO if the source is a container for the browser, or
|
||||
// another item that represents the same entity (e.g. tab or proxy icon)
|
||||
- (BOOL)shouldAcceptDragFromSource:(id)dragSource;
|
||||
|
||||
// Gecko wants to close the "window" associated with this instance. Some
|
||||
// embedding apps might want to multiplex multiple gecko views in one
|
||||
// window (tabbed browsing). This gives them the chance to change the
|
||||
// behavior.
|
||||
- (void)closeBrowserWindow;
|
||||
|
||||
@end
|
||||
|
||||
enum {
|
||||
NSLoadFlagsNone = 0x0000,
|
||||
NSLoadFlagsDontPutInHistory = 0x0010,
|
||||
NSLoadFlagsReplaceHistoryEntry = 0x0020,
|
||||
NSLoadFlagsBypassCacheAndProxy = 0x0040
|
||||
};
|
||||
|
||||
enum {
|
||||
NSStopLoadNetwork = 0x01,
|
||||
NSStopLoadContent = 0x02,
|
||||
NSStopLoadAll = 0x03
|
||||
};
|
||||
|
||||
@interface CHBrowserView : NSView
|
||||
{
|
||||
nsIWebBrowser* _webBrowser;
|
||||
CHBrowserListener* _listener;
|
||||
NSWindow* mWindow;
|
||||
|
||||
nsIDragHelperService* mDragHelper;
|
||||
NSPoint mLastTrackedLocation;
|
||||
NSWindow* mLastTrackedWindow;
|
||||
|
||||
nsIPrintSettings* mPrintSettings; // we own this
|
||||
BOOL mUseGlobalPrintSettings;
|
||||
}
|
||||
|
||||
// NSView overrides
|
||||
- (id)initWithFrame:(NSRect)frame;
|
||||
- (id)initWithFrame:(NSRect)frame andWindow:(NSWindow*)aWindow;
|
||||
|
||||
- (void)dealloc;
|
||||
- (void)setFrame:(NSRect)frameRect;
|
||||
|
||||
// nsIWebBrowser methods
|
||||
- (void)addListener:(id <CHBrowserListener>)listener;
|
||||
- (void)removeListener:(id <CHBrowserListener>)listener;
|
||||
- (void)setContainer:(id <CHBrowserContainer>)container;
|
||||
- (nsIDOMWindow*)getContentWindow; // addrefs
|
||||
|
||||
// nsIWebNavigation methods
|
||||
- (void)loadURI:(NSString *)urlSpec referrer:(NSString*)referrer flags:(unsigned int)flags;
|
||||
- (void)reload:(unsigned int)flags;
|
||||
- (BOOL)canGoBack;
|
||||
- (BOOL)canGoForward;
|
||||
- (void)goBack;
|
||||
- (void)goForward;
|
||||
- (void)gotoIndex:(int)index;
|
||||
- (void)stop:(unsigned int)flags;
|
||||
- (NSString*)getCurrentURI;
|
||||
|
||||
// nsIWebBrowserSetup methods
|
||||
- (void)setProperty:(unsigned int)property toValue:(unsigned int)value;
|
||||
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView;
|
||||
- (void)saveURL:(NSView*)aFilterView url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename;
|
||||
|
||||
- (void)printDocument;
|
||||
- (void)pageSetup;
|
||||
- (void)ensurePrintSettings;
|
||||
|
||||
- (BOOL)findInPageWithPattern:(NSString*)inText caseSensitive:(BOOL)inCaseSensitive
|
||||
wrap:(BOOL)inWrap backwards:(BOOL)inBackwards;
|
||||
|
||||
-(BOOL)validateMenuItem: (NSMenuItem*)aMenuItem;
|
||||
|
||||
-(IBAction)cut:(id)aSender;
|
||||
-(BOOL)canCut;
|
||||
-(IBAction)copy:(id)aSender;
|
||||
-(BOOL)canCopy;
|
||||
-(IBAction)paste:(id)aSender;
|
||||
-(BOOL)canPaste;
|
||||
-(IBAction)delete:(id)aSender;
|
||||
-(BOOL)canDelete;
|
||||
-(IBAction)selectAll:(id)aSender;
|
||||
|
||||
-(IBAction)undo:(id)aSender;
|
||||
-(IBAction)redo:(id)aSender;
|
||||
|
||||
- (BOOL)canUndo;
|
||||
- (BOOL)canRedo;
|
||||
|
||||
- (void)biggerTextSize;
|
||||
- (void)smallerTextSize;
|
||||
|
||||
- (BOOL)canMakeTextBigger;
|
||||
- (BOOL)canMakeTextSmaller;
|
||||
|
||||
-(NSString*)getCurrentURLSpec;
|
||||
|
||||
- (void)setActive: (BOOL)aIsActive;
|
||||
|
||||
- (NSMenu*)getContextMenu;
|
||||
- (NSWindow*)getNativeWindow;
|
||||
|
||||
- (void)destroyWebBrowser;
|
||||
- (nsIWebBrowser*)getWebBrowser;
|
||||
- (CHBrowserListener*)getCocoaBrowserListener;
|
||||
- (void)setWebBrowser:(nsIWebBrowser*)browser;
|
||||
|
||||
- (NSString*)getFocusedURLString;
|
||||
|
||||
// given a point in window coordinates, find the Gecko event sink of the ChildView the
|
||||
// point is over.
|
||||
- (void) findEventSink:(nsIEventSink**)outSink forPoint:(NSPoint)inPoint inWindow:(NSWindow*)inWind;
|
||||
|
||||
@end
|
||||
|
||||
#endif // __nsCocoaBrowserView_h__
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,236 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2002 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* David Hyatt <hyatt@netscape.com> (Original Author)
|
||||
* Max Horn <max@quendi.de> (Context menu & tooltip code)
|
||||
*/
|
||||
|
||||
#import "ExtendedOutlineView.h"
|
||||
|
||||
@interface ExtendedOutlineView (Private)
|
||||
- (void)_updateToolTipRect;
|
||||
@end
|
||||
|
||||
@implementation ExtendedOutlineView
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
if ( (self = [super initWithFrame:frame]) ) {
|
||||
mDeleteAction = 0;
|
||||
// FIXME - this method is *never* called for items that are archived in a nib!
|
||||
// Luckily, object memory is zeroed, so mDeleteAction will be 0 anyway.
|
||||
// I recommend that this method just be removed.
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
// Setup the initial NSToolTipRects
|
||||
[self _updateToolTipRect];
|
||||
}
|
||||
|
||||
-(void)setDeleteAction: (SEL)aDeleteAction
|
||||
{
|
||||
mDeleteAction = aDeleteAction;
|
||||
}
|
||||
|
||||
-(SEL)deleteAction
|
||||
{
|
||||
return mDeleteAction;
|
||||
}
|
||||
|
||||
-(void)setDelegate:(id)anObject
|
||||
{
|
||||
[super setDelegate:anObject];
|
||||
mDelegateTooltipStringForItem = [anObject respondsToSelector:@selector(outlineView:tooltipStringForItem:)];
|
||||
}
|
||||
|
||||
|
||||
-(void)keyDown:(NSEvent*)aEvent
|
||||
{
|
||||
// check each char in the event array. it should be just 1 char, but
|
||||
// just in case we use a loop.
|
||||
int len = [[aEvent characters] length];
|
||||
for ( int i = 0; i < len; ++i ) {
|
||||
unichar c = [[aEvent characters] characterAtIndex:i];
|
||||
|
||||
// Check for a certain set of special keys.
|
||||
|
||||
if (c == NSDeleteCharacter || c == NSBackspaceCharacter) {
|
||||
// delete the bookmark
|
||||
if (mDeleteAction)
|
||||
[NSApp sendAction: mDeleteAction to: [self target] from: self];
|
||||
return;
|
||||
}
|
||||
else if (c == NSCarriageReturnCharacter) {
|
||||
// Start editing
|
||||
if ([self numberOfSelectedRows] == 1) {
|
||||
[self editColumn:0 row:[self selectedRow] withEvent:aEvent select:YES];
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (c == NSLeftArrowFunctionKey || c == NSRightArrowFunctionKey)
|
||||
{
|
||||
BOOL expand = (c == NSRightArrowFunctionKey);
|
||||
if ([self numberOfSelectedRows] == 1) {
|
||||
int index = [self selectedRow];
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
id item = [self itemAtRow: index];
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (![self isExpandable: item])
|
||||
return;
|
||||
|
||||
if (![self isItemExpanded: item] && expand)
|
||||
[self expandItem: item];
|
||||
else if ([self isItemExpanded: item] && !expand)
|
||||
[self collapseItem: item];
|
||||
}
|
||||
}
|
||||
} // foreach character
|
||||
|
||||
return [super keyDown: aEvent];
|
||||
}
|
||||
|
||||
/*
|
||||
* Intercept changes to the window frame so we can update our tooltip rects
|
||||
*/
|
||||
- (void)setFrameOrigin:(NSPoint)newOrigin;
|
||||
{
|
||||
[super setFrameOrigin:newOrigin];
|
||||
[self _updateToolTipRect];
|
||||
}
|
||||
|
||||
- (void)setFrameSize:(NSSize)newSize;
|
||||
{
|
||||
[super setFrameSize:newSize];
|
||||
[self _updateToolTipRect];
|
||||
}
|
||||
|
||||
- (void)setFrame:(NSRect)frameRect
|
||||
{
|
||||
[super setFrame:frameRect];
|
||||
[self _updateToolTipRect];
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the informal NSToolTipOwner protocol to allow tooltips
|
||||
* on a per-item level.
|
||||
*/
|
||||
- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)data
|
||||
{
|
||||
NSString *result = nil;
|
||||
int rowIndex = [self rowAtPoint:point];
|
||||
if (rowIndex >= 0) {
|
||||
id delegate = [self delegate];
|
||||
id item = [self itemAtRow:rowIndex];
|
||||
|
||||
if (item && mDelegateTooltipStringForItem)
|
||||
result = [delegate outlineView:self tooltipStringForItem:item];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a context menu depending on which item was clicked.
|
||||
*/
|
||||
- (NSMenu *)menuForEvent:(NSEvent *)theEvent
|
||||
{
|
||||
id item;
|
||||
int rowIndex;
|
||||
NSPoint point;
|
||||
|
||||
point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
rowIndex = [self rowAtPoint:point];
|
||||
|
||||
if (rowIndex >= 0) {
|
||||
// There seems to be a bug in AppKit; selectRow is supposed to
|
||||
// abort editing, but it doesn't, thus we do it manually.
|
||||
[self abortEditing];
|
||||
|
||||
item = [self itemAtRow:rowIndex];
|
||||
if (item) {
|
||||
id delegate = [self delegate];
|
||||
|
||||
// If the item was not selected, select it now
|
||||
if (![self isRowSelected:rowIndex]) {
|
||||
if (![delegate respondsToSelector:@selector(outlineView:shouldSelectItem:)]
|
||||
|| [delegate outlineView:self shouldSelectItem:item])
|
||||
[self selectRow:rowIndex byExtendingSelection:NO];
|
||||
}
|
||||
|
||||
if ([delegate respondsToSelector:@selector(outlineView:contextMenuForItem:)])
|
||||
return [delegate outlineView:self contextMenuForItem:item];
|
||||
}
|
||||
}
|
||||
|
||||
// Just return the default context menu
|
||||
return [self menu];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ExtendedOutlineView (Private)
|
||||
|
||||
/*
|
||||
* Set up tooltip rects for every row, but only if the frame size or
|
||||
* the number of rows changed since the last invocation.
|
||||
*/
|
||||
- (void)_updateToolTipRect
|
||||
{
|
||||
static NSRect oldFrameRect;
|
||||
static int oldRows = 0;
|
||||
NSRect frameRect;
|
||||
int rows;
|
||||
|
||||
// Only set tooltip rects if the delegate implements outlineView:tooltipStringForItem:
|
||||
if (!mDelegateTooltipStringForItem)
|
||||
return;
|
||||
|
||||
frameRect = [self frame];
|
||||
rows = [self numberOfRows];
|
||||
|
||||
// Check if rows or frame changed
|
||||
if (rows != oldRows || !NSEqualRects(oldFrameRect, frameRect))
|
||||
{
|
||||
int i;
|
||||
NSRect rect;
|
||||
|
||||
// Remove all old NSToolTipRects
|
||||
[self removeAllToolTips];
|
||||
|
||||
// Add a NSToolTipRect for each row
|
||||
for (i = 0; i < rows; ++i)
|
||||
{
|
||||
rect = [self rectOfRow:i];
|
||||
[self addToolTipRect:rect owner:self userData:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
// Save the current values
|
||||
oldRows = rows;
|
||||
oldFrameRect = frameRect;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,114 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Appkit/Appkit.h>
|
||||
#import "ExtendedOutlineView.h"
|
||||
|
||||
class nsIRDFDataSource;
|
||||
class nsIRDFContainer;
|
||||
class nsIRDFContainerUtils;
|
||||
class nsIRDFResource;
|
||||
class nsIRDFService;
|
||||
|
||||
|
||||
// RDF Resource Wrapper to make the Outline View happy
|
||||
@interface RDFOutlineViewItem : NSObject
|
||||
{
|
||||
nsIRDFResource* mResource;
|
||||
unsigned int mCacheVersion; // if matches the cache version in the data source,
|
||||
// cached values are valid
|
||||
BOOL mExpandable;
|
||||
int mNumChildren;
|
||||
NSArray* mChildNodes;
|
||||
}
|
||||
|
||||
- (nsIRDFResource*)resource; // addRefs the result
|
||||
- (void)setResource:(nsIRDFResource*) aResource;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface RDFOutlineViewDataSource : NSObject
|
||||
{
|
||||
nsIRDFDataSource* mDataSource;
|
||||
nsIRDFContainer* mContainer;
|
||||
nsIRDFContainerUtils* mContainerUtils;
|
||||
nsIRDFResource* mRootResource;
|
||||
nsIRDFService* mRDFService;
|
||||
|
||||
IBOutlet ExtendedOutlineView* mOutlineView;
|
||||
|
||||
NSMutableDictionary* mDictionary;
|
||||
unsigned int mCacheVersion;
|
||||
}
|
||||
|
||||
// Initialization Methods
|
||||
- (void) ensureDataSourceLoaded;
|
||||
- (void) cleanupDataSource;
|
||||
|
||||
- (nsIRDFDataSource*) dataSource;
|
||||
- (nsIRDFResource*) rootResource;
|
||||
- (void) setDataSource: (nsIRDFDataSource*) aDataSource;
|
||||
- (void) setRootResource: (nsIRDFResource*) aResource;
|
||||
|
||||
// Outline View Data Source methods
|
||||
- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item;
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item;
|
||||
- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item;
|
||||
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;
|
||||
|
||||
// tooltip support from the ExtendedOutlineView. Override to provide a tooltip
|
||||
// other than the Name property for each item in the view.
|
||||
- (NSString *)outlineView:(NSOutlineView *)outlineView tooltipStringForItem:(id)inItem;
|
||||
|
||||
- (void)reloadDataForItem:(id)item reloadChildren: (BOOL)aReloadChildren;
|
||||
|
||||
// Implementation Methods
|
||||
- (id)getWrapperFor:(nsIRDFResource*) aRDFResource;
|
||||
- (void)invalidateCachedItems;
|
||||
|
||||
// override to do something different with the cell data rather than just
|
||||
// return a string (add an icon in an attributed string, for example).
|
||||
- (id)createCellContents:(NSString*)inValue withColumn:(NSString*)inColumn byItem:(id)inItem;
|
||||
|
||||
- (NSString*)getPropertyString:(NSString*)inPropertyURI forItem:(RDFOutlineViewItem*)inItem;
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -150,6 +150,7 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
|||
@interface HistoryDataSource(Private)
|
||||
|
||||
- (void)cleanupHistory;
|
||||
- (void)removeItemFromHistory:(id)inItem withService:(nsIBrowserHistory*)inHistService;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -398,15 +399,27 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
|||
|
||||
nsCOMPtr<nsIBrowserHistory> history = do_GetService("@mozilla.org/browser/global-history;1");
|
||||
if ( history ) {
|
||||
// Even though it looks like relying on row numbers as we delete will get us in trouble
|
||||
// and out of sync, until we actually invalidate the table, the rows keep their prior values.
|
||||
// If children are selected as well as the parent, we'll just end up trying to remove the
|
||||
// host string from history which will silently fail. It's extra work, but harmless.
|
||||
history->StartBatchUpdate();
|
||||
NSEnumerator* rowEnum = [mOutlineView selectedRowEnumerator];
|
||||
for ( NSNumber* currIndex = [rowEnum nextObject]; currIndex; currIndex = [rowEnum nextObject]) {
|
||||
index = [currIndex intValue];
|
||||
RDFOutlineViewItem* item = [mOutlineView itemAtRow: index];
|
||||
if (![mOutlineView isExpandable: item]) {
|
||||
NSString* urlString = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:item];
|
||||
history->RemovePage([urlString UTF8String]);
|
||||
if ([mOutlineView isExpandable: item]) {
|
||||
// delete a folder by iterating over each of its children and deleting them. There
|
||||
// should be a better way, but the history api's don't really support them. Expand
|
||||
// the folder before we delete it otherwise we don't get any child nodes to delete.
|
||||
[mOutlineView expandItem:item];
|
||||
NSEnumerator* childEnum = [item->mChildNodes objectEnumerator];
|
||||
RDFOutlineViewItem* currChild = nil;
|
||||
while ( (currChild = [childEnum nextObject]) )
|
||||
[self removeItemFromHistory:currChild withService:history];
|
||||
}
|
||||
else
|
||||
[self removeItemFromHistory:item withService:history];
|
||||
}
|
||||
history->EndBatchUpdate();
|
||||
if ( clearSelectionWhenDone )
|
||||
|
@ -417,6 +430,13 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
|||
}
|
||||
}
|
||||
|
||||
-(void)removeItemFromHistory:(id)inItem withService:(nsIBrowserHistory*)inHistService;
|
||||
{
|
||||
NSString* urlString = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:inItem];
|
||||
inHistService->RemovePage([urlString UTF8String]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// outlineView:tooltipForString
|
||||
//
|
||||
|
|
|
@ -1,674 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
#import "PreferenceManager.h"
|
||||
#import "UserDefaults.h"
|
||||
#import "CHBrowserService.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIProfile.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsString.h"
|
||||
#include "nsEmbedAPI.h"
|
||||
#include "AppDirServiceProvider.h"
|
||||
|
||||
|
||||
#ifdef _BUILD_STATIC_BIN
|
||||
#include "nsStaticComponent.h"
|
||||
nsresult PR_CALLBACK
|
||||
app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count);
|
||||
#endif
|
||||
|
||||
@interface PreferenceManager(PreferenceManagerPrivate)
|
||||
|
||||
+ (PreferenceManager *) sharedInstanceDontCreate;
|
||||
|
||||
- (void)registerNotificationListener;
|
||||
|
||||
- (void)termEmbedding: (NSNotification*)aNotification;
|
||||
- (void)xpcomTerminate: (NSNotification*)aNotification;
|
||||
|
||||
- (void)configureProxies;
|
||||
- (BOOL)updateOneProxy:(NSDictionary*)configDict
|
||||
protocol:(NSString*)protocol
|
||||
proxyEnableKey:(NSString*)enableKey
|
||||
proxyURLKey:(NSString*)urlKey
|
||||
proxyPortKey:(NSString*)portKey;
|
||||
|
||||
- (void)registerForProxyChanges;
|
||||
- (BOOL)readSystemProxySettings;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation PreferenceManager
|
||||
|
||||
static PreferenceManager* gSharedInstance = nil;
|
||||
#if DEBUG
|
||||
static BOOL gMadePrefManager;
|
||||
#endif
|
||||
|
||||
+ (PreferenceManager *)sharedInstance
|
||||
{
|
||||
if (!gSharedInstance)
|
||||
{
|
||||
#if DEBUG
|
||||
if (gMadePrefManager)
|
||||
NSLog(@"Recreating preferences manager on shutdown!");
|
||||
gMadePrefManager = YES;
|
||||
#endif
|
||||
gSharedInstance = [[PreferenceManager alloc] init];
|
||||
}
|
||||
|
||||
return gSharedInstance;
|
||||
}
|
||||
|
||||
+ (PreferenceManager *)sharedInstanceDontCreate
|
||||
{
|
||||
return gSharedInstance;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
mRunLoopSource = NULL;
|
||||
|
||||
[self registerNotificationListener];
|
||||
|
||||
if ([self initInternetConfig] == NO) {
|
||||
// XXXw. throw here
|
||||
NSLog (@"Failed to initialize Internet Config");
|
||||
}
|
||||
|
||||
if ([self initMozillaPrefs] == NO) {
|
||||
// XXXw. throw here too
|
||||
NSLog (@"Failed to initialize mozilla prefs");
|
||||
}
|
||||
|
||||
mDefaults = [NSUserDefaults standardUserDefaults];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
if (self == gSharedInstance)
|
||||
gSharedInstance = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)termEmbedding: (NSNotification*)aNotification
|
||||
{
|
||||
::ICStop(mInternetConfig);
|
||||
mInternetConfig = nil;
|
||||
NS_IF_RELEASE(mPrefs);
|
||||
// remove our runloop observer
|
||||
if (mRunLoopSource)
|
||||
{
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), mRunLoopSource, kCFRunLoopCommonModes);
|
||||
CFRelease(mRunLoopSource);
|
||||
mRunLoopSource = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)xpcomTerminate: (NSNotification*)aNotification
|
||||
{
|
||||
// save prefs now, in case any termination listeners set prefs.
|
||||
[self savePrefsFile];
|
||||
[gSharedInstance release];
|
||||
}
|
||||
|
||||
- (void)registerNotificationListener
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self
|
||||
selector: @selector(termEmbedding:)
|
||||
name: TermEmbeddingNotificationName
|
||||
object: nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self
|
||||
selector: @selector(xpcomTerminate:)
|
||||
name: XPCOMShutDownNotificationName
|
||||
object: nil];
|
||||
}
|
||||
|
||||
- (void)savePrefsFile
|
||||
{
|
||||
nsCOMPtr<nsIPrefService> prefsService = do_GetService(NS_PREF_CONTRACTID);
|
||||
if (prefsService)
|
||||
prefsService->SavePrefFile(nsnull);
|
||||
}
|
||||
|
||||
- (BOOL)initInternetConfig
|
||||
{
|
||||
OSStatus error;
|
||||
error = ::ICStart(&mInternetConfig, 'CHIM');
|
||||
if (error != noErr) {
|
||||
// XXX throw here?
|
||||
NSLog(@"Error initializing IC");
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)initMozillaPrefs
|
||||
{
|
||||
|
||||
#ifdef _BUILD_STATIC_BIN
|
||||
// Initialize XPCOM's module info table
|
||||
NSGetStaticModuleInfo = app_getModuleInfo;
|
||||
#endif
|
||||
|
||||
nsresult rv;
|
||||
|
||||
NSString *path = [[[NSBundle mainBundle] executablePath] stringByDeletingLastPathComponent];
|
||||
const char *binDirPath = [path fileSystemRepresentation];
|
||||
nsCOMPtr<nsILocalFile> binDir;
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(binDirPath), PR_TRUE, getter_AddRefs(binDir));
|
||||
if (NS_FAILED(rv))
|
||||
return NO;
|
||||
|
||||
// This shouldn't be needed since we are initing XPCOM with this
|
||||
// directory but causes a (harmless) warning if not defined.
|
||||
setenv("MOZILLA_FIVE_HOME", binDirPath, 1);
|
||||
|
||||
// get the 'mozProfileDirName' key from our Info.plist file
|
||||
NSString *dirString = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"mozProfileDirName"];
|
||||
const char* profileDirName;
|
||||
if (dirString)
|
||||
profileDirName = [dirString cString];
|
||||
else {
|
||||
NSLog(@"mozProfileDirName key missing from Info.plist file. Using default profile directory");
|
||||
profileDirName = "Chimera";
|
||||
}
|
||||
|
||||
// Supply our own directory service provider so we can control where
|
||||
// the registry and profiles are located.
|
||||
AppDirServiceProvider *provider = new AppDirServiceProvider(nsDependentCString(profileDirName));
|
||||
if (!provider) return NO;
|
||||
|
||||
nsCOMPtr<nsIDirectoryServiceProvider> dirProvider = (nsIDirectoryServiceProvider*)provider;
|
||||
rv = NS_InitEmbedding(binDir, dirProvider);
|
||||
if (NS_FAILED(rv)) {
|
||||
NSLog(@"Embedding init failed.");
|
||||
return NO;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProfile> profileService(do_GetService(NS_PROFILE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return NO;
|
||||
|
||||
nsAutoString newProfileName(NS_LITERAL_STRING("default"));
|
||||
PRBool profileExists = PR_FALSE;
|
||||
rv = profileService->ProfileExists(newProfileName.get(), &profileExists);
|
||||
if (NS_FAILED(rv))
|
||||
return NO;
|
||||
|
||||
if (!profileExists) {
|
||||
rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return NO;
|
||||
}
|
||||
|
||||
rv = profileService->SetCurrentProfile(newProfileName.get());
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_ERROR_FILE_ACCESS_DENIED) {
|
||||
NSString *alert = [NSString stringWithFormat: NSLocalizedString(@"AlreadyRunningAlert", @""), NSLocalizedStringFromTable(@"CFBundleName", @"InfoPlist", nil)];
|
||||
NSString *message = [NSString stringWithFormat: NSLocalizedString(@"AlreadyRunningMsg", @""), NSLocalizedStringFromTable(@"CFBundleName", @"InfoPlist", nil)];
|
||||
NSString *quit = NSLocalizedString(@"AlreadyRunningButton",@"");
|
||||
NSRunAlertPanel(alert,message,quit,nil,nil);
|
||||
[NSApp terminate:self];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
else if (rv == NS_ERROR_PROFILE_SETLOCK_FAILED) {
|
||||
NSLog(@"SetCurrentProfile returned NS_ERROR_PROFILE_SETLOCK_FAILED");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
mPrefs = prefs;
|
||||
NS_IF_ADDREF(mPrefs);
|
||||
|
||||
[self syncMozillaPrefs];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)syncMozillaPrefs
|
||||
{
|
||||
if (!mPrefs) {
|
||||
NSLog(@"Mozilla prefs not set up successfully");
|
||||
return;
|
||||
}
|
||||
|
||||
// set the universal charset detector pref. we can't set it in chimera.js
|
||||
// because it's a funky locale-specific pref.
|
||||
static const char* const kUniversalCharsetDetectorPref = "intl.charset.detector";
|
||||
mPrefs->SetCharPref(kUniversalCharsetDetectorPref, "universal_charset_detector");
|
||||
|
||||
// fix up the cookie prefs. If 'p3p' or 'accept foreign cookies' are on, remap them to
|
||||
// something that chimera can deal with.
|
||||
PRInt32 acceptCookies = 0;
|
||||
static const char* kCookieBehaviorPref = "network.cookie.cookieBehavior";
|
||||
mPrefs->GetIntPref(kCookieBehaviorPref, &acceptCookies);
|
||||
if ( acceptCookies == 1 ) { // accept foreign cookies, assume off
|
||||
acceptCookies = 2;
|
||||
mPrefs->SetIntPref(kCookieBehaviorPref, acceptCookies);
|
||||
}
|
||||
else if ( acceptCookies == 3 ) { // p3p, assume all cookies on
|
||||
acceptCookies = 0;
|
||||
mPrefs->SetIntPref(kCookieBehaviorPref, acceptCookies);
|
||||
}
|
||||
|
||||
[self configureProxies];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)configureProxies
|
||||
{
|
||||
[self readSystemProxySettings];
|
||||
[self registerForProxyChanges];
|
||||
}
|
||||
|
||||
static void SCProxiesChangedCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void * /* info */)
|
||||
{
|
||||
PreferenceManager* prefsManager = [PreferenceManager sharedInstanceDontCreate];
|
||||
[prefsManager readSystemProxySettings];
|
||||
#if DEBUG
|
||||
NSLog(@"Updating proxies");
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)registerForProxyChanges
|
||||
{
|
||||
if (mRunLoopSource) // don't register twice
|
||||
return;
|
||||
|
||||
SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL};
|
||||
|
||||
SCDynamicStoreRef dynamicStoreRef = SCDynamicStoreCreate(NULL, CFSTR("ChimeraProxiesNotification"), SCProxiesChangedCallback, &context);
|
||||
if (dynamicStoreRef)
|
||||
{
|
||||
CFStringRef proxyIdentifier = SCDynamicStoreKeyCreateProxies(NULL);
|
||||
CFArrayRef keyList = CFArrayCreate(NULL, (const void **)&proxyIdentifier, 1, &kCFTypeArrayCallBacks);
|
||||
|
||||
Boolean set = SCDynamicStoreSetNotificationKeys(dynamicStoreRef, keyList, NULL);
|
||||
if (set)
|
||||
{
|
||||
mRunLoopSource = SCDynamicStoreCreateRunLoopSource(NULL, dynamicStoreRef, 0);
|
||||
if (mRunLoopSource)
|
||||
{
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), mRunLoopSource, kCFRunLoopCommonModes);
|
||||
// we keep the ref to the source, so that we can remove it when the prefs manager is cleaned up.
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(proxyIdentifier);
|
||||
CFRelease(keyList);
|
||||
CFRelease(dynamicStoreRef);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)updateOneProxy:(NSDictionary*)configDict
|
||||
protocol:(NSString*)protocol
|
||||
proxyEnableKey:(NSString*)enableKey
|
||||
proxyURLKey:(NSString*)urlKey
|
||||
proxyPortKey:(NSString*)portKey
|
||||
{
|
||||
BOOL gotProxy = NO;
|
||||
|
||||
BOOL enabled = (BOOL)[[configDict objectForKey:enableKey] intValue];
|
||||
if (enabled)
|
||||
{
|
||||
NSString* protocolProxy = [configDict objectForKey:urlKey];
|
||||
int proxyPort = [[configDict objectForKey:portKey] intValue];
|
||||
if ([protocolProxy length] > 0 && proxyPort != 0)
|
||||
{
|
||||
[self setPref:[[NSString stringWithFormat:@"network.proxy.%@", protocol] cString] toString:protocolProxy];
|
||||
[self setPref:[[NSString stringWithFormat:@"network.proxy.%@_port", protocol] cString] toInt:proxyPort];
|
||||
gotProxy = YES;
|
||||
}
|
||||
}
|
||||
|
||||
return gotProxy;
|
||||
}
|
||||
|
||||
- (BOOL)readSystemProxySettings
|
||||
{
|
||||
BOOL usingProxies = NO;
|
||||
|
||||
PRInt32 proxyType, newProxyType;
|
||||
mPrefs->GetIntPref("network.proxy.type", &proxyType);
|
||||
newProxyType = proxyType;
|
||||
if (proxyType == 0 || proxyType == 1)
|
||||
{
|
||||
// get proxies from SystemConfiguration
|
||||
mPrefs->ClearUserPref("network.proxy.http");
|
||||
mPrefs->ClearUserPref("network.proxy.http_port");
|
||||
mPrefs->ClearUserPref("network.proxy.ssl");
|
||||
mPrefs->ClearUserPref("network.proxy.ssl_port");
|
||||
mPrefs->ClearUserPref("network.proxy.ftp");
|
||||
mPrefs->ClearUserPref("network.proxy.ftp_port");
|
||||
mPrefs->ClearUserPref("network.proxy.gopher");
|
||||
mPrefs->ClearUserPref("network.proxy.gopher_port");
|
||||
mPrefs->ClearUserPref("network.proxy.socks");
|
||||
mPrefs->ClearUserPref("network.proxy.socks_port");
|
||||
mPrefs->ClearUserPref("network.proxy.no_proxies_on");
|
||||
|
||||
NSDictionary* proxyConfigDict = (NSDictionary*)SCDynamicStoreCopyProxies(NULL);
|
||||
if (proxyConfigDict)
|
||||
{
|
||||
BOOL gotAProxy = NO;
|
||||
|
||||
gotAProxy |= [self updateOneProxy:proxyConfigDict protocol:@"http"
|
||||
proxyEnableKey:(NSString*)kSCPropNetProxiesHTTPEnable
|
||||
proxyURLKey:(NSString*)kSCPropNetProxiesHTTPProxy
|
||||
proxyPortKey:(NSString*)kSCPropNetProxiesHTTPPort];
|
||||
|
||||
gotAProxy |= [self updateOneProxy:proxyConfigDict protocol:@"ssl"
|
||||
proxyEnableKey:(NSString*)kSCPropNetProxiesHTTPSEnable
|
||||
proxyURLKey:(NSString*)kSCPropNetProxiesHTTPSProxy
|
||||
proxyPortKey:(NSString*)kSCPropNetProxiesHTTPSPort];
|
||||
|
||||
gotAProxy |= [self updateOneProxy:proxyConfigDict protocol:@"ftp"
|
||||
proxyEnableKey:(NSString*)kSCPropNetProxiesFTPEnable
|
||||
proxyURLKey:(NSString*)kSCPropNetProxiesFTPProxy
|
||||
proxyPortKey:(NSString*)kSCPropNetProxiesFTPPort];
|
||||
|
||||
gotAProxy |= [self updateOneProxy:proxyConfigDict protocol:@"gopher"
|
||||
proxyEnableKey:(NSString*)kSCPropNetProxiesGopherEnable
|
||||
proxyURLKey:(NSString*)kSCPropNetProxiesGopherProxy
|
||||
proxyPortKey:(NSString*)kSCPropNetProxiesGopherPort];
|
||||
|
||||
gotAProxy |= [self updateOneProxy:proxyConfigDict protocol:@"socks"
|
||||
proxyEnableKey:(NSString*)kSCPropNetProxiesSOCKSEnable
|
||||
proxyURLKey:(NSString*)kSCPropNetProxiesSOCKSProxy
|
||||
proxyPortKey:(NSString*)kSCPropNetProxiesSOCKSPort];
|
||||
|
||||
if (gotAProxy)
|
||||
{
|
||||
newProxyType = 1;
|
||||
|
||||
NSArray* exceptions = [proxyConfigDict objectForKey:(NSString*)kSCPropNetProxiesExceptionsList];
|
||||
if (exceptions)
|
||||
{
|
||||
NSString* sitesList = [exceptions componentsJoinedByString:@", "];
|
||||
if ([sitesList length] > 0)
|
||||
[self setPref:"network.proxy.no_proxies_on" toString:sitesList];
|
||||
}
|
||||
usingProxies = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
newProxyType = 0;
|
||||
}
|
||||
|
||||
[proxyConfigDict release];
|
||||
}
|
||||
|
||||
if (newProxyType != proxyType)
|
||||
mPrefs->SetIntPref("network.proxy.type", 1);
|
||||
}
|
||||
|
||||
return usingProxies;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString*)getStringPref: (const char*)prefName withSuccess:(BOOL*)outSuccess
|
||||
{
|
||||
NSString *prefValue = @"";
|
||||
|
||||
char *buf = nsnull;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mPrefs)
|
||||
rv = mPrefs->GetCharPref(prefName, &buf);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && buf) {
|
||||
// prefs are UTF-8
|
||||
prefValue = [NSString stringWithUTF8String:buf];
|
||||
free(buf);
|
||||
if (outSuccess) *outSuccess = YES;
|
||||
} else {
|
||||
if (outSuccess) *outSuccess = NO;
|
||||
}
|
||||
|
||||
return prefValue;
|
||||
}
|
||||
|
||||
- (NSColor*)getColorPref: (const char*)prefName withSuccess:(BOOL*)outSuccess
|
||||
{
|
||||
// colors are stored in HTML-like #FFFFFF strings
|
||||
NSString* colorString = [self getStringPref:prefName withSuccess:outSuccess];
|
||||
NSColor* returnColor = [NSColor blackColor];
|
||||
|
||||
if ([colorString hasPrefix:@"#"] && [colorString length] == 7)
|
||||
{
|
||||
unsigned int redInt, greenInt, blueInt;
|
||||
sscanf([colorString cString], "#%02x%02x%02x", &redInt, &greenInt, &blueInt);
|
||||
|
||||
float redFloat = ((float)redInt / 255.0);
|
||||
float greenFloat = ((float)greenInt / 255.0);
|
||||
float blueFloat = ((float)blueInt / 255.0);
|
||||
|
||||
returnColor = [NSColor colorWithCalibratedRed:redFloat green:greenFloat blue:blueFloat alpha:1.0f];
|
||||
}
|
||||
|
||||
return returnColor;
|
||||
}
|
||||
|
||||
- (BOOL)getBooleanPref: (const char*)prefName withSuccess:(BOOL*)outSuccess
|
||||
{
|
||||
PRBool boolPref = PR_FALSE;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mPrefs)
|
||||
rv = mPrefs->GetBoolPref(prefName, &boolPref);
|
||||
|
||||
if (outSuccess)
|
||||
*outSuccess = NS_SUCCEEDED(rv);
|
||||
|
||||
return boolPref ? YES : NO;
|
||||
}
|
||||
|
||||
- (int)getIntPref: (const char*)prefName withSuccess:(BOOL*)outSuccess
|
||||
{
|
||||
PRInt32 intPref = 0;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mPrefs)
|
||||
mPrefs->GetIntPref(prefName, &intPref);
|
||||
if (outSuccess)
|
||||
*outSuccess = NS_SUCCEEDED(rv);
|
||||
return intPref;
|
||||
}
|
||||
|
||||
- (void)setPref:(const char*)prefName toString:(NSString*)value
|
||||
{
|
||||
if (mPrefs)
|
||||
(void)mPrefs->SetCharPref(prefName, [value UTF8String]);
|
||||
}
|
||||
|
||||
- (void)setPref:(const char*)prefName toInt:(int)value
|
||||
{
|
||||
if (mPrefs)
|
||||
(void)mPrefs->SetIntPref(prefName, (PRInt32)value);
|
||||
}
|
||||
|
||||
- (void)setPref:(const char*)prefName toBoolean:(BOOL)value
|
||||
{
|
||||
if (mPrefs)
|
||||
(void)mPrefs->SetBoolPref(prefName, (PRBool)value);
|
||||
}
|
||||
|
||||
|
||||
//- (BOOL) getICBoolPref:(ConstStr255Param) prefKey;
|
||||
//{
|
||||
// ICAttr dummy;
|
||||
// OSStatus error;
|
||||
// SInt32 size;
|
||||
// Boolean buf;
|
||||
|
||||
// error = ICGetPref (internetConfig, prefKey, &dummy, &buf, &size);
|
||||
// if (error == noErr && buf)
|
||||
// return YES;
|
||||
// else
|
||||
// return NO;
|
||||
// }
|
||||
|
||||
- (NSString *) getICStringPref:(ConstStr255Param) prefKey;
|
||||
{
|
||||
NSString *string;
|
||||
ICAttr dummy;
|
||||
OSStatus error;
|
||||
SInt32 size = 256;
|
||||
char *buf;
|
||||
|
||||
do {
|
||||
if ((buf = (char*)malloc((unsigned int)size)) == NULL) {
|
||||
NSLog (@"malloc failed in [PreferenceManager getICStringPref]");
|
||||
return nil;
|
||||
}
|
||||
error = ICGetPref (mInternetConfig, prefKey, &dummy, buf, &size);
|
||||
if (error != noErr && error != icTruncatedErr) {
|
||||
free (buf);
|
||||
NSLog (@"[IC error %d in [PreferenceManager getICStringPref]", (int) error);
|
||||
return nil;
|
||||
}
|
||||
size *= 2;
|
||||
} while (error == icTruncatedErr);
|
||||
if (*buf == 0) {
|
||||
NSLog (@"ICGetPref returned empty string");
|
||||
free (buf);
|
||||
return nil;
|
||||
}
|
||||
CopyPascalStringToC ((ConstStr255Param) buf, buf);
|
||||
string = [NSString stringWithCString:buf];
|
||||
free(buf);
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *) homePage:(BOOL)checkStartupPagePref
|
||||
{
|
||||
if (!mPrefs)
|
||||
return @"about:blank";
|
||||
|
||||
PRInt32 mode = 1;
|
||||
|
||||
// In some cases, we need to check browser.startup.page to see if
|
||||
// we want to use the homepage or if the user wants a blank window.
|
||||
// mode 0 is blank page, mode 1 is home page. 2 is "last page visited"
|
||||
// but we don't care about that. Default to 1 unless |checkStartupPagePref|
|
||||
// is true.
|
||||
nsresult rv = NS_OK;
|
||||
if ( checkStartupPagePref )
|
||||
rv = mPrefs->GetIntPref("browser.startup.page", &mode);
|
||||
if (NS_FAILED(rv) || mode == 1) {
|
||||
// see which home page to use
|
||||
PRBool boolPref;
|
||||
if (NS_SUCCEEDED(mPrefs->GetBoolPref("chimera.use_system_home_page", &boolPref)) && boolPref)
|
||||
return [self getICStringPref:kICWWWHomePage];
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(mPrefs);
|
||||
if (!prefBranch) return @"about:blank";
|
||||
|
||||
NSString* homepagePref = nil;
|
||||
PRInt32 haveUserPref;
|
||||
if (NS_FAILED(prefBranch->PrefHasUserValue("browser.startup.homepage", &haveUserPref)) || !haveUserPref)
|
||||
{
|
||||
// no home page pref is set in user prefs.
|
||||
homepagePref = NSLocalizedStringFromTable( @"HomePageDefault", @"WebsiteDefaults", nil);
|
||||
// and let's copy this into the homepage pref if it's not bad
|
||||
if (![homepagePref isEqualToString:@"HomePageDefault"])
|
||||
mPrefs->SetCharPref("browser.startup.homepage", [homepagePref UTF8String]);
|
||||
}
|
||||
else {
|
||||
homepagePref = [self getStringPref:"browser.startup.homepage" withSuccess:NULL];
|
||||
}
|
||||
|
||||
if (homepagePref && [homepagePref length] > 0 && ![homepagePref isEqualToString:@"HomePageDefault"])
|
||||
return homepagePref;
|
||||
}
|
||||
|
||||
return @"about:blank";
|
||||
}
|
||||
|
||||
- (NSString *)searchPage
|
||||
{
|
||||
NSString* resultString = @"http://www.google.com/";
|
||||
if (!mPrefs)
|
||||
return resultString;
|
||||
|
||||
PRBool boolPref;
|
||||
if (NS_SUCCEEDED(mPrefs->GetBoolPref("chimera.use_system_home_page", &boolPref)) && boolPref)
|
||||
return [self getICStringPref:kICWebSearchPagePrefs];
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(mPrefs);
|
||||
if (!prefBranch)
|
||||
return resultString;
|
||||
|
||||
NSString* searchPagePref = nil;
|
||||
PRBool haveUserPref = PR_FALSE;
|
||||
prefBranch->PrefHasUserValue("chimera.search_page", &haveUserPref);
|
||||
if (haveUserPref)
|
||||
searchPagePref = [self getStringPref:"chimera.search_page" withSuccess:NULL];
|
||||
|
||||
if (!haveUserPref || (searchPagePref == NULL) || ([searchPagePref length] == 0))
|
||||
{
|
||||
// no home page pref is set in user prefs, or it's an empty string
|
||||
searchPagePref = NSLocalizedStringFromTable( @"SearchPageDefault", @"WebsiteDefaults", nil);
|
||||
// and let's copy this into the homepage pref if it's not bad
|
||||
if (![searchPagePref isEqualToString:@"SearchPageDefault"])
|
||||
mPrefs->SetCharPref("chimera.search_page", [searchPagePref UTF8String]);
|
||||
}
|
||||
|
||||
if (searchPagePref && [searchPagePref length] > 0 && ![searchPagePref isEqualToString:@"SearchPageDefault"])
|
||||
return searchPagePref;
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
Загрузка…
Ссылка в новой задаче