mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 21:18:35 +00:00
Merging changes from CHIMERA_M1_0_1_BRANCH.
This commit is contained in:
parent
97b9b3a02b
commit
2a7b65c505
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>646 106 458 263 0 0 1600 1002 </string>
|
||||
<string>674 107 458 263 0 0 1600 1002 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>214</key>
|
||||
@ -12,6 +12,6 @@
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6D52</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
@ -17,11 +17,7 @@
|
||||
</dict>
|
||||
<key>IBLastGroupID</key>
|
||||
<string>8</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
BIN
camino/resources/images/app/disclosureArrowDown.tiff
Normal file
BIN
camino/resources/images/app/disclosureArrowDown.tiff
Normal file
Binary file not shown.
BIN
camino/resources/images/app/disclosureArrowRight.tiff
Normal file
BIN
camino/resources/images/app/disclosureArrowRight.tiff
Normal file
Binary file not shown.
BIN
camino/resources/images/app/small_close.tiff
Normal file
BIN
camino/resources/images/app/small_close.tiff
Normal file
Binary file not shown.
@ -68,6 +68,7 @@
|
||||
closeCurrentTab = id;
|
||||
closeOtherTabs = id;
|
||||
closeSendersTab = id;
|
||||
copyImage = id;
|
||||
copyImageLocation = id;
|
||||
copyLinkLocation = id;
|
||||
endAddBookmarkSheet = id;
|
||||
@ -80,6 +81,7 @@
|
||||
goToLocationFromToolbarURLField = id;
|
||||
home = id;
|
||||
manageBookmarks = id;
|
||||
manageHistory = id;
|
||||
moveTabToNewWindow = id;
|
||||
newTab = id;
|
||||
nextTab = id;
|
||||
|
@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>66 21 653 383 0 0 1152 848 </string>
|
||||
<string>65 36 653 383 0 0 1152 848 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>124</key>
|
||||
@ -15,17 +15,17 @@
|
||||
<key>297</key>
|
||||
<string>107 466 213 294 0 0 1600 1002 </string>
|
||||
<key>314</key>
|
||||
<string>73 542 213 132 0 0 1600 1002 </string>
|
||||
<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>97 693 213 246 0 0 1600 1002 </string>
|
||||
<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>206 785 198 144 0 0 1600 1002 </string>
|
||||
<string>140 644 198 144 0 0 1152 848 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
@ -42,6 +42,6 @@
|
||||
<key>IBLockedObjects</key>
|
||||
<array/>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
14
camino/resources/localized/English.lproj/Keychain.nib/classes.nib
generated
Normal file
14
camino/resources/localized/English.lproj/Keychain.nib/classes.nib
generated
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{CLASS = KeychainBrowserListener; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
ACTIONS = {hitButtonCancel = id; hitButtonOK = id; hitButtonOther = id; shutdown = id; };
|
||||
CLASS = KeychainService;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {confirmChangePasswordPanel = id; confirmStorePasswordPanel = id; };
|
||||
SUPERCLASS = NSObject;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
12
camino/resources/localized/English.lproj/Keychain.nib/info.nib
generated
Normal file
12
camino/resources/localized/English.lproj/Keychain.nib/info.nib
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?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>240 146 356 240 0 0 1024 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>283.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
camino/resources/localized/English.lproj/Keychain.nib/objects.nib
generated
Normal file
BIN
camino/resources/localized/English.lproj/Keychain.nib/objects.nib
generated
Normal file
Binary file not shown.
Binary file not shown.
@ -20,6 +20,7 @@
|
||||
doReload = id;
|
||||
doSearch = id;
|
||||
doStop = id;
|
||||
downloadsWindow = id;
|
||||
exportBookmarks = id;
|
||||
feedbackLink = id;
|
||||
findAgain = id;
|
||||
@ -61,7 +62,6 @@
|
||||
mCreateBookmarksFolderMenuItem = NSMenuItem;
|
||||
mCreateBookmarksSeparatorMenuItem = NSMenuItem;
|
||||
mDockMenu = NSMenu;
|
||||
mFilterList = NSPopUpButton;
|
||||
mFilterView = NSView;
|
||||
mGoMenu = NSMenu;
|
||||
mServersSubmenu = NSMenu;
|
||||
|
@ -3,11 +3,11 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>237 33 482 372 0 0 1600 1002 </string>
|
||||
<string>105 33 482 372 0 0 1600 1002 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>437 533 277 90 0 0 1152 848 </string>
|
||||
<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>
|
||||
@ -31,7 +31,11 @@
|
||||
</dict>
|
||||
<key>IBLastGroupID</key>
|
||||
<string>2</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>29</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
@ -1,18 +1,40 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{
|
||||
CLASS = CHStackView;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {mDataSource = id; };
|
||||
SUPERCLASS = NSView;
|
||||
},
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{CLASS = NSObject; LANGUAGE = ObjC; },
|
||||
{CLASS = NSView; LANGUAGE = ObjC; SUPERCLASS = NSResponder; },
|
||||
{
|
||||
CLASS = ProgressDlgController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mElapsedTimeLabel = NSTextField;
|
||||
mFromField = NSTextField;
|
||||
mProgressBar = NSProgressIndicator;
|
||||
mStatusLabel = NSTextField;
|
||||
mTimeLeftLabel = NSTextField;
|
||||
mToField = NSTextField;
|
||||
mNoDownloadsText = NSTextField;
|
||||
mScrollView = NSScrollView;
|
||||
mStackView = CHStackView;
|
||||
};
|
||||
SUPERCLASS = NSWindowController;
|
||||
},
|
||||
{
|
||||
ACTIONS = {stop = id; toggleDisclosure = id; };
|
||||
CLASS = ProgressViewController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mLocationsLabel = NSTextField;
|
||||
mLocationsLabelCompact = NSTextField;
|
||||
mProgressBar = NSProgressIndicator;
|
||||
mProgressView = NSView;
|
||||
mProgressViewCompact = NSView;
|
||||
mServerLabel = NSTextField;
|
||||
mStatusLabel = NSTextField;
|
||||
mTimeLeftLabel = NSTextField;
|
||||
mTimeLeftLabelCompact = NSTextField;
|
||||
};
|
||||
SUPERCLASS = NSObject;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
|
||||
<plist version="0.9">
|
||||
<!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>94 26 404 250 0 0 1152 746 </string>
|
||||
<string>24 42 592 284 0 0 1600 1002 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
<string>286.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>5S60</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
22
camino/resources/localized/English.lproj/ProgressView.nib/classes.nib
generated
Normal file
22
camino/resources/localized/English.lproj/ProgressView.nib/classes.nib
generated
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
ACTIONS = {close = id; open = id; reveal = id; stop = id; toggleDisclosure = id; };
|
||||
CLASS = ProgressViewController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mCompletedView = NSView;
|
||||
mCompletedViewCompact = NSView;
|
||||
mExpandedCancelButton = NSButton;
|
||||
mExpandedOpenButton = NSButton;
|
||||
mExpandedRevealButton = NSButton;
|
||||
mProgressBar = NSProgressIndicator;
|
||||
mProgressView = NSView;
|
||||
mProgressViewCompact = NSView;
|
||||
};
|
||||
SUPERCLASS = NSObject;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
27
camino/resources/localized/English.lproj/ProgressView.nib/info.nib
generated
Normal file
27
camino/resources/localized/English.lproj/ProgressView.nib/info.nib
generated
Normal file
@ -0,0 +1,27 @@
|
||||
<?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>75 299 448 284 0 0 1600 1002 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>27</key>
|
||||
<string>573 628 420 80 0 0 1600 1002 </string>
|
||||
<key>5</key>
|
||||
<string>573 564 420 208 0 0 1600 1002 </string>
|
||||
<key>71</key>
|
||||
<string>573 564 420 208 0 0 1600 1002 </string>
|
||||
<key>97</key>
|
||||
<string>573 628 420 80 0 0 1600 1002 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
camino/resources/localized/English.lproj/ProgressView.nib/objects.nib
generated
Normal file
BIN
camino/resources/localized/English.lproj/ProgressView.nib/objects.nib
generated
Normal file
Binary file not shown.
@ -3,13 +3,9 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>410 67 356 301 0 0 1152 848 </string>
|
||||
<string>325 55 356 301 0 0 1024 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>251</integer>
|
||||
</array>
|
||||
<string>283.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
</dict>
|
||||
|
Binary file not shown.
@ -37,10 +37,14 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "SecurityDialogs.h"
|
||||
#import "CocoaPromptService.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#import "KeychainService.h"
|
||||
#import "nsDownloadListener.h"
|
||||
#import "ProgressDlgController.h"
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
// {0ffd3880-7a1a-11d6-a384-975d1d5f86fc}
|
||||
#define NS_SECURITYDIALOGS_CID \
|
||||
@ -55,6 +59,27 @@
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(SecurityDialogs);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(CocoaPromptService);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(KeychainPrompt);
|
||||
//NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadListener);
|
||||
|
||||
static NS_IMETHODIMP
|
||||
nsDownloadListenerConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
*aResult = NULL;
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsDownloadListener* inst;
|
||||
NS_NEWXPCOM(inst, nsDownloadListener);
|
||||
if (!inst)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(inst);
|
||||
inst->SetDisplayFactory([ProgressDlgController sharedDownloadController]);
|
||||
nsresult rv = inst->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(inst);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// used by MainController to register the components in which we want to override
|
||||
// with the Gecko embed layer.
|
||||
@ -83,6 +108,12 @@ static const nsModuleComponentInfo gAppComponents[] = {
|
||||
NS_KEYCHAINPROMPT_CID,
|
||||
"@mozilla.org/wallet/single-sign-on-prompt;1",
|
||||
KeychainPromptConstructor
|
||||
},
|
||||
{
|
||||
"Download",
|
||||
NS_DOWNLOAD_CID,
|
||||
NS_DOWNLOAD_CONTRACTID,
|
||||
nsDownloadListenerConstructor
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -52,9 +52,8 @@
|
||||
{
|
||||
IBOutlet NSApplication* mApplication;
|
||||
|
||||
// The following two items are used by the filter list when saving files.
|
||||
// The following item is added to NSSavePanels as an accessory view
|
||||
IBOutlet NSView* mFilterView;
|
||||
IBOutlet NSPopUpButton* mFilterList;
|
||||
|
||||
// IBOutlet NSMenuItem* mOfflineMenuItem;
|
||||
IBOutlet NSMenuItem* mCloseWindowMenuItem;
|
||||
@ -137,11 +136,12 @@
|
||||
-(IBAction) addFolder:(id)aSender;
|
||||
-(IBAction) addSeparator:(id)aSender;
|
||||
|
||||
//Window menu actions
|
||||
// Window menu actions
|
||||
-(IBAction) newTab:(id)aSender;
|
||||
-(IBAction) closeTab:(id)aSender;
|
||||
-(IBAction) downloadsWindow:(id)aSender;
|
||||
|
||||
//Help menu actions
|
||||
// Help menu actions
|
||||
-(IBAction) infoLink:(id)aSender;
|
||||
-(IBAction) feedbackLink:(id)aSender;
|
||||
|
||||
@ -154,7 +154,8 @@
|
||||
|
||||
- (void)adjustBookmarksMenuItemsEnabling:(BOOL)inBrowserWindowFrontmost;
|
||||
|
||||
-(NSWindow*)getFrontmostBrowserWindow;
|
||||
- (NSView*)getSavePanelView;
|
||||
- (NSWindow*)getFrontmostBrowserWindow;
|
||||
|
||||
- (MVPreferencesController *)preferencesController;
|
||||
- (void)displayPreferencesWindow:sender;
|
||||
|
@ -260,19 +260,7 @@ const int kReuseWindowOnAE = 2;
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
if ([ProgressDlgController numDownloadInProgress] > 0)
|
||||
{
|
||||
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)
|
||||
if (NSRunAlertPanel(alert, message, okButton, altButton, nil) == NSAlertDefaultReturn)
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
return NSTerminateNow;
|
||||
return [[ProgressDlgController sharedDownloadController] allowTerminate];
|
||||
}
|
||||
|
||||
-(void)applicationWillTerminate: (NSNotification*)aNotification
|
||||
@ -439,7 +427,7 @@ const int kReuseWindowOnAE = 2;
|
||||
{
|
||||
BrowserWindowController* browserController = [self getMainWindowBrowserController];
|
||||
if (browserController)
|
||||
[browserController saveDocument:NO filterView:mFilterView filterList: mFilterList];
|
||||
[browserController saveDocument:NO filterView:mFilterView];
|
||||
}
|
||||
|
||||
-(IBAction) pageSetup:(id)aSender
|
||||
@ -584,6 +572,11 @@ const int kReuseWindowOnAE = 2;
|
||||
}
|
||||
}
|
||||
|
||||
-(IBAction) downloadsWindow:(id)aSender
|
||||
{
|
||||
[[ProgressDlgController sharedDownloadController] showWindow:aSender];
|
||||
}
|
||||
|
||||
- (void)adjustBookmarksMenuItemsEnabling:(BOOL)inBrowserWindowFrontmost;
|
||||
{
|
||||
[mAddBookmarkMenuItem setEnabled:inBrowserWindowFrontmost];
|
||||
@ -591,6 +584,11 @@ const int kReuseWindowOnAE = 2;
|
||||
[mCreateBookmarksSeparatorMenuItem setEnabled:NO]; // separators are not implemented yet
|
||||
}
|
||||
|
||||
- (NSView*)getSavePanelView
|
||||
{
|
||||
return mFilterView;
|
||||
}
|
||||
|
||||
-(NSWindow*)getFrontmostBrowserWindow
|
||||
{
|
||||
// for some reason, [NSApp mainWindow] doesn't always work, so we have to
|
||||
|
@ -47,7 +47,58 @@ NSGETMODULE(_name) (nsIComponentManager* aCompMgr, \
|
||||
}
|
||||
|
||||
// NSGetModule entry points
|
||||
DECL_NSGETMODULE(UcharUtil) DECL_NSGETMODULE(nsUConvModule) 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) DECL_NSGETMODULE(nsPrefModule) DECL_NSGETMODULE(nsCJVMManagerModule) DECL_NSGETMODULE(nsSecurityManagerModule) 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(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(nsTextServicesModule) 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)
|
||||
DECL_NSGETMODULE(UcharUtil)
|
||||
DECL_NSGETMODULE(nsUConvModule)
|
||||
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)
|
||||
DECL_NSGETMODULE(nsPrefModule)
|
||||
DECL_NSGETMODULE(nsCJVMManagerModule)
|
||||
DECL_NSGETMODULE(nsSecurityManagerModule)
|
||||
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)
|
||||
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(nsTextServicesModule)
|
||||
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"
|
||||
|
||||
/**
|
||||
@ -55,7 +106,58 @@ DECL_NSGETMODULE(UcharUtil) DECL_NSGETMODULE(nsUConvModule) DECL_NSGETMODULE(nsU
|
||||
*/
|
||||
static nsStaticModuleInfo gStaticModuleInfo[] = {
|
||||
#define MODULE(_name) { (#_name), NSGETMODULE(_name) }
|
||||
MODULE(UcharUtil), MODULE(nsUConvModule), 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), MODULE(nsPrefModule), MODULE(nsCJVMManagerModule), MODULE(nsSecurityManagerModule), MODULE(nsChromeModule), MODULE(nsRDFModule), MODULE(nsParserModule), MODULE(nsGfxMacModule), MODULE(nsGfx2Module), MODULE(nsImageLib2Module), MODULE(nsPNGDecoderModule), MODULE(nsGIFModule2), MODULE(nsJPEGDecoderModule), 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(nsTextServicesModule), MODULE(nsProfileModule), MODULE(Session_History_Module), MODULE(application), MODULE(nsCookieModule), MODULE(nsXMLExtrasModule), MODULE(nsUniversalCharDetModule), MODULE(BOOT), MODULE(NSS),
|
||||
MODULE(UcharUtil),
|
||||
MODULE(nsUConvModule),
|
||||
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),
|
||||
MODULE(nsPrefModule),
|
||||
MODULE(nsCJVMManagerModule),
|
||||
MODULE(nsSecurityManagerModule),
|
||||
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),
|
||||
MODULE(nsContentModule),
|
||||
MODULE(nsLayoutModule),
|
||||
MODULE(nsMorkModule),
|
||||
MODULE(docshell_provider),
|
||||
MODULE(embedcomponents),
|
||||
MODULE(Browser_Embedding_Module),
|
||||
MODULE(nsEditorModule),
|
||||
MODULE(nsTransactionManagerModule),
|
||||
MODULE(nsTextServicesModule),
|
||||
MODULE(nsProfileModule),
|
||||
MODULE(Session_History_Module),
|
||||
MODULE(application),
|
||||
MODULE(nsCookieModule),
|
||||
MODULE(nsXMLExtrasModule),
|
||||
MODULE(nsUniversalCharDetModule),
|
||||
MODULE(BOOT),
|
||||
MODULE(NSS),
|
||||
#line 60 "nsStaticComponents.cpp.in"
|
||||
};
|
||||
|
||||
|
@ -601,7 +601,7 @@ const int kBookmarksRootItemTag = -2;
|
||||
|
||||
//Set cell's textual contents
|
||||
//[cellValue replaceCharactersInRange:NSMakeRange(0, [cellValue length]) withString:[NSString stringWith_nsAString: nameAttr]];
|
||||
cellValue = [[NSMutableAttributedString alloc] initWithString:[NSString stringWith_nsAString: nameAttr]];
|
||||
cellValue = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWith_nsAString: nameAttr]] autorelease];
|
||||
|
||||
//Create an attributed string to hold the empty attachment, then release the components.
|
||||
NSMutableAttributedString* attachmentAttrString = [NSMutableAttributedString attributedStringWithAttachment:textAttachment];
|
||||
|
@ -100,6 +100,7 @@
|
||||
|
||||
- (BOOL)isOpaque
|
||||
{
|
||||
// see http://developer.apple.com/qa/qa2001/qa1117.html
|
||||
if ( ([self tabViewType] == NSNoTabsBezelBorder) && (NSAppKitVersionNumber < 633) )
|
||||
return NO;
|
||||
|
||||
|
@ -54,6 +54,8 @@ static const int kEscapeKeyCode = 53;
|
||||
BOOL madeFirstResponder = [super makeFirstResponder:responder];
|
||||
if (madeFirstResponder && oldResponder != [self firstResponder])
|
||||
[(BrowserWindowController*)[self delegate] focusChangedFrom:oldResponder to:[self firstResponder]];
|
||||
|
||||
//NSLog(@"Old FR %@, new FR %@, responder %@, made %d", oldResponder, [self firstResponder], responder, madeFirstResponder);
|
||||
return madeFirstResponder;
|
||||
}
|
||||
|
||||
|
@ -109,12 +109,12 @@ typedef enum
|
||||
IBOutlet NSTextField* mLocationSheetURLField;
|
||||
IBOutlet NSView* mStatusBar; // contains the status text, progress bar, and lock
|
||||
IBOutlet PageProxyIcon* mProxyIcon;
|
||||
IBOutlet BrowserContentView* mContentView;
|
||||
IBOutlet BrowserContentView* mContentView;
|
||||
|
||||
IBOutlet BookmarksDataSource* mSidebarBookmarksDataSource;
|
||||
IBOutlet HistoryDataSource* mHistoryDataSource;
|
||||
IBOutlet HistoryDataSource* mHistoryDataSource;
|
||||
|
||||
IBOutlet BookmarksToolbar* mPersonalToolbar;
|
||||
IBOutlet BookmarksToolbar* mPersonalToolbar;
|
||||
|
||||
IBOutlet NSWindow* mAddBookmarkSheetWindow;
|
||||
IBOutlet NSTextField* mAddBookmarkTitleField;
|
||||
@ -191,6 +191,8 @@ typedef enum
|
||||
- (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
|
||||
@ -211,9 +213,9 @@ typedef enum
|
||||
- (IBAction)viewSource:(id)aSender; // focussed frame or page
|
||||
- (IBAction)viewPageSource:(id)aSender; // top-level page
|
||||
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList;
|
||||
- (void)saveURL: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
|
||||
url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename;
|
||||
- (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;
|
||||
@ -302,6 +304,7 @@ typedef enum
|
||||
- (IBAction)bookmarkLink: (id)aSender;
|
||||
|
||||
- (IBAction)copyLinkLocation:(id)aSender;
|
||||
- (IBAction)copyImage:(id)sender;
|
||||
- (IBAction)copyImageLocation:(id)sender;
|
||||
|
||||
- (BookmarksToolbar*) bookmarksToolbar;
|
||||
|
@ -816,6 +816,19 @@ static NSArray* sToolbarDefaults = nil;
|
||||
else
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)loadingStarted
|
||||
{
|
||||
[self updateToolbarItems];
|
||||
[self startThrobber];
|
||||
}
|
||||
|
||||
- (void)loadingDone
|
||||
{
|
||||
[self updateToolbarItems];
|
||||
[self stopThrobber];
|
||||
[mHistoryDataSource refresh];
|
||||
}
|
||||
|
||||
- (void)updateToolbarItems
|
||||
{
|
||||
@ -960,16 +973,14 @@ static NSArray* sToolbarDefaults = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView
|
||||
{
|
||||
[[mBrowserView getBrowserView] saveDocument:focusedFrame filterView:aFilterView filterList:aFilterList];
|
||||
[[mBrowserView getBrowserView] saveDocument:focusedFrame filterView:aFilterView];
|
||||
}
|
||||
|
||||
- (void)saveURL: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
|
||||
url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename
|
||||
- (void)saveURL: (NSView*)aFilterView url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename
|
||||
{
|
||||
[[mBrowserView getBrowserView] saveURL: aFilterView filterList: aFilterList
|
||||
url: aURLSpec suggestedFilename: aFilename];
|
||||
[[mBrowserView getBrowserView] saveURL: aFilterView url: aURLSpec suggestedFilename: aFilename];
|
||||
}
|
||||
|
||||
- (void)loadSourceOfURL:(NSString*)urlStr
|
||||
@ -1890,12 +1901,14 @@ static NSArray* sToolbarDefaults = nil;
|
||||
|
||||
- (IBAction)savePageAs:(id)aSender
|
||||
{
|
||||
[self saveDocument:NO filterView:nil filterList: nil];
|
||||
NSView* accessoryView = [[NSApp delegate] getSavePanelView];
|
||||
[self saveDocument:NO filterView:accessoryView];
|
||||
}
|
||||
|
||||
- (IBAction)saveFrameAs:(id)aSender
|
||||
{
|
||||
[self saveDocument:YES filterView:nil filterList: nil];
|
||||
NSView* accessoryView = [[NSApp delegate] getSavePanelView];
|
||||
[self saveDocument:YES filterView:accessoryView];
|
||||
}
|
||||
|
||||
- (IBAction)saveLinkAs:(id)aSender
|
||||
@ -1915,8 +1928,7 @@ static NSArray* sToolbarDefaults = nil;
|
||||
nsAutoString text;
|
||||
GeckoUtils::GatherTextUnder(mContextMenuNode, text);
|
||||
|
||||
[self saveURL: nil filterList: nil
|
||||
url: hrefStr suggestedFilename: [NSString stringWith_nsAString: text]];
|
||||
[self saveURL:nil url:hrefStr suggestedFilename:[NSString stringWith_nsAString:text]];
|
||||
}
|
||||
|
||||
- (IBAction)saveImageAs:(id)aSender
|
||||
@ -1931,11 +1943,18 @@ static NSArray* sToolbarDefaults = nil;
|
||||
|
||||
NSString* hrefStr = [NSString stringWith_nsAString: url];
|
||||
|
||||
[self saveURL: nil filterList: nil
|
||||
url: hrefStr suggestedFilename: [NSString stringWith_nsAString: text]];
|
||||
[self saveURL:nil url:hrefStr suggestedFilename: [NSString stringWith_nsAString: text]];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)copyImage:(id)sender
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowser> webBrowser = getter_AddRefs([[[self getBrowserWrapper] getBrowserView] getWebBrowser]);
|
||||
nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(webBrowser));
|
||||
if (clipboard)
|
||||
clipboard->CopyImageContents();
|
||||
}
|
||||
|
||||
- (IBAction)copyImageLocation:(id)sender
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowser> webBrowser = getter_AddRefs([[[self getBrowserWrapper] getBrowserView] getWebBrowser]);
|
||||
|
@ -335,10 +335,8 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
||||
mTabTitle = [mLoadingStatusString retain];
|
||||
[mTabItem setLabel:mTabTitle];
|
||||
|
||||
if (mWindowController) {
|
||||
[mWindowController updateToolbarItems];
|
||||
[mWindowController startThrobber];
|
||||
}
|
||||
if (mWindowController)
|
||||
[mWindowController loadingStarted];
|
||||
}
|
||||
|
||||
- (void)onLoadingCompleted:(BOOL)succeeded
|
||||
@ -402,10 +400,8 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
if (mWindowController) {
|
||||
[mWindowController updateToolbarItems];
|
||||
[mWindowController stopThrobber];
|
||||
}
|
||||
if (mWindowController)
|
||||
[mWindowController loadingDone];
|
||||
}
|
||||
|
||||
- (void)onProgressChange:(int)currentBytes outOf:(int)maxBytes
|
||||
|
@ -139,8 +139,7 @@ ContentClickListener::MouseClick(nsIDOMEvent* aEvent)
|
||||
nsAutoString text;
|
||||
GeckoUtils::GatherTextUnder(content, text);
|
||||
|
||||
[mBrowserController saveURL: nil filterList: nil
|
||||
url: hrefStr suggestedFilename: [NSString stringWith_nsAString: text]];
|
||||
[mBrowserController saveURL:nil url:hrefStr suggestedFilename:[NSString stringWith_nsAString:text]];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -51,10 +51,16 @@
|
||||
|
||||
class nsIPrefBranch;
|
||||
|
||||
enum KeychainPromptResult { kSave, kDontRemember, kNeverRemember } ;
|
||||
|
||||
@class CHBrowserView;
|
||||
|
||||
|
||||
@interface KeychainService : NSObject
|
||||
{
|
||||
IBOutlet id confirmStorePasswordPanel;
|
||||
IBOutlet id confirmChangePasswordPanel;
|
||||
|
||||
BOOL mIsEnabled;
|
||||
BOOL mIsAutoFillEnabled;
|
||||
|
||||
@ -64,6 +70,13 @@ class nsIPrefBranch;
|
||||
+ (KeychainService*) instance;
|
||||
- (void) shutdown:(id)sender;
|
||||
|
||||
- (IBAction)hitButtonOK:(id)sender;
|
||||
- (IBAction)hitButtonCancel:(id)sender;
|
||||
- (IBAction)hitButtonOther:(id)sender;
|
||||
|
||||
- (KeychainPromptResult)confirmStorePassword:(NSWindow*)parent;
|
||||
- (BOOL)confirmChangedPassword:(NSWindow*)parent;
|
||||
|
||||
- (BOOL) getUsernameAndPassword:(NSString*)realm port:(PRInt32)inPort user:(NSMutableString*)username password:(NSMutableString*)pwd item:(KCItemRef*)outItem;
|
||||
- (BOOL) findUsernameAndPassword:(NSString*)realm port:(PRInt32)inPort;
|
||||
- (void) storeUsernameAndPassword:(NSString*)realm port:(PRInt32)inPort user:(NSString*)username password:(NSString*)pwd;
|
||||
@ -75,13 +88,43 @@ class nsIPrefBranch;
|
||||
- (BOOL) isEnabled;
|
||||
- (BOOL) isAutoFillEnabled;
|
||||
|
||||
// routines to manipulate the keychain deny list for which hosts we shouldn't
|
||||
// ask about
|
||||
- (void) addHostToDenyList:(NSString*)host;
|
||||
- (BOOL) isHostInDenyList:(NSString*)host;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
//
|
||||
// KeychainDenyList
|
||||
//
|
||||
// A singleton object that maintains a list of sites where we should
|
||||
// not prompt the user for saving in the keychain. This object also
|
||||
// handles archiving the list in the user's profile dir.
|
||||
//
|
||||
|
||||
@interface KeychainDenyList : NSObject
|
||||
{
|
||||
NSMutableArray* mDenyList; // the list
|
||||
BOOL mIsDirty; // do we need to write the list to disk?
|
||||
}
|
||||
|
||||
+ (KeychainDenyList*) instance;
|
||||
- (void) shutdown:(id)sender;
|
||||
|
||||
- (BOOL) isHostPresent:(NSString*)host;
|
||||
- (void) addHost:(NSString*)host;
|
||||
- (void) removeHost:(NSString*)host;
|
||||
- (void) writeToDisk;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
class KeychainPrompt : public nsIAuthPromptWrapper
|
||||
{
|
||||
public:
|
||||
KeychainPrompt();
|
||||
KeychainPrompt(KeychainService*);
|
||||
virtual ~KeychainPrompt();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -95,7 +138,6 @@ protected:
|
||||
static void ExtractHostAndPort(const PRUnichar* inRealm, NSString** outHost, PRInt32* outPort);
|
||||
|
||||
nsCOMPtr<nsIPrompt> mPrompt;
|
||||
KeychainService* mKeychain;
|
||||
};
|
||||
|
||||
//
|
||||
@ -105,7 +147,7 @@ class KeychainFormSubmitObserver : public nsIObserver,
|
||||
public nsIFormSubmitObserver
|
||||
{
|
||||
public:
|
||||
KeychainFormSubmitObserver(KeychainService*);
|
||||
KeychainFormSubmitObserver();
|
||||
virtual ~KeychainFormSubmitObserver();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -116,12 +158,10 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
static BOOL CheckStorePasswordYN(nsIDOMWindowInternal*);
|
||||
static KeychainPromptResult CheckStorePasswordYN(nsIDOMWindowInternal*);
|
||||
static BOOL CheckChangeDataYN(nsIDOMWindowInternal*);
|
||||
|
||||
static NSWindow* GetNSWindow(nsIDOMWindowInternal* inWindow);
|
||||
|
||||
KeychainService* mKeychain;
|
||||
};
|
||||
|
||||
//
|
||||
@ -129,11 +169,10 @@ private:
|
||||
//
|
||||
@interface KeychainBrowserListener : NSObject<CHBrowserListener>
|
||||
{
|
||||
KeychainService* mKeychain;
|
||||
CHBrowserView* mBrowserView;
|
||||
}
|
||||
|
||||
- (id)initWithBrowser:(KeychainService*)keychain browser:(CHBrowserView*)aBrowser;
|
||||
- (id)initWithBrowser:(CHBrowserView*)aBrowser;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -69,6 +69,9 @@
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
|
||||
extern NSString* XPCOMShutDownNotificationName;
|
||||
|
||||
|
||||
nsresult
|
||||
@ -114,7 +117,7 @@ int KeychainPrefChangedCallback(const char* inPref, void* unused)
|
||||
// observer service uses a weakref.
|
||||
nsCOMPtr<nsIObserverService> svc = do_GetService("@mozilla.org/observer-service;1");
|
||||
NS_ASSERTION(svc, "Keychain can't get observer service");
|
||||
mFormSubmitObserver = new KeychainFormSubmitObserver(self);
|
||||
mFormSubmitObserver = new KeychainFormSubmitObserver();
|
||||
if ( mFormSubmitObserver && svc ) {
|
||||
NS_ADDREF(mFormSubmitObserver);
|
||||
svc->AddObserver(mFormSubmitObserver, NS_FORMSUBMIT_SUBJECT, PR_FALSE);
|
||||
@ -122,7 +125,7 @@ int KeychainPrefChangedCallback(const char* inPref, void* unused)
|
||||
|
||||
// register for the cocoa notification posted when XPCOM shutdown so we
|
||||
// can unregister the pref callbacks we register below
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(shutdown:) name:@"XPCOM Shutdown"
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(shutdown:) name:XPCOMShutDownNotificationName
|
||||
object:nil];
|
||||
|
||||
// cache the values of the prefs and register pref-changed callbacks. Yeah, I know
|
||||
@ -139,6 +142,10 @@ int KeychainPrefChangedCallback(const char* inPref, void* unused)
|
||||
pref->RegisterCallback(gAutoFillEnabledPref, KeychainPrefChangedCallback, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
// load the keychain.nib file with our dialogs in it
|
||||
BOOL success = [NSBundle loadNibNamed:@"Keychain" owner:self];
|
||||
NS_ASSERTION(success, "can't load keychain prompt dialogs");
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -168,6 +175,8 @@ int KeychainPrefChangedCallback(const char* inPref, void* unused)
|
||||
pref->UnregisterCallback(gUseKeychainPref, KeychainPrefChangedCallback, nsnull);
|
||||
pref->UnregisterCallback(gAutoFillEnabledPref, KeychainPrefChangedCallback, nsnull);
|
||||
}
|
||||
|
||||
[sInstance release];
|
||||
}
|
||||
|
||||
|
||||
@ -324,7 +333,181 @@ int KeychainPrefChangedCallback(const char* inPref, void* unused)
|
||||
//
|
||||
- (void) addListenerToView:(CHBrowserView*)view
|
||||
{
|
||||
[view addListener:[[[KeychainBrowserListener alloc] initWithBrowser:self browser:view] autorelease]];
|
||||
[view addListener:[[[KeychainBrowserListener alloc] initWithBrowser:view] autorelease]];
|
||||
}
|
||||
|
||||
//
|
||||
// hitButtonOK:
|
||||
// hitButtonCancel:
|
||||
// hitButtonOther:
|
||||
//
|
||||
// actions for the buttons of the keychain prompt dialogs.
|
||||
//
|
||||
|
||||
enum { kOKButton = 0, kCancelButton = 1, kOtherButton = 2 };
|
||||
|
||||
- (IBAction)hitButtonOK:(id)sender
|
||||
{
|
||||
[NSApp stopModalWithCode:kOKButton];
|
||||
}
|
||||
|
||||
- (IBAction)hitButtonCancel:(id)sender
|
||||
{
|
||||
[NSApp stopModalWithCode:kCancelButton];
|
||||
}
|
||||
|
||||
- (IBAction)hitButtonOther:(id)sender
|
||||
{
|
||||
[NSApp stopModalWithCode:kOtherButton];
|
||||
}
|
||||
|
||||
//
|
||||
// confirmStorePassword:
|
||||
//
|
||||
// Puts up a dialog when the keychain doesn't yet have an entry from
|
||||
// this site asking to store it, forget it this once, or mark the site
|
||||
// on a deny list so we never ask again.
|
||||
//
|
||||
- (KeychainPromptResult)confirmStorePassword:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:confirmStorePasswordPanel relativeToWindow:parent];
|
||||
[confirmStorePasswordPanel close];
|
||||
|
||||
// the results of hitButtonXX: map to the corresponding values in the
|
||||
// |KeychainPromptResult| enum so we can just cast and return
|
||||
return NS_STATIC_CAST(KeychainPromptResult, result);
|
||||
}
|
||||
|
||||
//
|
||||
// confirmChangedPassword:
|
||||
//
|
||||
// The password stored in the keychain differs from what the user typed
|
||||
// in. Ask what they want to do to resolve the issue.
|
||||
//
|
||||
- (BOOL)confirmChangedPassword:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:confirmChangePasswordPanel relativeToWindow:parent];
|
||||
[confirmChangePasswordPanel close];
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
|
||||
- (void) addHostToDenyList:(NSString*)host
|
||||
{
|
||||
[[KeychainDenyList instance] addHost:host];
|
||||
}
|
||||
|
||||
- (BOOL) isHostInDenyList:(NSString*)host
|
||||
{
|
||||
return [[KeychainDenyList instance] isHostPresent:host];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface KeychainDenyList (KeychainDenyListPrivate)
|
||||
- (NSString*) pathToDenyListFile;
|
||||
@end
|
||||
|
||||
|
||||
@implementation KeychainDenyList
|
||||
|
||||
static KeychainDenyList *sDenyListInstance = nil;
|
||||
|
||||
+ (KeychainDenyList*) instance
|
||||
{
|
||||
return sDenyListInstance ? sDenyListInstance : sDenyListInstance = [[self alloc] init];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ( (self = [super init]) ) {
|
||||
mDenyList = [[NSUnarchiver unarchiveObjectWithFile:[self pathToDenyListFile]] retain];
|
||||
if ( !mDenyList )
|
||||
mDenyList = [[NSMutableArray alloc] init];
|
||||
|
||||
mIsDirty = NO;
|
||||
|
||||
// register for the cocoa notification posted when XPCOM shutdown so we
|
||||
// can release our singleton and flush the file
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(shutdown:) name:XPCOMShutDownNotificationName object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self writeToDisk];
|
||||
[mDenyList release];
|
||||
}
|
||||
|
||||
//
|
||||
// shutdown:
|
||||
//
|
||||
// Called in response to the cocoa notification "XPCOM Shutdown" sent by the cocoa
|
||||
// browser service before it terminates embedding and shuts down xpcom. Allows us
|
||||
// to get rid of anything we're holding onto for the length of the app.
|
||||
//
|
||||
- (void) shutdown:(id)unused
|
||||
{
|
||||
[sDenyListInstance release];
|
||||
}
|
||||
|
||||
//
|
||||
// writeToDisk
|
||||
//
|
||||
// flushes the deny list to the save file in the user's profile, but only
|
||||
// if it has changed since we read it in.
|
||||
//
|
||||
- (void) writeToDisk
|
||||
{
|
||||
if ( mIsDirty )
|
||||
[NSArchiver archiveRootObject:mDenyList toFile:[self pathToDenyListFile]];
|
||||
mIsDirty = NO;
|
||||
}
|
||||
|
||||
- (BOOL) isHostPresent:(NSString*)host
|
||||
{
|
||||
return [mDenyList containsObject:host];
|
||||
}
|
||||
|
||||
- (void) addHost:(NSString*)host
|
||||
{
|
||||
if ( ![self isHostPresent:host] ) {
|
||||
[mDenyList addObject:host];
|
||||
mIsDirty = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) removeHost:(NSString*)host
|
||||
{
|
||||
if ( [self isHostPresent:host] ) {
|
||||
[mDenyList removeObject:host];
|
||||
mIsDirty = YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// pathToDenyListFile
|
||||
//
|
||||
// returns a path ('/' delimited) that cocoa can use to point to the
|
||||
// deny list save file in the current user's profile
|
||||
//
|
||||
- (NSString*) pathToDenyListFile
|
||||
{
|
||||
NSMutableString* path = [[[NSMutableString alloc] init] autorelease];
|
||||
|
||||
nsCOMPtr<nsIFile> appProfileDir;
|
||||
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(appProfileDir));
|
||||
if ( appProfileDir ) {
|
||||
nsAutoString profilePath;
|
||||
appProfileDir->GetPath(profilePath);
|
||||
[path setString:[NSString stringWith_nsAString:profilePath]];
|
||||
[path appendString:@"/Keychain Deny List"]; // |profilePath| is '/' delimited
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -338,12 +521,6 @@ NS_IMPL_ISUPPORTS2(KeychainPrompt,
|
||||
nsIAuthPromptWrapper)
|
||||
|
||||
KeychainPrompt::KeychainPrompt()
|
||||
: mKeychain([KeychainService instance])
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
KeychainPrompt::KeychainPrompt(KeychainService* keychain) : mKeychain(keychain)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
@ -391,7 +568,8 @@ KeychainPrompt::ExtractHostAndPort(const PRUnichar* inRealm, NSString** outHost,
|
||||
void
|
||||
KeychainPrompt::PreFill(const PRUnichar *realm, PRUnichar **user, PRUnichar **pwd)
|
||||
{
|
||||
if(![mKeychain isEnabled] || ![mKeychain isAutoFillEnabled])
|
||||
KeychainService* keychain = [KeychainService instance];
|
||||
if(![keychain isEnabled] || ![keychain isAutoFillEnabled])
|
||||
return;
|
||||
|
||||
NSString* host = nil;
|
||||
@ -409,7 +587,7 @@ KeychainPrompt::PreFill(const PRUnichar *realm, PRUnichar **user, PRUnichar **pw
|
||||
// Pre-fill user/password if found in the keychain.
|
||||
//
|
||||
KCItemRef ignore;
|
||||
if([mKeychain getUsernameAndPassword:(NSString*)host port:port user:username password:password item:&ignore]) {
|
||||
if([keychain getUsernameAndPassword:(NSString*)host port:port user:username password:password item:&ignore]) {
|
||||
if ( user )
|
||||
*user = [username createNewUnicodeBuffer];
|
||||
if ( pwd )
|
||||
@ -427,10 +605,12 @@ KeychainPrompt::ProcessPrompt(const PRUnichar* realm, bool checked, PRUnichar* u
|
||||
NSString* username = [NSString stringWithPRUnichars:user];
|
||||
NSString* password = [NSString stringWithPRUnichars:pwd];
|
||||
|
||||
KeychainService* keychain = [KeychainService instance];
|
||||
|
||||
NSMutableString* origUsername = [NSMutableString string];
|
||||
NSMutableString* origPwd = [NSMutableString string];
|
||||
KCItemRef itemRef;
|
||||
bool found = [mKeychain getUsernameAndPassword:(NSString*)host port:port user:origUsername password:origPwd item:&itemRef];
|
||||
bool found = [keychain getUsernameAndPassword:(NSString*)host port:port user:origUsername password:origPwd item:&itemRef];
|
||||
|
||||
//
|
||||
// Update, store or remove the user/password depending on the user
|
||||
@ -438,11 +618,11 @@ KeychainPrompt::ProcessPrompt(const PRUnichar* realm, bool checked, PRUnichar* u
|
||||
// keychain.
|
||||
//
|
||||
if(checked && !found)
|
||||
[mKeychain storeUsernameAndPassword:(NSString*)host port:port user:username password:password];
|
||||
[keychain storeUsernameAndPassword:(NSString*)host port:port user:username password:password];
|
||||
else if(checked && found && (![origUsername isEqualToString:username] || ![origPwd isEqualToString:password]))
|
||||
[mKeychain updateUsernameAndPassword:(NSString*)host port:port user:username password:password item:itemRef];
|
||||
[keychain updateUsernameAndPassword:(NSString*)host port:port user:username password:password item:itemRef];
|
||||
else if(!checked && found)
|
||||
[mKeychain removeUsernameAndPassword:(NSString*)host port:port item:itemRef];
|
||||
[keychain removeUsernameAndPassword:(NSString*)host port:port item:itemRef];
|
||||
}
|
||||
|
||||
//
|
||||
@ -476,7 +656,7 @@ KeychainPrompt::PromptUsernameAndPassword(const PRUnichar *dialogTitle,
|
||||
{
|
||||
PreFill(realm, user, pwd);
|
||||
|
||||
PRBool checked = [mKeychain isEnabled];
|
||||
PRBool checked = [[KeychainService instance] isEnabled];
|
||||
PRUnichar* checkTitle = [NSLocalizedString(@"KeychainCheckTitle", @"") createNewUnicodeBuffer];
|
||||
|
||||
nsresult rv = mPrompt->PromptUsernameAndPassword(dialogTitle, text, user, pwd, checkTitle, &checked, _retval);
|
||||
@ -501,7 +681,7 @@ KeychainPrompt::PromptPassword(const PRUnichar *dialogTitle,
|
||||
{
|
||||
PreFill(realm, nsnull, pwd);
|
||||
|
||||
PRBool checked = [mKeychain isEnabled];
|
||||
PRBool checked = [[KeychainService instance] isEnabled];
|
||||
PRUnichar* checkTitle = [NSLocalizedString(@"KeychainCheckTitle", @"") createNewUnicodeBuffer];
|
||||
|
||||
nsresult rv = mPrompt->PromptPassword(dialogTitle, text, pwd, checkTitle, &checked, _retval);
|
||||
@ -530,7 +710,7 @@ NS_IMPL_ISUPPORTS2(KeychainFormSubmitObserver,
|
||||
nsIObserver,
|
||||
nsIFormSubmitObserver)
|
||||
|
||||
KeychainFormSubmitObserver::KeychainFormSubmitObserver(KeychainService* keychain) : mKeychain(keychain)
|
||||
KeychainFormSubmitObserver::KeychainFormSubmitObserver()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
//NSLog(@"Keychain form submit observer created.");
|
||||
@ -551,7 +731,8 @@ NS_IMETHODIMP
|
||||
KeychainFormSubmitObserver::Notify(nsIContent* node, nsIDOMWindowInternal* window, nsIURI* actionURL,
|
||||
PRBool* cancelSubmit)
|
||||
{
|
||||
if (![mKeychain isEnabled])
|
||||
KeychainService* keychain = [KeychainService instance];
|
||||
if (![keychain isEnabled])
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> formNode(do_QueryInterface(node));
|
||||
@ -590,25 +771,41 @@ KeychainFormSubmitObserver::Notify(nsIContent* node, nsIDOMWindowInternal* windo
|
||||
docURL->GetHost(host);
|
||||
docURL->GetPort(&port);
|
||||
|
||||
// is the host in the deny list? if yes, bail. otherwise check the keychain.
|
||||
NSString* realm = [NSString stringWithCString:host.get()];
|
||||
if ( [keychain isHostInDenyList:realm] )
|
||||
return NS_OK;
|
||||
|
||||
//
|
||||
// If there's already an entry in the keychain, check if the username
|
||||
// and password match. If not, ask the user what they want to do and replace
|
||||
// it as necessary. If there's no entry, ask if they want to remember it
|
||||
// and then put it into the keychain
|
||||
//
|
||||
NSString* realm = [NSString stringWithCString:host.get()];
|
||||
NSString* existingUser = [NSMutableString string];
|
||||
NSString* existingPassword = [NSMutableString string];
|
||||
KCItemRef itemRef;
|
||||
BOOL foundExistingPassword = [mKeychain getUsernameAndPassword:realm port:port user:existingUser password:existingPassword item:&itemRef];
|
||||
BOOL foundExistingPassword = [keychain getUsernameAndPassword:realm port:port user:existingUser password:existingPassword item:&itemRef];
|
||||
if ( foundExistingPassword ) {
|
||||
if ( !([existingUser isEqualToString:username] && [existingPassword isEqualToString:password]) )
|
||||
if ( CheckChangeDataYN(window) )
|
||||
[mKeychain updateUsernameAndPassword:realm port:port user:username password:password item:itemRef];
|
||||
[keychain updateUsernameAndPassword:realm port:port user:username password:password item:itemRef];
|
||||
}
|
||||
else {
|
||||
if (CheckStorePasswordYN(window))
|
||||
[mKeychain storeUsernameAndPassword:realm port:port user:username password:password];
|
||||
switch (CheckStorePasswordYN(window)) {
|
||||
case kSave:
|
||||
[keychain storeUsernameAndPassword:realm port:port user:username password:password];
|
||||
break;
|
||||
|
||||
case kNeverRemember:
|
||||
// tell the keychain we never want to be prompted about this host again
|
||||
[keychain addHostToDenyList:realm];
|
||||
break;
|
||||
|
||||
case kDontRemember:
|
||||
// do nothing at all
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -644,12 +841,11 @@ KeychainFormSubmitObserver::GetNSWindow(nsIDOMWindowInternal* inWindow)
|
||||
return nswindow;
|
||||
}
|
||||
|
||||
BOOL
|
||||
KeychainPromptResult
|
||||
KeychainFormSubmitObserver::CheckStorePasswordYN(nsIDOMWindowInternal* window)
|
||||
{
|
||||
NSWindow* nswindow = GetNSWindow(window);
|
||||
nsAlertController* dialog = CHBrowserService::GetAlertController();
|
||||
return [dialog confirmStorePassword:nswindow];
|
||||
return [[KeychainService instance] confirmStorePassword:nswindow];
|
||||
}
|
||||
|
||||
|
||||
@ -657,16 +853,14 @@ BOOL
|
||||
KeychainFormSubmitObserver::CheckChangeDataYN(nsIDOMWindowInternal* window)
|
||||
{
|
||||
NSWindow* nswindow = GetNSWindow(window);
|
||||
nsAlertController* dialog = CHBrowserService::GetAlertController();
|
||||
return [dialog confirmChangedPassword:nswindow];
|
||||
return [[KeychainService instance] confirmChangedPassword:nswindow];
|
||||
}
|
||||
|
||||
@implementation KeychainBrowserListener
|
||||
|
||||
- (id)initWithBrowser:(KeychainService*)keychain browser:(CHBrowserView*)aBrowser
|
||||
- (id)initWithBrowser:(CHBrowserView*)aBrowser
|
||||
{
|
||||
if ( (self = [super init]) ) {
|
||||
mKeychain = keychain;
|
||||
mBrowserView = aBrowser;
|
||||
}
|
||||
return self;
|
||||
@ -683,7 +877,8 @@ KeychainFormSubmitObserver::CheckChangeDataYN(nsIDOMWindowInternal* window)
|
||||
if(!succeeded)
|
||||
return;
|
||||
|
||||
if(![mKeychain isEnabled] || ![mKeychain isAutoFillEnabled])
|
||||
KeychainService* keychain = [KeychainService instance];
|
||||
if(![keychain isEnabled] || ![keychain isAutoFillEnabled])
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> domWin = getter_AddRefs([mBrowserView getContentWindow]);
|
||||
@ -750,7 +945,7 @@ KeychainFormSubmitObserver::CheckChangeDataYN(nsIDOMWindowInternal* window)
|
||||
docURL->GetPort(&port);
|
||||
|
||||
KCItemRef ignore;
|
||||
if ([mKeychain getUsernameAndPassword:hostStr port:port user:username password:password item:&ignore]) {
|
||||
if ([keychain getUsernameAndPassword:hostStr port:port user:username password:password item:&ignore]) {
|
||||
nsAutoString user, pwd;
|
||||
[username assignTo_nsAString:user];
|
||||
[password assignTo_nsAString:pwd];
|
||||
|
@ -286,7 +286,7 @@ static nsresult MakeFaviconURIFromURI(const nsAString& inURIString, nsAString& o
|
||||
NSImage* faviconImage = nil;
|
||||
|
||||
NS_DURING
|
||||
faviconImage = [[NSImage alloc] initWithData:data];
|
||||
faviconImage = [[[NSImage alloc] initWithData:data] autorelease];
|
||||
NS_HANDLER
|
||||
NSLog(@"Exception \"%@ making\" favicon image for %@", localException, inURI);
|
||||
faviconImage = nil;
|
||||
|
@ -53,8 +53,6 @@
|
||||
IBOutlet id confirmPanelText;
|
||||
IBOutlet id confirmPanelButton1;
|
||||
IBOutlet id confirmPanelButton2;
|
||||
IBOutlet id confirmStorePasswordPanel;
|
||||
IBOutlet id confirmChangePasswordPanel;
|
||||
IBOutlet id promptPanel;
|
||||
IBOutlet id promptPanelCheck;
|
||||
IBOutlet id promptPanelText;
|
||||
@ -90,8 +88,6 @@
|
||||
- (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)confirmStorePassword:(NSWindow*)parent;
|
||||
- (BOOL)confirmChangedPassword:(NSWindow*)parent;
|
||||
|
||||
- (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;
|
||||
|
@ -154,19 +154,6 @@ enum { kOKButton = 0, kCancelButton = 1, kOtherButton = 2 };
|
||||
return result;
|
||||
}
|
||||
|
||||
- (BOOL)confirmStorePassword:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:confirmStorePasswordPanel relativeToWindow:parent];
|
||||
[confirmStorePasswordPanel close];
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (BOOL)confirmChangedPassword:(NSWindow*)parent
|
||||
{
|
||||
int result = [NSApp runModalForWindow:confirmChangePasswordPanel relativeToWindow:parent];
|
||||
[confirmChangePasswordPanel close];
|
||||
return (result == kOKButton);
|
||||
}
|
||||
|
||||
- (BOOL)prompt:(NSWindow*)parent title:(NSString*)title text:(NSString*)text promptText:(NSMutableString*)promptText checkMsg:(NSString*)checkMsg checkValue:(BOOL*)checkValue doCheck:(BOOL)doCheck
|
||||
{
|
||||
|
@ -20,6 +20,8 @@
|
||||
* 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
|
||||
@ -38,49 +40,72 @@
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import "CHDownloadProgressDisplay.h"
|
||||
#import "CHStackView.h"
|
||||
|
||||
#include "nscore.h"
|
||||
/*
|
||||
How ProgressViewController and ProgressDlgController work.
|
||||
|
||||
ProgressDlgController manages the window the the downloads are displayed in.
|
||||
It contains a single CHStackView, a custom class that asks its datasource
|
||||
for a list of views to display, in a similar fashion to the way NSTableView
|
||||
asks its datasource for data to display. There is a single instance of
|
||||
ProgressDlgController, returned by +sharedDownloadController.
|
||||
|
||||
The ProgressDlgController is a subclass of CHDownloadController, which
|
||||
means that it gets asked to create new objects conforming to the
|
||||
CHDownloadProgressDisplay protocol, which are used to display
|
||||
the progress of a single download. It does so by returning instances of
|
||||
ProgressViewController, which manage an NSView that contains a progress
|
||||
indicator, some text fields for status info and a cancel button.
|
||||
|
||||
After a ProgressViewController is requested, the CHStackView is reloaded,
|
||||
which causes it to ask the ProgressDlgController (it's datasource) to
|
||||
provide it with a list of all the subviews to be diaplyed. It calculates
|
||||
it's new frame, and arranges the subviews in a vertical list.
|
||||
|
||||
The ProgressDlgController now needs to resize its window. It knows when
|
||||
to do this because is watches for changes in the CHStackViews frame (using
|
||||
NSViews built in NSNotification for this).
|
||||
|
||||
|
||||
Expanding/contracting download progress views
|
||||
|
||||
When a disclosure triangle is clicked, the ProgressViewController just swaps
|
||||
the expanded view for a smaller one. It saves the new state as the users
|
||||
preference for "browser.download.compactView". If the option key was held down,
|
||||
a notification is posted (that all ProgressViewControllers listen for) that
|
||||
makes all ProgressViewControllers change their state to the new state of the sender.
|
||||
|
||||
class nsIWebBrowserPersist;
|
||||
class nsISupports;
|
||||
class nsIInputStream;
|
||||
class nsDownloadListener;
|
||||
*/
|
||||
|
||||
#import "CHDownloadProgressDisplay.h"
|
||||
|
||||
@interface ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
@end
|
||||
|
||||
|
||||
@interface ProgressDlgController : NSWindowController <CHDownloadProgressDisplay>
|
||||
@interface ProgressDlgController : NSWindowController<CHDownloadDisplayFactory, CHStackViewDataSource>
|
||||
{
|
||||
IBOutlet NSTextField *mElapsedTimeLabel;
|
||||
IBOutlet NSTextField *mFromField;
|
||||
IBOutlet NSTextField *mStatusLabel;
|
||||
IBOutlet NSTextField *mTimeLeftLabel;
|
||||
IBOutlet NSTextField *mToField;
|
||||
IBOutlet NSProgressIndicator *mProgressBar;
|
||||
|
||||
NSToolbarItem *leaveOpenToggleToolbarItem;
|
||||
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDoingAutoFileDownload;
|
||||
BOOL mIsFileSave;
|
||||
BOOL mDownloadIsComplete;
|
||||
long mCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
|
||||
CHDownloader *mDownloader; // we hold a ref to this
|
||||
NSTimer *mDownloadTimer;
|
||||
IBOutlet CHStackView *mStackView;
|
||||
IBOutlet NSScrollView *mScrollView;
|
||||
IBOutlet NSTextField *mNoDownloadsText;
|
||||
|
||||
NSSize mDefaultWindowSize;
|
||||
NSTimer *mDownloadTimer;
|
||||
NSMutableArray *mProgressViewControllers;
|
||||
int mNumActiveDownloads;
|
||||
}
|
||||
|
||||
+ (int)numDownloadInProgress;
|
||||
+ (ProgressDlgController *)sharedDownloadController;
|
||||
|
||||
-(void)autosaveWindowFrame;
|
||||
- (int)numDownloadsInProgress;
|
||||
|
||||
-(void) setupDownloadTimer;
|
||||
-(void) killDownloadTimer;
|
||||
-(void) setDownloadProgress:(NSTimer *)aTimer;
|
||||
-(NSString *) formatTime:(int)aSeconds;
|
||||
-(NSString *) formatFuzzyTime:(int)aSeconds;
|
||||
-(NSString *) formatBytes:(float)aBytes;
|
||||
- (void)autosaveWindowFrame;
|
||||
|
||||
- (void)setupDownloadTimer;
|
||||
- (void)killDownloadTimer;
|
||||
- (void)setDownloadProgress:(NSTimer *)aTimer;
|
||||
|
||||
- (void)didStartDownload:(id <CHDownloadProgressDisplay>)progressDisplay;
|
||||
- (void)didEndDownload:(id <CHDownloadProgressDisplay>)progressDisplay;
|
||||
- (void)removeDownload:(id <CHDownloadProgressDisplay>)progressDisplay;
|
||||
|
||||
- (NSApplicationTerminateReply)allowTerminate;
|
||||
|
||||
@end
|
||||
|
@ -20,6 +20,7 @@
|
||||
* 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
|
||||
@ -35,504 +36,319 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "NSView+Utils.h"
|
||||
|
||||
#import "ProgressDlgController.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *ShowFileToolbarItemIdentifier = @"Show File Toolbar Item";
|
||||
static NSString *OpenFileToolbarItemIdentifier = @"Open File Toolbar Item";
|
||||
static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar Item";
|
||||
#import "ProgressViewController.h"
|
||||
#import "PreferenceManager.h"
|
||||
|
||||
static NSString *ProgressWindowFrameSaveName = @"ProgressWindow";
|
||||
|
||||
@implementation ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<CHDownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
NSWindowController* progressController = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
NSAssert([progressController conformsToProtocol:@protocol(CHDownloadProgressDisplay)],
|
||||
@"progressController should conform to CHDownloadProgressDisplay protocol");
|
||||
return progressController;
|
||||
}
|
||||
|
||||
@interface ProgressDlgController(PrivateProgressDlgController)
|
||||
|
||||
- (void)resizeWindowToFit;
|
||||
- (void)rebuildViews;
|
||||
- (NSSize)windowSizeForStackSize:(NSSize)stackSize;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
@interface ProgressDlgController(Private)
|
||||
-(void)setupToolbar;
|
||||
@end
|
||||
|
||||
@implementation ProgressDlgController
|
||||
|
||||
static int gNumActiveDownloads = 0;
|
||||
static id gSharedProgressController = nil;
|
||||
|
||||
+ (int)numDownloadInProgress
|
||||
+ (ProgressDlgController *)sharedDownloadController;
|
||||
{
|
||||
return gNumActiveDownloads;
|
||||
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 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);
|
||||
if (self == gSharedProgressController)
|
||||
gSharedProgressController = nil;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[mProgressViewControllers release];
|
||||
[mNoDownloadsText release];
|
||||
[self killDownloadTimer];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
- (void)didStartDownload:(id <CHDownloadProgressDisplay>)progressDisplay
|
||||
{
|
||||
[super windowDidLoad];
|
||||
|
||||
mDownloadIsComplete = NO;
|
||||
mDoingAutoFileDownload = NO;
|
||||
[self showWindow:nil]; // make sure the window is visible
|
||||
|
||||
if (!mIsFileSave) {
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
PRBool save = PR_FALSE;
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive", &save);
|
||||
mSaveFileDialogShouldStayOpen = save;
|
||||
|
||||
PRBool autoHelperDispatch = PR_FALSE;
|
||||
prefs->GetBoolPref("browser.download.autoDispatch", &autoHelperDispatch);
|
||||
mDoingAutoFileDownload = autoHelperDispatch;
|
||||
[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 setupToolbar];
|
||||
[mProgressBar setUsesThreadedAnimation:YES];
|
||||
[mProgressBar startAnimation:self]; // move to onStateChange
|
||||
[self rebuildViews];
|
||||
}
|
||||
|
||||
- (void)setupToolbar
|
||||
- (void)stackViewResized:(NSNotification *)notification
|
||||
{
|
||||
NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:SaveFileToolbarIdentifier] autorelease];
|
||||
|
||||
[toolbar setDisplayMode:NSToolbarDisplayModeDefault];
|
||||
[toolbar setAllowsUserCustomization:YES];
|
||||
[toolbar setAutosavesConfiguration:YES];
|
||||
[toolbar setDelegate:self];
|
||||
[[self window] setToolbar:toolbar];
|
||||
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];
|
||||
}
|
||||
|
||||
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
|
||||
// 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
|
||||
{
|
||||
return [NSArray arrayWithObjects: CancelToolbarItemIdentifier,
|
||||
ShowFileToolbarItemIdentifier,
|
||||
OpenFileToolbarItemIdentifier,
|
||||
LeaveOpenToolbarItemIdentifier,
|
||||
NSToolbarCustomizeToolbarItemIdentifier,
|
||||
NSToolbarFlexibleSpaceItemIdentifier,
|
||||
NSToolbarSpaceItemIdentifier,
|
||||
NSToolbarSeparatorItemIdentifier,
|
||||
nil];
|
||||
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;
|
||||
}
|
||||
|
||||
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
|
||||
- (void)resizeWindowToFit
|
||||
{
|
||||
return [NSArray arrayWithObjects: CancelToolbarItemIdentifier,
|
||||
NSToolbarFlexibleSpaceItemIdentifier,
|
||||
LeaveOpenToolbarItemIdentifier,
|
||||
NSToolbarFlexibleSpaceItemIdentifier,
|
||||
ShowFileToolbarItemIdentifier,
|
||||
OpenFileToolbarItemIdentifier,
|
||||
nil];
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem
|
||||
- (void)rebuildViews
|
||||
{
|
||||
if ([toolbarItem action] == @selector(cancel)) // cancel button
|
||||
return (!mDownloadIsComplete);
|
||||
if ([toolbarItem action] == @selector(pauseAndResumeDownload)) // pause/resume button
|
||||
return (NO); // Hey - it hasn't been hooked up yet. !mDownloadIsComplete when it is.
|
||||
if ([toolbarItem action] == @selector(showFile)) // show file
|
||||
return (mDownloadIsComplete);
|
||||
if ([toolbarItem action] == @selector(openFile)) // open file
|
||||
return (mDownloadIsComplete);
|
||||
return YES; // turn it on otherwise.
|
||||
[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];
|
||||
}
|
||||
|
||||
- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar
|
||||
itemForItemIdentifier:(NSString *)itemIdent
|
||||
willBeInsertedIntoToolbar:(BOOL)willBeInserted
|
||||
{
|
||||
NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdent] autorelease];
|
||||
|
||||
if ( [itemIdent isEqual:CancelToolbarItemIdentifier] )
|
||||
{
|
||||
[toolbarItem setLabel:NSLocalizedString(@"Cancel",@"Cancel")];
|
||||
[toolbarItem setPaletteLabel:NSLocalizedString(@"CancelPaletteLabel",@"Cancel Download")];
|
||||
[toolbarItem setToolTip:NSLocalizedString(@"CancelToolTip",@"Cancel this file download")];
|
||||
[toolbarItem setImage:[NSImage imageNamed:@"saveCancel"]];
|
||||
[toolbarItem setTarget:self];
|
||||
[toolbarItem setAction:@selector(cancel)];
|
||||
}
|
||||
else if ( [itemIdent isEqual:ShowFileToolbarItemIdentifier] )
|
||||
{
|
||||
[toolbarItem setLabel:NSLocalizedString(@"Show File",@"Show File")];
|
||||
[toolbarItem setPaletteLabel:NSLocalizedString(@"Show File",@"Show File")];
|
||||
[toolbarItem setToolTip:NSLocalizedString(@"ShowToolTip",@"Show the saved file in the Finder")];
|
||||
[toolbarItem setImage:[NSImage imageNamed:@"saveShowFile"]];
|
||||
[toolbarItem setTarget:self];
|
||||
[toolbarItem setAction:@selector(showFile)];
|
||||
}
|
||||
else if ( [itemIdent isEqual:OpenFileToolbarItemIdentifier] )
|
||||
{
|
||||
[toolbarItem setLabel:NSLocalizedString(@"Open File",@"Open File")];
|
||||
[toolbarItem setPaletteLabel:NSLocalizedString(@"Open File",@"Open File")];
|
||||
[toolbarItem setToolTip:NSLocalizedString(@"OpenToolTip",@"Open the saved file in its default application.")];
|
||||
[toolbarItem setImage:[NSImage imageNamed:@"saveOpenFile"]];
|
||||
[toolbarItem setTarget:self];
|
||||
[toolbarItem setAction:@selector(openFile)];
|
||||
}
|
||||
else if ( [itemIdent isEqual:LeaveOpenToolbarItemIdentifier] )
|
||||
{
|
||||
if ( !mIsFileSave && !mDoingAutoFileDownload )
|
||||
{
|
||||
if ( mSaveFileDialogShouldStayOpen )
|
||||
{
|
||||
[toolbarItem setLabel:NSLocalizedString(@"Leave Open",@"Leave Open")];
|
||||
[toolbarItem setPaletteLabel:NSLocalizedString(@"Toggle Close Behavior",@"Toggle Close Behavior")];
|
||||
[toolbarItem setToolTip:NSLocalizedString(@"LeaveOpenToolTip",@"Window will stay open when download finishes.")];
|
||||
[toolbarItem setImage:[NSImage imageNamed:@"saveLeaveOpenYES"]];
|
||||
[toolbarItem setTarget:self];
|
||||
[toolbarItem setAction:@selector(toggleLeaveOpen)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[toolbarItem setLabel:NSLocalizedString(@"Close When Done",@"Close When Done")];
|
||||
[toolbarItem setPaletteLabel:NSLocalizedString(@"Toggle Close Behavior",@"Toggle Close Behavior")];
|
||||
[toolbarItem setToolTip:NSLocalizedString(@"CloseWhenDoneToolTip",@"Window will close automatically when download finishes.")];
|
||||
[toolbarItem setImage:[NSImage imageNamed:@"saveLeaveOpenNO"]];
|
||||
[toolbarItem setTarget:self];
|
||||
[toolbarItem setAction:@selector(toggleLeaveOpen)];
|
||||
}
|
||||
if ( willBeInserted )
|
||||
{
|
||||
leaveOpenToggleToolbarItem = toolbarItem; //establish reference
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
toolbarItem = nil;
|
||||
}
|
||||
|
||||
return toolbarItem;
|
||||
}
|
||||
|
||||
-(void)cancel
|
||||
{
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->CancelDownload();
|
||||
|
||||
// clean up downloaded file. - do it here on in CancelDownload?
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSString *thePath = [[mToField stringValue] stringByExpandingTildeInPath];
|
||||
if ([fileManager isDeletableFileAtPath:thePath])
|
||||
// if we delete it, fantastic. if not, oh well. better to move to trash instead?
|
||||
[fileManager removeFileAtPath:thePath handler:nil];
|
||||
|
||||
// we can _not_ set the |mDownloadIsComplete| flag here because the download really
|
||||
// isn't done yet. We'll probably continue to process more PLEvents that are already
|
||||
// in the queue until we get a STATE_STOP state change. As a result, we just keep
|
||||
// going until that comes in (and it will, because we called CancelDownload() above).
|
||||
// Ensure that the window goes away when we get there by flipping the 'stay alive'
|
||||
// flag. (bug 154913)
|
||||
mSaveFileDialogShouldStayOpen = NO;
|
||||
}
|
||||
|
||||
-(void)showFile
|
||||
{
|
||||
NSString *theFile = [[mToField stringValue] stringByExpandingTildeInPath];
|
||||
if ([[NSWorkspace sharedWorkspace] selectFile:theFile
|
||||
inFileViewerRootedAtPath:[theFile stringByDeletingLastPathComponent]])
|
||||
return;
|
||||
// hmmm. it didn't work. that's odd. need localized error messages. for now, just beep.
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
-(void)openFile
|
||||
{
|
||||
NSString *theFile = [[mToField stringValue] stringByExpandingTildeInPath];
|
||||
if ([[NSWorkspace sharedWorkspace] openFile:theFile])
|
||||
return;
|
||||
// hmmm. it didn't work. that's odd. need localized error message. for now, just beep.
|
||||
NSBeep();
|
||||
|
||||
}
|
||||
|
||||
-(void)toggleLeaveOpen
|
||||
{
|
||||
if ( ! mSaveFileDialogShouldStayOpen ) {
|
||||
mSaveFileDialogShouldStayOpen = YES;
|
||||
[leaveOpenToggleToolbarItem setLabel:NSLocalizedString(@"Leave Open",@"Leave Open")];
|
||||
[leaveOpenToggleToolbarItem setPaletteLabel:NSLocalizedString(@"Toggle Close Behavior",@"Toggle Close Behavior")];
|
||||
[leaveOpenToggleToolbarItem setToolTip:NSLocalizedString(@"LeaveOpenToolTip",@"Window will stay open when download finishes.")];
|
||||
[leaveOpenToggleToolbarItem setImage:[NSImage imageNamed:@"saveLeaveOpenYES"]];
|
||||
} else {
|
||||
mSaveFileDialogShouldStayOpen = NO;
|
||||
[leaveOpenToggleToolbarItem setLabel:NSLocalizedString(@"Close When Done",@"Close When Done")];
|
||||
[leaveOpenToggleToolbarItem setPaletteLabel:NSLocalizedString(@"Toggle Close Behavior",@"Toggle Close Behavior")];
|
||||
[leaveOpenToggleToolbarItem setToolTip:NSLocalizedString(@"CloseWhenDoneToolTip",@"Window will close automatically when download finishes.")];
|
||||
[leaveOpenToggleToolbarItem setImage:[NSImage imageNamed:@"saveLeaveOpenNO"]];
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
prefs->SetBoolPref("browser.download.progressDnldDialog.keepAlive", mSaveFileDialogShouldStayOpen);
|
||||
[[self window] saveFrameUsingName:ProgressWindowFrameSaveName];
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
[self autosaveWindowFrame];
|
||||
[self autorelease];
|
||||
}
|
||||
|
||||
- (BOOL)windowShouldClose:(NSNotification *)notification
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
if (!mDownloadIsComplete) { //whoops. hard cancel.
|
||||
[self cancel];
|
||||
return NO; // let setDownloadProgress handle the close.
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)killDownloadTimer
|
||||
{
|
||||
if (mDownloadTimer) {
|
||||
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];
|
||||
}
|
||||
|
||||
-(NSString *)formatTime:(int)seconds
|
||||
{
|
||||
NSMutableString *theTime =[[[NSMutableString alloc] initWithCapacity:8] autorelease];
|
||||
[theTime setString:@""];
|
||||
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 alloc] initWithFormat:NSLocalizedString(@"UnderSec",@"Under %d seconds"),5] autorelease];
|
||||
if (seconds < 13)
|
||||
return [[[NSString alloc] initWithFormat:NSLocalizedString(@"UnderSec",@"Under %d seconds"),10] autorelease];
|
||||
return [[[NSString alloc] initWithString:NSLocalizedString(@"UnderMin",@"Under a minute")] autorelease];
|
||||
}
|
||||
// seconds becomes minutes and we keep checking.
|
||||
seconds = seconds/60;
|
||||
if (seconds < 60) {
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:NSLocalizedString(@"AboutMin",@"About a minute")] autorelease];
|
||||
// OK, tell the good people how much time we have left.
|
||||
return [[[NSString alloc] initWithFormat:NSLocalizedString(@"AboutMins",@"About %d minutes"),seconds] autorelease];
|
||||
}
|
||||
//this download will never seemingly never end. now seconds become hours.
|
||||
seconds = seconds/60;
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:NSLocalizedString(@"AboutHour",@"Over an hour")] autorelease];
|
||||
return [[[NSString alloc] initWithFormat:NSLocalizedString(@"AboutHours",@"Over %d hours"),seconds] autorelease];
|
||||
}
|
||||
|
||||
|
||||
-(NSString *)formatBytes:(float)bytes
|
||||
{ // this is simpler than my first try. I peaked at Omnigroup byte formatting code.
|
||||
// if bytes are negative, we return question marks.
|
||||
if (bytes < 0)
|
||||
return [[[NSString alloc] initWithString:@"???"] autorelease];
|
||||
// bytes first.
|
||||
if (bytes < 1024)
|
||||
return [[[NSString alloc] initWithFormat:@"%.1f bytes",bytes] autorelease];
|
||||
// kb
|
||||
bytes = bytes/1024;
|
||||
if (bytes < 1024)
|
||||
return [[[NSString alloc] initWithFormat:@"%.1f KB",bytes] autorelease];
|
||||
// mb
|
||||
bytes = bytes/1024;
|
||||
if (bytes < 1024)
|
||||
return [[[NSString alloc] initWithFormat:@"%.1f MB",bytes] autorelease];
|
||||
// gb
|
||||
bytes = bytes/1024;
|
||||
return [[[NSString alloc] initWithFormat:@"%.1f GB",bytes] autorelease];
|
||||
}
|
||||
|
||||
// this handles lots of things.
|
||||
- (void)setDownloadProgress:(NSTimer *)downloadTimer;
|
||||
{
|
||||
// XXX this logic needs cleaning up.
|
||||
|
||||
// Ack! we're closing the window with the download still running!
|
||||
if (mDownloadIsComplete)
|
||||
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)
|
||||
{
|
||||
[[self window] performClose:self];
|
||||
return;
|
||||
// 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;
|
||||
}
|
||||
// get the elapsed time
|
||||
NSArray *elapsedTimeArray = [[mElapsedTimeLabel stringValue] componentsSeparatedByString:@":"];
|
||||
int j = [elapsedTimeArray count];
|
||||
int elapsedSec = [[elapsedTimeArray objectAtIndex:(j-1)] intValue] + [[elapsedTimeArray objectAtIndex:(j-2)] intValue]*60;
|
||||
if (j==3) // this download is taking forever.
|
||||
elapsedSec += [[elapsedTimeArray objectAtIndex:0] intValue]*3600;
|
||||
// update elapsed time
|
||||
[mElapsedTimeLabel setStringValue:[self formatTime:(++elapsedSec)]];
|
||||
// for status field & time left
|
||||
float maxBytes = ([mProgressBar maxValue]);
|
||||
float byteSec = mCurrentProgress/elapsedSec;
|
||||
// OK - if downloadTimer is nil, we're done - fix maxBytes value for status report.
|
||||
if (!downloadTimer)
|
||||
maxBytes = mCurrentProgress;
|
||||
// update status field
|
||||
NSString *labelString = NSLocalizedString(@"LabelString",@"%@ of %@ total (at %@/sec)");
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:mCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
// updating estimated time left field
|
||||
// if maxBytes < 0, can't calc time left.
|
||||
// if !downloadTimer, download is finished. either way, make sure time left is 0.
|
||||
if ((maxBytes > 0) && (downloadTimer))
|
||||
{
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/mCurrentProgress) - elapsedSec);
|
||||
[mTimeLeftLabel setStringValue:[self formatFuzzyTime:secToGo]];
|
||||
}
|
||||
else if (!downloadTimer)
|
||||
{ // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
mDownloadIsComplete = YES; // all done. we got a STATE_STOP
|
||||
[mTimeLeftLabel setStringValue:@""];
|
||||
[self setProgressTo:mCurrentProgress ofMax:mCurrentProgress];
|
||||
if (!mSaveFileDialogShouldStayOpen || mDoingAutoFileDownload)
|
||||
[[self window] performClose:self]; // close window
|
||||
else
|
||||
[[self window] update]; // redraw window
|
||||
}
|
||||
else //maxBytes is undetermined. Set remaining time to question marks.
|
||||
[mTimeLeftLabel setStringValue:@"???"];
|
||||
|
||||
return NSTerminateNow;
|
||||
}
|
||||
|
||||
- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
|
||||
{
|
||||
[NSApp stopModalWithCode:returnCode];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// CHDownloadProgressDisplay protocol methods
|
||||
|
||||
- (void)onStartDownload:(BOOL)isFileSave;
|
||||
// implement to zoom to a size that just fits the contents
|
||||
- (NSRect)windowWillUseStandardFrame:(NSWindow *)sender defaultFrame:(NSRect)defaultFrame
|
||||
{
|
||||
mIsFileSave = isFileSave;
|
||||
NSSize scrollFrameSize = [NSScrollView frameSizeForContentSize:[mStackView bounds].size
|
||||
hasHorizontalScroller:NO hasVerticalScroller:YES borderType:NSNoBorder];
|
||||
|
||||
[self window]; // make the window
|
||||
[[self window] setFrameUsingName: ProgressWindowFrameSaveName];
|
||||
NSSize curScrollFrameSize = [mScrollView frame].size;
|
||||
float frameDelta = (scrollFrameSize.height - curScrollFrameSize.height);
|
||||
|
||||
[self showWindow: self];
|
||||
[self setupDownloadTimer];
|
||||
|
||||
gNumActiveDownloads++;
|
||||
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;
|
||||
}
|
||||
|
||||
- (void)onEndDownload
|
||||
#pragma mark -
|
||||
|
||||
/*
|
||||
CHStackView datasource methods
|
||||
*/
|
||||
|
||||
- (int)subviewsForStackView:(CHStackView *)stackView
|
||||
{
|
||||
gNumActiveDownloads --;
|
||||
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];
|
||||
|
||||
// if we're quitting, our progress window is already gone and we're in the
|
||||
// process of shutting down gecko and all the d/l listeners. The timer, at
|
||||
// that point, is the only thing keeping us alive. Killing it will cause
|
||||
// us to go away immediately, so kung-fu deathgrip it until we're done twiddling
|
||||
// bits on ourself.
|
||||
[self retain]; // Enter The Dragon!
|
||||
[self killDownloadTimer];
|
||||
[self setDownloadProgress:nil];
|
||||
[self release];
|
||||
}
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress
|
||||
{
|
||||
mCurrentProgress = aCurProgress; // fall back for stat calcs
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
- (void)setSourceURL:(NSString*)aSourceURL
|
||||
{
|
||||
[mFromField setStringValue: aSourceURL];
|
||||
[mFromField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
- (void)setDestinationPath:(NSString*)aDestPath
|
||||
{
|
||||
[mToField setStringValue: [aDestPath stringByAbbreviatingWithTildeInPath]];
|
||||
[mToField display]; // force an immmeditate update
|
||||
|
||||
// also set the window title
|
||||
NSString* downloadFileName = [aDestPath lastPathComponent];
|
||||
if ([downloadFileName length] == 0)
|
||||
downloadFileName = aDestPath;
|
||||
|
||||
[[self window] setTitle:[NSString stringWithFormat:NSLocalizedString(@"DownloadingTitle", @""), downloadFileName]];
|
||||
return newController;
|
||||
}
|
||||
|
||||
@end
|
||||
|
105
camino/src/download/ProgressViewController.h
Normal file
105
camino/src/download/ProgressViewController.h
Normal file
@ -0,0 +1,105 @@
|
||||
/* -*- 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 "CHDownloadProgressDisplay.h"
|
||||
|
||||
class CHDownloader;
|
||||
@class ProgressDlgController;
|
||||
|
||||
@interface ProgressViewController : NSObject<CHDownloadProgressDisplay>
|
||||
{
|
||||
// we share one progress bar between both views. It's in the expanded
|
||||
// view by default
|
||||
IBOutlet NSProgressIndicator *mProgressBar;
|
||||
|
||||
// in-progress expanded view
|
||||
IBOutlet NSView *mProgressView;
|
||||
IBOutlet NSButton *mExpandedCancelButton;
|
||||
|
||||
// in-progress collapsed view
|
||||
IBOutlet NSView *mProgressViewCompact;
|
||||
|
||||
// completed expanded view
|
||||
IBOutlet NSView *mCompletedView;
|
||||
IBOutlet NSButton *mExpandedRevealButton;
|
||||
IBOutlet NSButton *mExpandedOpenButton;
|
||||
|
||||
// completed collapsed view
|
||||
IBOutlet NSView *mCompletedViewCompact;
|
||||
|
||||
BOOL mViewIsCompact;
|
||||
BOOL mIsFileSave;
|
||||
BOOL mUserCancelled;
|
||||
BOOL mDownloadingError;
|
||||
BOOL mDownloadDone;
|
||||
BOOL mRemoveWhenDone;
|
||||
|
||||
NSTimeInterval mDownloadTime; // only set when done
|
||||
|
||||
long mCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
long mDownloadSize;
|
||||
|
||||
NSString *mSourceURL;
|
||||
NSString *mDestPath;
|
||||
NSDate *mStartTime;
|
||||
|
||||
CHDownloader *mDownloader; // we hold a ref to this
|
||||
|
||||
ProgressDlgController *mProgressWindowController; // not retained
|
||||
}
|
||||
|
||||
+ (NSString *)formatTime:(int)aSeconds;
|
||||
+ (NSString *)formatFuzzyTime:(int)aSeconds;
|
||||
+ (NSString *)formatBytes:(float)aBytes;
|
||||
|
||||
- (NSView *)view;
|
||||
|
||||
- (IBAction)close:(id)sender;
|
||||
|
||||
- (IBAction)stop:(id)sender;
|
||||
- (IBAction)toggleDisclosure:(id)sender;
|
||||
|
||||
- (IBAction)reveal:(id)sender;
|
||||
- (IBAction)open:(id)sender;
|
||||
|
||||
- (BOOL)isActive;
|
||||
|
||||
- (void)setProgressWindowController:(ProgressDlgController*)progressWindowController;
|
||||
|
||||
@end
|
544
camino/src/download/ProgressViewController.mm
Normal file
544
camino/src/download/ProgressViewController.mm
Normal file
@ -0,0 +1,544 @@
|
||||
/* -*- 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
|
@ -56,7 +56,7 @@ public:
|
||||
nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsAString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList);
|
||||
NSView* aFilterView);
|
||||
virtual ~nsHeaderSniffer();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -79,6 +79,5 @@ private:
|
||||
nsCString mContentType;
|
||||
nsCString mContentDisposition;
|
||||
NSView* mFilterView;
|
||||
NSPopUpButton* mFilterList;
|
||||
};
|
||||
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
#import "ChimeraUIConstants.h"
|
||||
|
||||
#include "SaveHeaderSniffer.h"
|
||||
|
||||
#include "netCore.h"
|
||||
@ -56,7 +58,7 @@ const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrows
|
||||
nsHeaderSniffer::nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsAString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList)
|
||||
NSView* aFilterView)
|
||||
: mPersist(aPersist)
|
||||
, mTmpFile(aFile)
|
||||
, mURL(aURL)
|
||||
@ -65,9 +67,8 @@ nsHeaderSniffer::nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile,
|
||||
, mDefaultFilename(aSuggestedFilename)
|
||||
, mBypassCache(aBypassCache)
|
||||
, mFilterView(aFilterView)
|
||||
, mFilterList(aFilterList)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsHeaderSniffer::~nsHeaderSniffer()
|
||||
@ -183,14 +184,16 @@ nsresult nsHeaderSniffer::PerformSave(nsIURI* inOriginalURI)
|
||||
return rv;
|
||||
nsCOMPtr<nsIPrefBranch> dirBranch;
|
||||
prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
|
||||
PRInt32 filterIndex = 0;
|
||||
PRInt32 filterIndex = eSaveFormatHTMLComplete;
|
||||
if (dirBranch) {
|
||||
nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
|
||||
if (NS_FAILED(rv))
|
||||
filterIndex = 0;
|
||||
filterIndex = eSaveFormatHTMLComplete;
|
||||
}
|
||||
if (mFilterList)
|
||||
[mFilterList selectItemAtIndex: filterIndex];
|
||||
|
||||
NSPopUpButton* filterList = [mFilterView viewWithTag:kSaveFormatPopupTag];
|
||||
if (filterList)
|
||||
[filterList selectItemAtIndex: filterIndex];
|
||||
|
||||
// We need to figure out what file name to use.
|
||||
nsAutoString defaultFileName;
|
||||
@ -294,17 +297,17 @@ nsresult nsHeaderSniffer::PerformSave(nsIURI* inOriginalURI)
|
||||
return NS_OK;
|
||||
|
||||
// Update the filter index.
|
||||
if (isHTML && mFilterList) {
|
||||
filterIndex = [mFilterList indexOfSelectedItem];
|
||||
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 == 2)
|
||||
if (isHTML && filterIndex == eSaveFormatPlainText)
|
||||
mContentType = "text/plain";
|
||||
|
||||
nsCOMPtr<nsISupports> sourceData;
|
||||
if (isHTML && filterIndex != 1)
|
||||
if (isHTML && filterIndex != eSaveFormatHTMLSource)
|
||||
sourceData = do_QueryInterface(mDocument);
|
||||
else
|
||||
sourceData = do_QueryInterface(mURL);
|
||||
|
@ -21,6 +21,7 @@
|
||||
*
|
||||
* 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
|
||||
@ -49,6 +50,8 @@
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "nsExternalHelperAppService.h"
|
||||
|
||||
|
||||
@ -56,24 +59,28 @@
|
||||
|
||||
class nsDownloadListener : public CHDownloader,
|
||||
public nsIDownload,
|
||||
public nsIWebProgressListener
|
||||
public nsIWebProgressListener,
|
||||
public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(DownloadControllerFactory* inDownloadControllerFactory);
|
||||
nsDownloadListener();
|
||||
virtual ~nsDownloadListener();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
// nsITimerCallback
|
||||
NS_IMETHOD Notify(nsITimer *timer);
|
||||
|
||||
public:
|
||||
//void BeginDownload();
|
||||
|
||||
void InitDialog();
|
||||
|
||||
virtual void PauseDownload();
|
||||
virtual void ResumeDownload();
|
||||
virtual void CancelDownload();
|
||||
virtual void DownloadDone();
|
||||
virtual void DownloadDone(nsresult aStatus);
|
||||
virtual void DetachDownloadDisplay();
|
||||
|
||||
private:
|
||||
@ -84,10 +91,13 @@ private:
|
||||
|
||||
nsCOMPtr<nsIURI> mURI; // The URI of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
nsCOMPtr<nsITimer> mEndRefreshTimer; // Timer used to update the status to done
|
||||
nsresult mDownloadStatus; // status from last nofication
|
||||
PRInt64 mStartTime; // When the download started
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
PRPackedBool mUserCanceled; // true if the user canceled the download
|
||||
PRPackedBool mSentCancel; // true when we've notified the backend of the cancel
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
*
|
||||
* 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
|
||||
@ -46,20 +46,25 @@
|
||||
#include "nsIURL.h"
|
||||
#include "netCore.h"
|
||||
|
||||
nsDownloadListener::nsDownloadListener(DownloadControllerFactory* inControllerFactory)
|
||||
: CHDownloader(inControllerFactory)
|
||||
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_INHERITED2(nsDownloadListener, CHDownloader, nsIDownload, nsIWebProgressListener)
|
||||
NS_IMPL_ISUPPORTS_INHERITED3(nsDownloadListener, CHDownloader, nsIDownload, nsIWebProgressListener, nsITimerCallback)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@ -193,14 +198,14 @@ nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
if (mUserCanceled)
|
||||
if (mUserCanceled && !mSentCancel)
|
||||
{
|
||||
if (mHelperAppLauncher)
|
||||
mHelperAppLauncher->Cancel();
|
||||
else if (aRequest)
|
||||
aRequest->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
mUserCanceled = false;
|
||||
mSentCancel = PR_TRUE;
|
||||
}
|
||||
|
||||
[mDownloadDisplay setProgressTo:aCurTotalProgress ofMax:aMaxTotalProgress];
|
||||
@ -236,7 +241,7 @@ nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *a
|
||||
// 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,
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
@ -250,29 +255,64 @@ nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRe
|
||||
// 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();
|
||||
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
|
||||
[mDownloadDisplay onStartDownload:(BOOL)IsFileSave()];
|
||||
|
||||
if (mURI)
|
||||
{
|
||||
nsCAutoString spec;
|
||||
mURI->GetSpec(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
|
||||
@ -292,19 +332,19 @@ nsDownloadListener::CancelDownload()
|
||||
{
|
||||
mUserCanceled = PR_TRUE;
|
||||
|
||||
if (mWebPersist)
|
||||
if (mWebPersist && !mSentCancel)
|
||||
{
|
||||
mWebPersist->CancelSave();
|
||||
mUserCanceled = PR_FALSE;
|
||||
mSentCancel = PR_TRUE;
|
||||
}
|
||||
|
||||
// delete any files we've created...
|
||||
|
||||
|
||||
// DownloadDone will get called (eventually)
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::DownloadDone()
|
||||
nsDownloadListener::DownloadDone(nsresult aStatus)
|
||||
{
|
||||
// break the reference cycle by removing ourselves as a listener
|
||||
if (mWebPersist)
|
||||
@ -314,8 +354,23 @@ nsDownloadListener::DownloadDone()
|
||||
}
|
||||
|
||||
mHelperAppLauncher = nsnull;
|
||||
|
||||
[mDownloadDisplay onEndDownload];
|
||||
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)];
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -38,7 +38,6 @@
|
||||
#import "NSString+Utils.h"
|
||||
|
||||
#import "CHBrowserService.h"
|
||||
#import "CHDownloadFactories.h"
|
||||
#import "CHBrowserView.h"
|
||||
|
||||
#include "nsIWindowWatcher.h"
|
||||
@ -107,14 +106,6 @@ CHBrowserService::InitEmbedding()
|
||||
static NS_DEFINE_CID(kHelperDlgCID, NS_HELPERAPPLAUNCHERDIALOG_CID);
|
||||
nsresult rv = cr->RegisterFactory(kHelperDlgCID, NS_IHELPERAPPLAUNCHERDLG_CLASSNAME, NS_IHELPERAPPLAUNCHERDLG_CONTRACTID,
|
||||
sSingleton);
|
||||
|
||||
// replace the downloader with our own which does not rely on the xpfe downlaod manager
|
||||
nsCOMPtr<nsIFactory> downloadFactory;
|
||||
rv = NewDownloadListenerFactory(getter_AddRefs(downloadFactory));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
static NS_DEFINE_CID(kDownloadCID, NS_DOWNLOAD_CID);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID, downloadFactory);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -163,9 +163,8 @@ enum {
|
||||
// nsIWebBrowserSetup methods
|
||||
- (void)setProperty:(unsigned int)property toValue:(unsigned int)value;
|
||||
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList;
|
||||
- (void)saveURL: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
|
||||
url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename;
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView;
|
||||
- (void)saveURL:(NSView*)aFilterView url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename;
|
||||
|
||||
- (void)printDocument;
|
||||
- (void)pageSetup;
|
||||
|
@ -430,7 +430,6 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
||||
suggestedFilename: (NSString*)aFileName
|
||||
bypassCache: (BOOL)aBypassCache
|
||||
filterView: (NSView*)aFilterView
|
||||
filterList: (NSPopUpButton*)aFilterList
|
||||
{
|
||||
// Create our web browser persist object. This is the object that knows
|
||||
// how to actually perform the saving of the page (and of the images
|
||||
@ -477,7 +476,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
||||
[aFileName assignTo_nsAString:fileName];
|
||||
nsHeaderSniffer* sniffer = new nsHeaderSniffer(webPersist, tmpFile, aURI,
|
||||
aDocument, postData, fileName, aBypassCache,
|
||||
aFilterView, aFilterList);
|
||||
aFilterView);
|
||||
if (!sniffer)
|
||||
return;
|
||||
webPersist->SetProgressListener(sniffer); // owned
|
||||
@ -572,8 +571,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
||||
return found;
|
||||
}
|
||||
|
||||
- (void)saveURL: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
|
||||
url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename
|
||||
- (void)saveURL: (NSView*)aFilterView url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename
|
||||
{
|
||||
nsCOMPtr<nsIURI> url;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(url), [aURLSpec UTF8String]);
|
||||
@ -584,8 +582,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
||||
withDocument: nsnull
|
||||
suggestedFilename: aFilename
|
||||
bypassCache: YES
|
||||
filterView: aFilterView
|
||||
filterList: aFilterList];
|
||||
filterView: aFilterView];
|
||||
}
|
||||
|
||||
-(NSString*)getFocusedURLString
|
||||
@ -616,7 +613,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
||||
return [NSString stringWith_nsAString: urlStr];
|
||||
}
|
||||
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView
|
||||
{
|
||||
if (!_webBrowser)
|
||||
return;
|
||||
@ -656,8 +653,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
||||
withDocument: domDocument
|
||||
suggestedFilename: @""
|
||||
bypassCache: NO
|
||||
filterView: aFilterView
|
||||
filterList: aFilterList];
|
||||
filterView: aFilterView];
|
||||
}
|
||||
|
||||
-(void)doCommand:(const char*)commandName
|
||||
|
@ -20,6 +20,7 @@
|
||||
*
|
||||
* 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
|
||||
@ -45,19 +46,17 @@
|
||||
1. The CHDownloadProgressDisplay protocol.
|
||||
|
||||
This is a formal protocol that needs to be implemented by
|
||||
a window controller for your progress window. Its methods
|
||||
will be called by the underlying C++ downloading classes.
|
||||
an object (eg. a window controller or a view controller)
|
||||
for your progress window. Its methods will be called by the
|
||||
underlying C++ downloading classes.
|
||||
|
||||
2. The Obj-C DownloadControllerFactory class.
|
||||
|
||||
This class should be subclassed by an embedder, with an
|
||||
implementation of 'createDownloadController' that hands back
|
||||
a new instance of an NSWindowController that implements the
|
||||
<CHDownloadProgressDisplay> protocol.
|
||||
|
||||
The underlying C++ classes use this factory to create the
|
||||
progress window controller.
|
||||
2. The CHDownloadDisplayFactory protocol
|
||||
|
||||
This is a formal protocol that can be implemented by
|
||||
any object that can create objects that themselves
|
||||
implement CHDownloadProgressDisplay. This would probably be
|
||||
an NSWindowController.
|
||||
|
||||
3. The CHDownloader C++ class
|
||||
|
||||
This base class exists to hide the complextity of the download
|
||||
@ -90,10 +89,10 @@
|
||||
|
||||
In both cases, creating the nsDownloadListener and calling its Init() method
|
||||
calls nsDownloder::CreateDownloadDisplay(). The nsDownloder has as a member
|
||||
variable a DownloadControllerFactory (see above), which got passed to it
|
||||
via our XPCOM factory for nsIDownload objects. It then uses that DownloadControllerFactory
|
||||
to get an instance of the download progress window controller, which then
|
||||
shows the download progress window.
|
||||
variable an object that implements CHDownloadDisplayFactory (see above), which got set
|
||||
on it via a call to SetDisplayFactory. It then uses that CHDownloadDisplayFactory
|
||||
to create an instance of the download progress display, which then controls
|
||||
something (like a view or window) that shows in the UI.
|
||||
|
||||
Simple, eh?
|
||||
|
||||
@ -105,13 +104,13 @@
|
||||
|
||||
class CHDownloader;
|
||||
|
||||
// a formal protocol for something that implements progress display
|
||||
// Embedders can make a window controller that conforms to this
|
||||
// A formal protocol for something that implements progress display.
|
||||
// Embedders can make a window or view controller that conforms to this
|
||||
// protocol, and reuse nsDownloadListener to get download UI.
|
||||
@protocol CHDownloadProgressDisplay
|
||||
|
||||
- (void)onStartDownload:(BOOL)isFileSave;
|
||||
- (void)onEndDownload;
|
||||
- (void)onEndDownload:(BOOL)completedOK;
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress;
|
||||
|
||||
@ -121,35 +120,34 @@ class CHDownloader;
|
||||
|
||||
@end
|
||||
|
||||
// subclass this, and have your subclass instantiate and return your window
|
||||
// controller in createDownloadController
|
||||
@interface DownloadControllerFactory : NSObject
|
||||
{
|
||||
}
|
||||
// A formal protocol which is implemented by a factory of progress UI.
|
||||
@protocol CHDownloadDisplayFactory
|
||||
|
||||
- (NSWindowController<CHDownloadProgressDisplay> *)createDownloadController;
|
||||
- (id <CHDownloadProgressDisplay>)createProgressDisplay;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Pure virtual base class for a generic downloader, that the progress UI can talk to.
|
||||
// It implements nsISupports so that it can be refcounted. This class insulates the
|
||||
// UI code from having to know too much about the nsIDownloadListener.
|
||||
// It is responsible for creating the download UI, via the DownloadControllerFactory
|
||||
// UI code from having to know too much about the nsDownloadListener.
|
||||
// It is responsible for creating the download UI, via the CHDownloadController
|
||||
// that it owns.
|
||||
class CHDownloader : public nsISupports
|
||||
{
|
||||
public:
|
||||
CHDownloader(DownloadControllerFactory* inControllerFactory);
|
||||
CHDownloader();
|
||||
virtual ~CHDownloader();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void SetDisplayFactory(id<CHDownloadDisplayFactory> inDownloadDisplayFactory); // retains
|
||||
|
||||
virtual void PauseDownload() = 0;
|
||||
virtual void ResumeDownload() = 0;
|
||||
virtual void CancelDownload() = 0;
|
||||
virtual void DownloadDone() = 0;
|
||||
virtual void DetachDownloadDisplay() = 0; // tell downloader to forget about its display
|
||||
virtual void DownloadDone(nsresult aStatus) = 0;
|
||||
virtual void DetachDownloadDisplay() = 0; // tell downloader to forget about its display
|
||||
|
||||
virtual void CreateDownloadDisplay();
|
||||
|
||||
@ -160,8 +158,8 @@ protected:
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory;
|
||||
id <CHDownloadProgressDisplay> mDownloadDisplay; // something that implements the CHDownloadProgressDisplay protocol
|
||||
PRBool mIsFileSave; // true if we're doing a save, rather than a download
|
||||
id<CHDownloadDisplayFactory> mDisplayFactory;
|
||||
id<CHDownloadProgressDisplay> mDownloadDisplay; // something that implements the CHDownloadProgressDisplay protocol
|
||||
PRBool mIsFileSave; // true if we're doing a save, rather than a download
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
*
|
||||
* 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
|
||||
@ -37,40 +38,34 @@
|
||||
|
||||
#import "CHDownloadProgressDisplay.h"
|
||||
|
||||
// CHDownloader is a simple class that that the download UI can talk to
|
||||
|
||||
@implementation DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<CHDownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
// a dummy implementation. You should provide a subclass that
|
||||
// returns an instance of your progress dialog controller.
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// see the header file for comments
|
||||
CHDownloader::CHDownloader(DownloadControllerFactory* inControllerFactory)
|
||||
: mControllerFactory(inControllerFactory)
|
||||
CHDownloader::CHDownloader()
|
||||
: mDisplayFactory(NULL)
|
||||
, mDownloadDisplay(nil)
|
||||
, mIsFileSave(PR_FALSE)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
[mControllerFactory retain];
|
||||
}
|
||||
|
||||
CHDownloader::~CHDownloader()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
[mDisplayFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(CHDownloader, nsISupports);
|
||||
|
||||
void
|
||||
CHDownloader::SetDisplayFactory(id<CHDownloadDisplayFactory> inDownloadControllerFactory)
|
||||
{
|
||||
mDisplayFactory = inDownloadControllerFactory;
|
||||
[mDisplayFactory retain];
|
||||
}
|
||||
|
||||
void
|
||||
CHDownloader::CreateDownloadDisplay()
|
||||
{
|
||||
mDownloadDisplay = [mControllerFactory createDownloadController];
|
||||
NS_ASSERTION(mDisplayFactory, "Should have a UI factory");
|
||||
mDownloadDisplay = [mDisplayFactory createProgressDisplay];
|
||||
[mDownloadDisplay setDownloadListener:this];
|
||||
}
|
||||
|
61
camino/src/extensions/CHStackView.h
Normal file
61
camino/src/extensions/CHStackView.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* ***** 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 Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Calum Robinson.
|
||||
* 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 <AppKit/AppKit.h>
|
||||
|
||||
// views contained in the stack should send this notification when they change size
|
||||
extern NSString* StackViewReloadNotificationName;
|
||||
|
||||
// the stack view sends this notification after it has adjusted to subview sizes
|
||||
extern NSString* StackViewResizedNotificationName;
|
||||
|
||||
@interface CHStackView : NSView
|
||||
{
|
||||
IBOutlet id mDataSource;
|
||||
}
|
||||
|
||||
- (void)setDataSource:(id)aDataSource;
|
||||
- (void)reloadSubviews;
|
||||
|
||||
@end
|
||||
|
||||
@protocol CHStackViewDataSource
|
||||
|
||||
- (int)subviewsForStackView:(CHStackView *)stackView;
|
||||
- (NSView *)viewForStackView:(CHStackView *)stackView atIndex:(int)index;
|
||||
|
||||
@end
|
143
camino/src/extensions/CHStackView.m
Normal file
143
camino/src/extensions/CHStackView.m
Normal file
@ -0,0 +1,143 @@
|
||||
/* ***** 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 Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Calum Robinson.
|
||||
* 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 ***** */
|
||||
|
||||
/*
|
||||
This class was inspired by the OAStack view from OmniGroup, but not copied directly. This
|
||||
implementation is a little simpler, which is fine.
|
||||
|
||||
It's like NSTableView, except the data source returns views instead of strings/images etc.
|
||||
*/
|
||||
|
||||
#import "CHStackView.h"
|
||||
|
||||
NSString* StackViewReloadNotificationName = @"ReloadStackView";
|
||||
NSString* StackViewResizedNotificationName = @"StackViewResized";
|
||||
|
||||
@implementation CHStackView
|
||||
|
||||
- (id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
if ((self = [super initWithFrame:frameRect]))
|
||||
{
|
||||
// Register for notifications when one of the subviews changes size
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(reloadNotification:)
|
||||
name:StackViewReloadNotificationName
|
||||
object:nil];
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setDataSource:(id)aDataSource
|
||||
{
|
||||
mDataSource = aDataSource; // should this retain?
|
||||
|
||||
[self reloadSubviews];
|
||||
}
|
||||
|
||||
- (void)reloadNotification:(NSNotification *)notification
|
||||
{
|
||||
[self reloadSubviews];
|
||||
}
|
||||
|
||||
- (void)reloadSubviews
|
||||
{
|
||||
NSRect newFrame = [self frame];
|
||||
NSSize oldSize = [self bounds].size;
|
||||
int i, subviewCount = [mDataSource subviewsForStackView:self];
|
||||
|
||||
NSPoint nextOrigin = NSZeroPoint;
|
||||
|
||||
// we'll maintain the width of the stack view, assuming that it's
|
||||
// scaled by its superview.
|
||||
newFrame.size.height = 0.0;
|
||||
|
||||
[[self subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
|
||||
for (i = 0; i < subviewCount; i++)
|
||||
{
|
||||
NSView *subview = [mDataSource viewForStackView:self atIndex:i];
|
||||
NSRect subviewFrame = [subview frame];
|
||||
|
||||
unsigned int autoResizeMask = [subview autoresizingMask];
|
||||
if (autoResizeMask & NSViewWidthSizable)
|
||||
subviewFrame.size.width = newFrame.size.width;
|
||||
|
||||
newFrame.size.height += NSHeight(subviewFrame);
|
||||
|
||||
subviewFrame.origin = nextOrigin;
|
||||
[subview setFrame:subviewFrame];
|
||||
nextOrigin.y += NSHeight(subviewFrame);
|
||||
|
||||
[self addSubview:subview];
|
||||
|
||||
// If there are more subviews, add a separator
|
||||
if (i + 1 < subviewCount)
|
||||
{
|
||||
NSBox *separator = [[NSBox alloc] initWithFrame:
|
||||
NSMakeRect(nextOrigin.x, nextOrigin.y - 1.0, NSWidth([subview frame]), 1.0)];
|
||||
[separator setBoxType:NSBoxSeparator];
|
||||
[separator setAutoresizingMask:NSViewWidthSizable];
|
||||
[self addSubview:separator];
|
||||
[separator release];
|
||||
}
|
||||
}
|
||||
|
||||
NSRect newBounds = newFrame;
|
||||
newBounds.origin = NSZeroPoint;
|
||||
|
||||
[self setFrame:newFrame];
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:StackViewResizedNotificationName
|
||||
object:self
|
||||
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithSize:oldSize], @"oldsize", nil]];
|
||||
}
|
||||
|
||||
- (BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
60
camino/src/extensions/NSView+Utils.h
Normal file
60
camino/src/extensions/NSView+Utils.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* ***** 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 <AppKit/AppKit.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// utility routine; returns YES if the sizes are equal, with the given slop
|
||||
BOOL CHCloseSizes(NSSize aSize, NSSize bSize, float slop);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// category on NSView to add utilities for easy view resizing etc.
|
||||
|
||||
@interface NSView(CHViewUtils)
|
||||
|
||||
// move the recipient view from its superview to the destView,
|
||||
// maintaining the relative size and position of the view based
|
||||
// on its autoresize flags.
|
||||
- (void)moveToView:(NSView*)destView resize:(BOOL)resize;
|
||||
|
||||
@end
|
154
camino/src/extensions/NSView+Utils.m
Normal file
154
camino/src/extensions/NSView+Utils.m
Normal file
@ -0,0 +1,154 @@
|
||||
/* ***** 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 "NSView+Utils.h"
|
||||
|
||||
BOOL CHCloseSizes(NSSize aSize, NSSize bSize, float slop)
|
||||
{
|
||||
return (fabs(aSize.width - bSize.width) <= slop) &&
|
||||
(fabs(aSize.height - bSize.height) <= slop);
|
||||
}
|
||||
|
||||
// mask has 3 bits: 0 = 1 scales, 1 = 2 scales, 2 = 3 scales.
|
||||
static void RedistributeSpace(int resizeMask, float newWidth, /* in out */ float ioSpaces[3])
|
||||
{
|
||||
float oldWidth = ioSpaces[0] + ioSpaces[1] + ioSpaces[2];
|
||||
|
||||
if (resizeMask != 0)
|
||||
{
|
||||
switch (resizeMask)
|
||||
{
|
||||
// 1 scalable section
|
||||
case 1: // first
|
||||
ioSpaces[0] += newWidth - oldWidth; // it can go negative
|
||||
break;
|
||||
case 2: // middle
|
||||
ioSpaces[1] += newWidth - oldWidth; // it can go negative
|
||||
break;
|
||||
case 4: // last
|
||||
ioSpaces[2] += newWidth - oldWidth; // it can go negative
|
||||
break;
|
||||
|
||||
// 2 scalable sections
|
||||
case 3: // last fixed
|
||||
{
|
||||
float oldScaledWidth = ioSpaces[0] + ioSpaces[1];
|
||||
float newScaledWidth = (newWidth - ioSpaces[2]);
|
||||
ioSpaces[0] = newScaledWidth * (ioSpaces[0] / oldScaledWidth);
|
||||
ioSpaces[1] = newScaledWidth * (ioSpaces[1] / oldScaledWidth);
|
||||
break;
|
||||
}
|
||||
case 5: // middle fixed
|
||||
{
|
||||
float oldScaledWidth = ioSpaces[0] + ioSpaces[2];
|
||||
float newScaledWidth = (newWidth - ioSpaces[1]);
|
||||
ioSpaces[0] = newScaledWidth * (ioSpaces[0] / oldScaledWidth);
|
||||
ioSpaces[2] = newScaledWidth * (ioSpaces[2] / oldScaledWidth);
|
||||
break;
|
||||
}
|
||||
case 6: // first fixed
|
||||
{
|
||||
float oldScaledWidth = ioSpaces[1] + ioSpaces[2];
|
||||
float newScaledWidth = (newWidth - ioSpaces[0]);
|
||||
ioSpaces[1] = newScaledWidth * (ioSpaces[1] / oldScaledWidth);
|
||||
ioSpaces[2] = newScaledWidth * (ioSpaces[2] / oldScaledWidth);
|
||||
break;
|
||||
}
|
||||
|
||||
// all scalable
|
||||
case 7:
|
||||
ioSpaces[0] *= newWidth / oldWidth;
|
||||
ioSpaces[1] *= newWidth / oldWidth;
|
||||
ioSpaces[2] *= newWidth / oldWidth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// otherwise nothing changes
|
||||
}
|
||||
|
||||
@implementation NSView(CHViewUtils)
|
||||
|
||||
- (void)moveToView:(NSView*)destView resize:(BOOL)resize
|
||||
{
|
||||
//resize &= [destView autoresizesSubviews];
|
||||
|
||||
NSRect oldFrame = [self frame];
|
||||
NSRect oldSuperBounds = [[self superview] bounds];
|
||||
|
||||
[self retain];
|
||||
[self removeFromSuperview];
|
||||
|
||||
[destView addSubview:self];
|
||||
[self release];
|
||||
|
||||
[destView setAutoresizesSubviews:YES];
|
||||
|
||||
if (resize)
|
||||
{
|
||||
unsigned int resizeMask = [self autoresizingMask];
|
||||
NSRect newFrame = oldFrame;
|
||||
|
||||
if (resizeMask != NSViewNotSizable && !NSEqualRects([destView bounds], oldSuperBounds))
|
||||
{
|
||||
float spaces[3];
|
||||
// horizontal
|
||||
float newWidth = NSWidth([destView bounds]);
|
||||
spaces[0] = NSMinX(oldFrame);
|
||||
spaces[1] = NSWidth(oldFrame);
|
||||
spaces[2] = NSMaxX(oldSuperBounds) - NSMaxX(oldFrame);
|
||||
|
||||
RedistributeSpace(resizeMask & 0x07, newWidth, spaces);
|
||||
newFrame.origin.x = spaces[0];
|
||||
newFrame.size.width = spaces[1];
|
||||
|
||||
// vertical. we assume that the view should stick to the top of the destView here
|
||||
float newHeight = NSHeight([destView bounds]);
|
||||
spaces[0] = NSMinY(oldFrame);
|
||||
spaces[1] = NSHeight(oldFrame);
|
||||
spaces[2] = NSMaxY(oldSuperBounds) - NSMaxY(oldFrame);
|
||||
|
||||
RedistributeSpace((resizeMask >> 3) & 0x07, newHeight, spaces);
|
||||
newFrame.origin.y = spaces[0];
|
||||
newFrame.size.height = spaces[1];
|
||||
}
|
||||
|
||||
[self setFrame:newFrame];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@ -51,24 +51,31 @@ class nsIRDFService;
|
||||
@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;
|
||||
- (void) setResource: (nsIRDFResource*) aResource;
|
||||
- (nsIRDFResource*)resource; // addRefs the result
|
||||
- (void)setResource:(nsIRDFResource*) aResource;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface RDFOutlineViewDataSource : NSObject {
|
||||
nsIRDFDataSource* mDataSource;
|
||||
nsIRDFContainer* mContainer;
|
||||
nsIRDFContainerUtils* mContainerUtils;
|
||||
nsIRDFResource* mRootResource;
|
||||
nsIRDFService* mRDFService;
|
||||
@interface RDFOutlineViewDataSource : NSObject
|
||||
{
|
||||
nsIRDFDataSource* mDataSource;
|
||||
nsIRDFContainer* mContainer;
|
||||
nsIRDFContainerUtils* mContainerUtils;
|
||||
nsIRDFResource* mRootResource;
|
||||
nsIRDFService* mRDFService;
|
||||
|
||||
IBOutlet ExtendedOutlineView* mOutlineView;
|
||||
IBOutlet ExtendedOutlineView* mOutlineView;
|
||||
|
||||
NSMutableDictionary* mDictionary;
|
||||
NSMutableDictionary* mDictionary;
|
||||
unsigned int mCacheVersion;
|
||||
}
|
||||
|
||||
// Initialization Methods
|
||||
@ -85,7 +92,6 @@ class nsIRDFService;
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item;
|
||||
- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item;
|
||||
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;
|
||||
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(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.
|
||||
@ -94,14 +100,14 @@ class nsIRDFService;
|
||||
- (void)reloadDataForItem:(id)item reloadChildren: (BOOL)aReloadChildren;
|
||||
|
||||
// Implementation Methods
|
||||
- (id) makeWrapperFor: (nsIRDFResource*) aRDFResource;
|
||||
- (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:(const nsAString&)inValue withColumn:(NSString*)inColumn byItem:(id) inItem;
|
||||
- (id)createCellContents:(NSString*)inValue withColumn:(NSString*)inColumn byItem:(id)inItem;
|
||||
|
||||
-(void) getPropertyString:(NSString*)inPropertyURI forItem:(RDFOutlineViewItem*)inItem
|
||||
result:(PRUnichar**)outResult;
|
||||
- (NSString*)getPropertyString:(NSString*)inPropertyURI forItem:(RDFOutlineViewItem*)inItem;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#import "RDFOutlineViewDataSource.h"
|
||||
#import "CHBrowserService.h"
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "nsIRDFDataSource.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsIRDFLiteral.h"
|
||||
@ -55,14 +56,116 @@
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsString.h"
|
||||
|
||||
@interface RDFOutlineViewDataSource(Private);
|
||||
|
||||
- (void)registerForShutdownNotification;
|
||||
- (void)cleanup;
|
||||
@interface RDFOutlineViewItem(Private)
|
||||
|
||||
- (unsigned int)cacheVersion;
|
||||
- (void)setNumChildren:(int)numChildren isExpandable:(BOOL)expandable cacheVersion:(unsigned int)version;
|
||||
- (void)setChildren:(NSArray*)childArray;
|
||||
- (BOOL)cacheValid:(unsigned int)version needChildren:(BOOL)needChildren;
|
||||
- (BOOL)cachedChildren;
|
||||
|
||||
- (BOOL)isExpandable;
|
||||
- (int)numChildren;
|
||||
- (id)childAtIndex:(int)index;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation RDFOutlineViewItem
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
mCacheVersion = 0;
|
||||
mExpandable = NO;
|
||||
mNumChildren = 0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[mChildNodes release];
|
||||
NS_IF_RELEASE(mResource);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (nsIRDFResource*)resource
|
||||
{
|
||||
NS_IF_ADDREF(mResource);
|
||||
return mResource;
|
||||
}
|
||||
|
||||
- (void)setResource:(nsIRDFResource*) aResource
|
||||
{
|
||||
nsIRDFResource* oldResource = mResource;
|
||||
NS_IF_ADDREF(mResource = aResource);
|
||||
NS_IF_RELEASE(oldResource);
|
||||
}
|
||||
|
||||
- (unsigned int)cacheVersion
|
||||
{
|
||||
return mCacheVersion;
|
||||
}
|
||||
|
||||
- (void)setNumChildren:(int)numChildren isExpandable:(BOOL)expandable cacheVersion:(unsigned int)version;
|
||||
{
|
||||
mNumChildren = numChildren;
|
||||
mExpandable = expandable;
|
||||
mCacheVersion = version;
|
||||
}
|
||||
|
||||
- (void)setChildren:(NSArray*)childArray
|
||||
{
|
||||
// childArray can legally be nil here. If it is, we're clearing the cached children
|
||||
NSArray* oldChildren = mChildNodes;
|
||||
mChildNodes = childArray;
|
||||
[mChildNodes retain];
|
||||
[oldChildren release];
|
||||
}
|
||||
|
||||
- (BOOL)cacheValid:(unsigned int)version needChildren:(BOOL)needChildren;
|
||||
{
|
||||
return (mCacheVersion == version) && (needChildren ? (mChildNodes != nil) : 1);
|
||||
}
|
||||
|
||||
- (BOOL)cachedChildren
|
||||
{
|
||||
return (mChildNodes != nil);
|
||||
}
|
||||
|
||||
- (BOOL)isExpandable
|
||||
{
|
||||
return mExpandable;
|
||||
}
|
||||
|
||||
- (int)numChildren
|
||||
{
|
||||
return mNumChildren;
|
||||
}
|
||||
|
||||
- (id)childAtIndex:(int)index
|
||||
{
|
||||
if (mChildNodes)
|
||||
return [mChildNodes objectAtIndex:index];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface RDFOutlineViewDataSource(Private)
|
||||
|
||||
- (void)registerForShutdownNotification;
|
||||
- (void)cleanup;
|
||||
- (void)updateItemProperties:(id)item enumerateChildren:(BOOL)doChildren;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RDFOutlineViewDataSource
|
||||
|
||||
- (id)init
|
||||
@ -70,6 +173,7 @@
|
||||
if ((self = [super init]))
|
||||
{
|
||||
[self registerForShutdownNotification];
|
||||
mCacheVersion = 1;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -78,7 +182,7 @@
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
[self cleanup];
|
||||
[self cleanup];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@ -167,123 +271,62 @@
|
||||
// XXX - For now, we'll just say that none of our items are editable, as we aren't using any
|
||||
// RDF datasources that are mutable.
|
||||
//
|
||||
- (BOOL) outlineView: (NSOutlineView*) aOutlineView shouldEditTableColumn: (NSTableColumn*) aTableColumn
|
||||
- (BOOL) outlineView: (NSOutlineView*)aOutlineView shouldEditTableColumn: (NSTableColumn*) aTableColumn
|
||||
item: (id) aItem
|
||||
{
|
||||
return NO;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) outlineView: (NSOutlineView*) aOutlineView isItemExpandable: (id) aItem
|
||||
- (BOOL) outlineView: (NSOutlineView*)aOutlineView isItemExpandable:(id)aItem
|
||||
{
|
||||
if (!mDataSource)
|
||||
return NO;
|
||||
|
||||
if (!aItem)
|
||||
return YES; // The root is always open
|
||||
|
||||
nsCOMPtr<nsIRDFResource> itemResource = dont_AddRef([aItem resource]);
|
||||
|
||||
PRBool isSeq = PR_FALSE;
|
||||
mContainerUtils->IsSeq(mDataSource, itemResource, &isSeq);
|
||||
if (isSeq)
|
||||
return YES;
|
||||
|
||||
nsCOMPtr<nsIRDFResource> childProperty;
|
||||
mRDFService->GetResource("http://home.netscape.com/NC-rdf#child", getter_AddRefs(childProperty));
|
||||
|
||||
nsCOMPtr<nsIRDFNode> childNode;
|
||||
mDataSource->GetTarget(itemResource, childProperty, PR_TRUE, getter_AddRefs(childNode));
|
||||
|
||||
return childNode != nsnull;
|
||||
if (!mDataSource)
|
||||
return NO;
|
||||
|
||||
if (!aItem)
|
||||
return YES; // The root is always open
|
||||
|
||||
if (![aItem cacheValid:mCacheVersion needChildren:NO])
|
||||
[self updateItemProperties:aItem enumerateChildren:NO];
|
||||
|
||||
return [aItem isExpandable];
|
||||
}
|
||||
|
||||
- (id) outlineView: (NSOutlineView*) aOutlineView child: (int) aIndex
|
||||
ofItem: (id) aItem
|
||||
- (id)outlineView:(NSOutlineView*)aOutlineView child:(int)aIndex ofItem:(id)aItem
|
||||
{
|
||||
if (!mDataSource)
|
||||
return nil;
|
||||
if (!mDataSource)
|
||||
return nil;
|
||||
|
||||
if (!aItem)
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> rootResource = dont_AddRef([self rootResource]);
|
||||
aItem = [self getWrapperFor:rootResource];
|
||||
}
|
||||
|
||||
if (![aItem cacheValid:mCacheVersion needChildren:YES])
|
||||
[self updateItemProperties:aItem enumerateChildren:YES];
|
||||
|
||||
nsCOMPtr<nsIRDFResource> resource = !aItem ? dont_AddRef([self rootResource]) : dont_AddRef([aItem resource]);
|
||||
|
||||
nsCOMPtr<nsIRDFResource> ordinalResource;
|
||||
mContainerUtils->IndexToOrdinalResource(aIndex + 1, getter_AddRefs(ordinalResource));
|
||||
|
||||
nsCOMPtr<nsIRDFNode> childNode;
|
||||
mDataSource->GetTarget(resource, ordinalResource, PR_TRUE, getter_AddRefs(childNode));
|
||||
if (childNode) {
|
||||
// Yay. A regular container. We don't need to count, we can go directly to
|
||||
// our object.
|
||||
nsCOMPtr<nsIRDFResource> childResource(do_QueryInterface(childNode));
|
||||
if (childResource)
|
||||
return [self makeWrapperFor:childResource];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Oh well, not a regular container. We need to count, dagnabbit.
|
||||
nsCOMPtr<nsIRDFResource> childProperty;
|
||||
mRDFService->GetResource("http://home.netscape.com/NC-rdf#child", getter_AddRefs(childProperty));
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> childNodes;
|
||||
mDataSource->GetTargets(resource, childProperty, PR_TRUE, getter_AddRefs(childNodes));
|
||||
|
||||
nsCOMPtr<nsISupports> supp;
|
||||
PRInt32 count = 0;
|
||||
|
||||
PRBool hasMore = PR_FALSE;
|
||||
while (NS_SUCCEEDED(childNodes->HasMoreElements(&hasMore)) && hasMore)
|
||||
{
|
||||
childNodes->GetNext(getter_AddRefs(supp));
|
||||
if (count == aIndex)
|
||||
break;
|
||||
count ++;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRDFResource> childResource(do_QueryInterface(supp));
|
||||
if (childResource) {
|
||||
return [self makeWrapperFor:childResource];
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
return [aItem childAtIndex:aIndex];
|
||||
}
|
||||
|
||||
- (int) outlineView: (NSOutlineView*) aOutlineView numberOfChildrenOfItem: (id) aItem;
|
||||
- (int)outlineView:(NSOutlineView*)aOutlineView numberOfChildrenOfItem:(id) aItem;
|
||||
{
|
||||
if (!mDataSource)
|
||||
return 0;
|
||||
|
||||
nsCOMPtr<nsIRDFResource> resource = dont_AddRef(aItem ? [aItem resource] : [self rootResource]);
|
||||
|
||||
// XXX just assume NC:child is the only containment arc for now
|
||||
nsCOMPtr<nsIRDFResource> childProperty;
|
||||
mRDFService->GetResource("http://home.netscape.com/NC-rdf#child", getter_AddRefs(childProperty));
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> childNodes;
|
||||
mDataSource->GetTargets(resource, childProperty, PR_TRUE, getter_AddRefs(childNodes));
|
||||
|
||||
PRBool hasMore = PR_FALSE;
|
||||
PRInt32 count = 0;
|
||||
|
||||
while (NS_SUCCEEDED(childNodes->HasMoreElements(&hasMore)) && hasMore)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supp;
|
||||
childNodes->GetNext(getter_AddRefs(supp));
|
||||
count ++;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
nsresult rv = mContainer->Init(mDataSource, resource);
|
||||
if (NS_FAILED(rv))
|
||||
return 0;
|
||||
|
||||
mContainer->GetCount(&count);
|
||||
}
|
||||
|
||||
return count;
|
||||
if (!mDataSource)
|
||||
return 0;
|
||||
|
||||
if (!aItem)
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> rootResource = dont_AddRef([self rootResource]);
|
||||
aItem = [self getWrapperFor:rootResource];
|
||||
}
|
||||
|
||||
if (![aItem cacheValid:mCacheVersion needChildren:YES])
|
||||
[self updateItemProperties:aItem enumerateChildren:YES];
|
||||
|
||||
return [aItem numChildren];
|
||||
}
|
||||
|
||||
- (id) outlineView: (NSOutlineView*) aOutlineView objectValueForTableColumn: (NSTableColumn*) aTableColumn
|
||||
byItem: (id) aItem
|
||||
- (id)outlineView:(NSOutlineView*)aOutlineView objectValueForTableColumn:(NSTableColumn*)aTableColumn
|
||||
byItem:(id)aItem
|
||||
{
|
||||
if (!mDataSource || !aItem)
|
||||
return nil;
|
||||
@ -291,25 +334,22 @@
|
||||
// The table column's identifier is the RDF Resource URI of the property being displayed in
|
||||
// that column, e.g. "http://home.netscape.com/NC-rdf#Name"
|
||||
NSString* columnPropertyURI = [aTableColumn identifier];
|
||||
nsXPIDLString literalValue;
|
||||
[self getPropertyString:columnPropertyURI forItem:aItem result:getter_Copies(literalValue)];
|
||||
NSString* propString = [self getPropertyString:columnPropertyURI forItem:aItem];
|
||||
|
||||
return [self createCellContents:literalValue withColumn:columnPropertyURI byItem:aItem];
|
||||
return [self createCellContents:propString withColumn:columnPropertyURI byItem:aItem];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// createCellContents:withColumn:byItem
|
||||
//
|
||||
// Constructs a NSString from the given string data for this item in the given column.
|
||||
// This should be overridden to do more fancy things, such as add an icon, etc.
|
||||
//
|
||||
-(id) createCellContents:(const nsAString&)inValue withColumn:(NSString*)inColumn byItem:(id) inItem
|
||||
- (id)createCellContents:(NSString*)inValue withColumn:(NSString*)inColumn byItem:(id)inItem
|
||||
{
|
||||
return [NSString stringWith_nsAString: inValue];
|
||||
return inValue;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// outlineView:tooltipForString
|
||||
//
|
||||
@ -318,21 +358,9 @@
|
||||
//
|
||||
- (NSString *)outlineView:(NSOutlineView *)outlineView tooltipStringForItem:(id)inItem
|
||||
{
|
||||
nsXPIDLString literalValue;
|
||||
[self getPropertyString:@"http://home.netscape.com/NC-rdf#Name" forItem:inItem result:getter_Copies(literalValue)];
|
||||
return [NSString stringWith_nsAString:literalValue];
|
||||
return [self getPropertyString:@"http://home.netscape.com/NC-rdf#Name" forItem:inItem];
|
||||
}
|
||||
|
||||
|
||||
- (void) outlineView: (NSOutlineView*) aOutlineView setObjectValue: (id) aObject
|
||||
forTableColumn: (NSTableColumn*) aTableColumn
|
||||
byItem: (id) aItem
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void) reloadDataForItem: (id) aItem reloadChildren: (BOOL) aReloadChildren
|
||||
{
|
||||
if (!aItem)
|
||||
@ -341,7 +369,7 @@
|
||||
[mOutlineView reloadItem: aItem reloadChildren: aReloadChildren];
|
||||
}
|
||||
|
||||
- (id) makeWrapperFor: (nsIRDFResource*) aRDFResource
|
||||
- (id)getWrapperFor:(nsIRDFResource*) aRDFResource
|
||||
{
|
||||
const char* k;
|
||||
aRDFResource->GetValueConst(&k);
|
||||
@ -350,8 +378,9 @@
|
||||
// see if we've created a wrapper already, if not, create a new wrapper object
|
||||
// and stash it in our dictionary
|
||||
RDFOutlineViewItem* item = [mDictionary objectForKey:key];
|
||||
if (!item) {
|
||||
item = [[RDFOutlineViewItem alloc] init];
|
||||
if (!item)
|
||||
{
|
||||
item = [[[RDFOutlineViewItem alloc] init] autorelease];
|
||||
[item setResource: aRDFResource];
|
||||
[mDictionary setObject:item forKey:key]; // retains |item|
|
||||
}
|
||||
@ -359,14 +388,56 @@
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
-(void) getPropertyString:(NSString*)inPropertyURI forItem:(RDFOutlineViewItem*)inItem
|
||||
result:(PRUnichar**)outResult
|
||||
- (void)invalidateCachedItems
|
||||
{
|
||||
if ( !outResult )
|
||||
return;
|
||||
*outResult = nil;
|
||||
mCacheVersion++;
|
||||
}
|
||||
|
||||
- (void)updateItemProperties:(id)item enumerateChildren:(BOOL)doChildren
|
||||
{
|
||||
BOOL isExpandable = NO;
|
||||
NSMutableArray* itemChildren = doChildren ? [[[NSMutableArray alloc] initWithCapacity:10] autorelease] : nil;
|
||||
|
||||
nsCOMPtr<nsIRDFResource> itemResource = dont_AddRef([item resource]);
|
||||
|
||||
PRBool isSeq = PR_FALSE;
|
||||
mContainerUtils->IsSeq(mDataSource, itemResource, &isSeq);
|
||||
if (isSeq)
|
||||
isExpandable = YES;
|
||||
|
||||
nsCOMPtr<nsIRDFResource> childProperty;
|
||||
mRDFService->GetResource("http://home.netscape.com/NC-rdf#child", getter_AddRefs(childProperty));
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> childNodes;
|
||||
mDataSource->GetTargets(itemResource, childProperty, PR_TRUE, getter_AddRefs(childNodes));
|
||||
|
||||
PRBool hasMore = PR_FALSE;
|
||||
while (NS_SUCCEEDED(childNodes->HasMoreElements(&hasMore)) && hasMore)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supp;
|
||||
childNodes->GetNext(getter_AddRefs(supp));
|
||||
|
||||
nsCOMPtr<nsIRDFResource> childResource = do_QueryInterface(supp);
|
||||
if (childResource)
|
||||
{
|
||||
id childItem = [self getWrapperFor:childResource];
|
||||
if (childItem)
|
||||
{
|
||||
isExpandable = YES;
|
||||
if (!itemChildren) break; // know enough already
|
||||
[itemChildren addObject:childItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// itemChildren will be nil here if we don't care about children, but that's OK.
|
||||
// the setChildren call will clear the cached child list.
|
||||
[item setNumChildren:[itemChildren count] isExpandable:isExpandable cacheVersion:mCacheVersion];
|
||||
[item setChildren:itemChildren];
|
||||
}
|
||||
|
||||
- (NSString*)getPropertyString:(NSString*)inPropertyURI forItem:(RDFOutlineViewItem*)inItem
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> propertyResource;
|
||||
mRDFService->GetResource([inPropertyURI UTF8String], getter_AddRefs(propertyResource));
|
||||
|
||||
@ -378,38 +449,20 @@
|
||||
#if DEBUG
|
||||
NSLog(@"ValueNode is null in RDF objectValueForTableColumn");
|
||||
#endif
|
||||
return;
|
||||
return @"";
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRDFLiteral> valueLiteral(do_QueryInterface(valueNode));
|
||||
if (!valueLiteral)
|
||||
return;
|
||||
return @"";
|
||||
|
||||
valueLiteral->GetValue(outResult);
|
||||
const PRUnichar* value = NULL;
|
||||
valueLiteral->GetValueConst(&value);
|
||||
if (value)
|
||||
return [NSString stringWithCharacters:value length:nsCRT::strlen(value)];
|
||||
|
||||
return @"";
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation RDFOutlineViewItem
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
NS_IF_RELEASE(mResource);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (nsIRDFResource*) resource
|
||||
{
|
||||
NS_IF_ADDREF(mResource);
|
||||
return mResource;
|
||||
}
|
||||
|
||||
- (void) setResource: (nsIRDFResource*) aResource
|
||||
{
|
||||
nsIRDFResource* oldResource = mResource;
|
||||
NS_IF_ADDREF(mResource = aResource);
|
||||
NS_IF_RELEASE(oldResource);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -49,17 +49,23 @@ class HistoryDataSourceObserver;
|
||||
{
|
||||
HistoryDataSourceObserver* mObserver; // STRONG ref, should be nsCOMPtr but can't
|
||||
IBOutlet BrowserWindowController* mBrowserWindowController;
|
||||
BOOL mUpdatesEnabled;
|
||||
BOOL mNeedsRefresh;
|
||||
}
|
||||
|
||||
// overridden to create a attributed string with icon
|
||||
-(id) createCellContents:(const nsAString&)inValue withColumn:(NSString*)inColumn byItem:(id) inItem;
|
||||
- (id)createCellContents:(NSString*)inValue withColumn:(NSString*)inColumn byItem:(id) inItem;
|
||||
|
||||
- (NSString *)outlineView:(NSOutlineView *)outlineView tooltipStringForItem:(id)inItem;
|
||||
|
||||
-(void) enableObserver;
|
||||
-(void) disableObserver;
|
||||
- (void)enableObserver;
|
||||
- (void)disableObserver;
|
||||
|
||||
-(IBAction)openHistoryItem: (id)aSender;
|
||||
-(IBAction)deleteHistoryItems: (id)aSender;
|
||||
- (void)setNeedsRefresh:(BOOL)needsRefresh;
|
||||
- (BOOL)needsRefresh;
|
||||
- (void)refresh;
|
||||
|
||||
- (IBAction)openHistoryItem: (id)aSender;
|
||||
- (IBAction)deleteHistoryItems: (id)aSender;
|
||||
|
||||
@end
|
||||
|
@ -63,33 +63,29 @@
|
||||
class HistoryDataSourceObserver : public nsIRDFObserver
|
||||
{
|
||||
public:
|
||||
HistoryDataSourceObserver(NSOutlineView* outlineView) :
|
||||
mOutlineView(outlineView), mEnabled(false)
|
||||
HistoryDataSourceObserver(HistoryDataSource* dataSource)
|
||||
: mHistoryDataSource(dataSource)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
virtual ~HistoryDataSourceObserver() { } ;
|
||||
virtual ~HistoryDataSourceObserver() { }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHODIMP OnAssert(nsIRDFDataSource*, nsIRDFResource*, nsIRDFResource*, nsIRDFNode*) ;
|
||||
NS_IMETHODIMP OnUnassert(nsIRDFDataSource*, nsIRDFResource*, nsIRDFResource*, nsIRDFNode*) { return NS_OK; }
|
||||
NS_IMETHOD OnAssert(nsIRDFDataSource*, nsIRDFResource*, nsIRDFResource*, nsIRDFNode*);
|
||||
NS_IMETHOD OnUnassert(nsIRDFDataSource*, nsIRDFResource*, nsIRDFResource*, nsIRDFNode*);
|
||||
|
||||
NS_IMETHODIMP OnMove(nsIRDFDataSource*, nsIRDFResource*, nsIRDFResource*, nsIRDFResource*, nsIRDFNode*)
|
||||
NS_IMETHOD OnMove(nsIRDFDataSource*, nsIRDFResource*, nsIRDFResource*, nsIRDFResource*, nsIRDFNode*)
|
||||
{ return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP OnChange(nsIRDFDataSource*, nsIRDFResource*, nsIRDFResource*, nsIRDFNode*, nsIRDFNode*);
|
||||
NS_IMETHOD OnChange(nsIRDFDataSource*, nsIRDFResource*, nsIRDFResource*, nsIRDFNode*, nsIRDFNode*);
|
||||
|
||||
NS_IMETHODIMP BeginUpdateBatch(nsIRDFDataSource*) { return NS_OK; }
|
||||
NS_IMETHODIMP EndUpdateBatch(nsIRDFDataSource*) { return NS_OK; }
|
||||
|
||||
void Enable() { mEnabled = true; }
|
||||
void Disable() { mEnabled = false; }
|
||||
NS_IMETHOD BeginUpdateBatch(nsIRDFDataSource*) { return NS_OK; }
|
||||
NS_IMETHOD EndUpdateBatch(nsIRDFDataSource*) { return NS_OK; }
|
||||
|
||||
private:
|
||||
|
||||
NSOutlineView* mOutlineView;
|
||||
bool mEnabled;
|
||||
HistoryDataSource* mHistoryDataSource;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(HistoryDataSourceObserver, nsIRDFObserver)
|
||||
@ -105,15 +101,30 @@ NS_IMETHODIMP
|
||||
HistoryDataSourceObserver::OnAssert(nsIRDFDataSource*, nsIRDFResource*,
|
||||
nsIRDFResource* aProperty, nsIRDFNode*)
|
||||
{
|
||||
if(mEnabled) {
|
||||
const char* p;
|
||||
aProperty->GetValueConst(&p);
|
||||
if (strcmp("http://home.netscape.com/NC-rdf#Date", p) == 0)
|
||||
[mOutlineView reloadData];
|
||||
}
|
||||
const char* p;
|
||||
aProperty->GetValueConst(&p);
|
||||
if (strcmp("http://home.netscape.com/NC-rdf#Date", p) == 0)
|
||||
[mHistoryDataSource setNeedsRefresh:YES];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// OnUnassert
|
||||
//
|
||||
// This gets called on redirects, when nsGlobalHistory::RemovePage is called.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
HistoryDataSourceObserver::OnUnassert(nsIRDFDataSource*, nsIRDFResource*,
|
||||
nsIRDFResource* aProperty, nsIRDFNode*)
|
||||
{
|
||||
const char* p;
|
||||
aProperty->GetValueConst(&p);
|
||||
if (strcmp("http://home.netscape.com/NC-rdf#Date", p) == 0)
|
||||
[mHistoryDataSource setNeedsRefresh:YES];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// OnChange
|
||||
@ -125,12 +136,12 @@ NS_IMETHODIMP
|
||||
HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
nsIRDFResource* aProperty, nsIRDFNode*, nsIRDFNode*)
|
||||
{
|
||||
if(mEnabled) {
|
||||
const char* p;
|
||||
aProperty->GetValueConst(&p);
|
||||
if (strcmp("http://home.netscape.com/NC-rdf#Date", p) == 0)
|
||||
[mOutlineView reloadData];
|
||||
}
|
||||
const char* p;
|
||||
aProperty->GetValueConst(&p);
|
||||
|
||||
if (strcmp("http://home.netscape.com/NC-rdf#Date", p) == 0)
|
||||
[mHistoryDataSource setNeedsRefresh:YES];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -138,7 +149,7 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
|
||||
@interface HistoryDataSource(Private)
|
||||
|
||||
- (void)cleanup;
|
||||
- (void)cleanupHistory;
|
||||
|
||||
@end
|
||||
|
||||
@ -146,12 +157,12 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self cleanup];
|
||||
[self cleanupHistory];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// "non-virtual" cleanup method -- safe to call from dealloc.
|
||||
- (void)cleanup
|
||||
- (void)cleanupHistory
|
||||
{
|
||||
if (mDataSource && mObserver)
|
||||
{
|
||||
@ -163,7 +174,7 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
// "virtual" method; called from superclass
|
||||
- (void)cleanupDataSource
|
||||
{
|
||||
[self cleanup];
|
||||
[self cleanupHistory];
|
||||
[super cleanupDataSource];
|
||||
}
|
||||
|
||||
@ -181,7 +192,8 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
|
||||
NS_ASSERTION(mRDFService, "Uh oh, RDF service not loaded in parent class");
|
||||
|
||||
if ( !mDataSource ) {
|
||||
if ( !mDataSource )
|
||||
{
|
||||
// Get the Global History DataSource
|
||||
mRDFService->GetDataSource("rdf:history", &mDataSource);
|
||||
// Get the Date Folder Root
|
||||
@ -191,14 +203,15 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
[mOutlineView setDoubleAction: @selector(openHistoryItem:)];
|
||||
[mOutlineView setDeleteAction: @selector(deleteHistoryItems:)];
|
||||
|
||||
mObserver = new HistoryDataSourceObserver(mOutlineView);
|
||||
mObserver = new HistoryDataSourceObserver(self);
|
||||
if ( mObserver ) {
|
||||
NS_ADDREF(mObserver);
|
||||
mDataSource->AddObserver(mObserver);
|
||||
}
|
||||
[mOutlineView reloadData];
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// everything is loaded, but we have to refresh our tree otherwise
|
||||
// changes that took place while the drawer was closed won't be noticed
|
||||
[mOutlineView reloadData];
|
||||
@ -207,18 +220,41 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
NS_ASSERTION(mDataSource, "Uh oh, History RDF Data source not created");
|
||||
}
|
||||
|
||||
- (void) enableObserver
|
||||
- (void)enableObserver
|
||||
{
|
||||
if ( mObserver )
|
||||
mObserver->Enable();
|
||||
mUpdatesEnabled = YES;
|
||||
}
|
||||
|
||||
-(void) disableObserver
|
||||
-(void)disableObserver
|
||||
{
|
||||
if ( mObserver )
|
||||
mObserver->Disable();
|
||||
mUpdatesEnabled = NO;
|
||||
}
|
||||
|
||||
- (void)setNeedsRefresh:(BOOL)needsRefresh
|
||||
{
|
||||
mNeedsRefresh = needsRefresh;
|
||||
}
|
||||
|
||||
- (BOOL)needsRefresh
|
||||
{
|
||||
return mNeedsRefresh;
|
||||
}
|
||||
|
||||
- (void)refresh
|
||||
{
|
||||
if (mNeedsRefresh)
|
||||
{
|
||||
[self invalidateCachedItems];
|
||||
if (mUpdatesEnabled)
|
||||
{
|
||||
// this can be very slow! See bug 180109.
|
||||
//NSLog(@"history reload started");
|
||||
[self reloadDataForItem:nil reloadChildren:NO];
|
||||
//NSLog(@"history reload done");
|
||||
}
|
||||
mNeedsRefresh = NO;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// createCellContents:withColumn:byItem
|
||||
@ -226,31 +262,29 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
// override to create an NSAttributedString instead of just the string with the
|
||||
// given text. We add an icon and adjust the positioning of the text w/in the cell
|
||||
//
|
||||
-(id) createCellContents:(const nsAString&)inValue withColumn:(NSString*)inColumn byItem:(id) inItem
|
||||
-(id) createCellContents:(NSString*)inValue withColumn:(NSString*)inColumn byItem:(id) inItem
|
||||
{
|
||||
NSMutableAttributedString *cellValue = [[NSMutableAttributedString alloc] init];
|
||||
|
||||
//Set cell's textual contents
|
||||
[cellValue replaceCharactersInRange:NSMakeRange(0, [cellValue length]) withString:[NSString stringWith_nsAString:inValue]];
|
||||
if ([inValue length] == 0)
|
||||
inValue = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:inItem];
|
||||
|
||||
if ([inColumn isEqualToString: @"http://home.netscape.com/NC-rdf#Name"]) {
|
||||
NSMutableAttributedString *attachmentAttrString = nil;
|
||||
NSFileWrapper *fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:nil];
|
||||
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
|
||||
NSCell *attachmentAttrStringCell;
|
||||
NSMutableAttributedString *cellValue = [[[NSMutableAttributedString alloc] initWithString:inValue] autorelease];
|
||||
|
||||
if ([inColumn isEqualToString:@"http://home.netscape.com/NC-rdf#Name"])
|
||||
{
|
||||
NSFileWrapper *fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:nil];
|
||||
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
|
||||
|
||||
//Create an attributed string to hold the empty attachment, then release the components.
|
||||
attachmentAttrString = [[NSMutableAttributedString attributedStringWithAttachment:textAttachment] retain];
|
||||
// Create an attributed string to hold the empty attachment, then release the components.
|
||||
NSMutableAttributedString *attachmentAttrString = [NSMutableAttributedString attributedStringWithAttachment:textAttachment];
|
||||
[textAttachment release];
|
||||
[fileWrapper release];
|
||||
|
||||
//Get the cell of the text attachment.
|
||||
attachmentAttrStringCell = (NSCell *)[(NSTextAttachment *)[attachmentAttrString attribute:
|
||||
NSCell* attachmentAttrStringCell = (NSCell *)[(NSTextAttachment *)[attachmentAttrString attribute:
|
||||
NSAttachmentAttributeName atIndex:0 effectiveRange:nil] attachmentCell];
|
||||
|
||||
if ([self outlineView:mOutlineView isItemExpandable:inItem]) {
|
||||
if ([self outlineView:mOutlineView isItemExpandable:inItem])
|
||||
[attachmentAttrStringCell setImage:[NSImage imageNamed:@"folder"]];
|
||||
}
|
||||
else
|
||||
[attachmentAttrStringCell setImage:[NSImage imageNamed:@"smallbookmark"]];
|
||||
|
||||
@ -298,11 +332,8 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
id item = [toDrag objectAtIndex: 0];
|
||||
|
||||
// if we have just one item, we add some more flavours
|
||||
nsXPIDLString urlLiteral, nameLiteral;
|
||||
[self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:item result:getter_Copies(urlLiteral)];
|
||||
[self getPropertyString:@"http://home.netscape.com/NC-rdf#Name" forItem:item result:getter_Copies(nameLiteral)];
|
||||
NSString* url = [NSString stringWith_nsAString: urlLiteral];
|
||||
NSString* title = [NSString stringWith_nsAString: nameLiteral];
|
||||
NSString* url = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:item];
|
||||
NSString* title = [self getPropertyString:@"http://home.netscape.com/NC-rdf#Name" forItem:item];
|
||||
NSString *cleanedTitle = [title stringByReplacingCharactersInSet:[NSCharacterSet controlCharacterSet] withString:@" "];
|
||||
|
||||
[pboard declareURLPasteboardWithAdditionalTypes:[NSArray array] owner:self];
|
||||
@ -340,11 +371,8 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
return;
|
||||
}
|
||||
|
||||
nsXPIDLString urlLiteral;
|
||||
[self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:item result:getter_Copies(urlLiteral)];
|
||||
|
||||
// get uri
|
||||
NSString* url = [NSString stringWith_nsAString: urlLiteral];
|
||||
NSString* url = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:item];
|
||||
[[mBrowserWindowController getBrowserWrapper] loadURI: url referrer: nil flags: NSLoadFlagsNone activate:YES];
|
||||
}
|
||||
|
||||
@ -376,14 +404,15 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
index = [currIndex intValue];
|
||||
RDFOutlineViewItem* item = [mOutlineView itemAtRow: index];
|
||||
if (![mOutlineView isExpandable: item]) {
|
||||
nsXPIDLString urlLiteral;
|
||||
[self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:item result:getter_Copies(urlLiteral)];
|
||||
history->RemovePage(NS_ConvertUCS2toUTF8(urlLiteral).get());
|
||||
NSString* urlString = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:item];
|
||||
history->RemovePage([urlString UTF8String]);
|
||||
}
|
||||
}
|
||||
history->EndBatchUpdate();
|
||||
if ( clearSelectionWhenDone )
|
||||
[mOutlineView deselectAll:self];
|
||||
|
||||
[self invalidateCachedItems];
|
||||
[mOutlineView reloadData]; // necessary or the outline is really horked
|
||||
}
|
||||
}
|
||||
@ -402,9 +431,8 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
||||
NSString* pageTitle = [super outlineView:outlineView tooltipStringForItem:inItem];
|
||||
|
||||
// append url
|
||||
nsXPIDLString literalValue;
|
||||
[self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:inItem result:getter_Copies(literalValue)];
|
||||
return [NSString stringWithFormat:@"%@\n%@", pageTitle, [NSString stringWith_nsAString:literalValue]];
|
||||
NSString* url = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:inItem];
|
||||
return [NSString stringWithFormat:@"%@\n%@", pageTitle, [url stringByTruncatingTo:80 at:kTruncateAtEnd]];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
@ -52,3 +52,13 @@ const int kDividerTag = 4000;
|
||||
|
||||
// the tag of the separator after which to insert bookmark items
|
||||
const int kBookmarksDividerTag = -1;
|
||||
|
||||
// Save file dialog
|
||||
const int kSaveFormatPopupTag = 1000;
|
||||
|
||||
enum
|
||||
{
|
||||
eSaveFormatHTMLComplete = 0,
|
||||
eSaveFormatHTMLSource,
|
||||
eSaveFormatPlainText
|
||||
};
|
||||
|
@ -45,6 +45,9 @@ class nsIPref;
|
||||
NSUserDefaults* mDefaults;
|
||||
ICInstance mInternetConfig;
|
||||
nsIPref* mPrefs;
|
||||
|
||||
// proxies notification stuff
|
||||
CFRunLoopSourceRef mRunLoopSource;
|
||||
}
|
||||
|
||||
+ (PreferenceManager *)sharedInstance;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
#import "PreferenceManager.h"
|
||||
#import "UserDefaults.h"
|
||||
#import "CHBrowserService.h"
|
||||
@ -60,11 +61,23 @@ app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count);
|
||||
|
||||
@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
|
||||
|
||||
|
||||
@ -76,7 +89,7 @@ static PreferenceManager* gSharedInstance = nil;
|
||||
static BOOL gMadePrefManager;
|
||||
#endif
|
||||
|
||||
+ (PreferenceManager *) sharedInstance
|
||||
+ (PreferenceManager *)sharedInstance
|
||||
{
|
||||
if (!gSharedInstance)
|
||||
{
|
||||
@ -88,13 +101,20 @@ static BOOL gMadePrefManager;
|
||||
gSharedInstance = [[PreferenceManager alloc] init];
|
||||
}
|
||||
|
||||
return gSharedInstance;
|
||||
return gSharedInstance;
|
||||
}
|
||||
|
||||
+ (PreferenceManager *)sharedInstanceDontCreate
|
||||
{
|
||||
return gSharedInstance;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
mRunLoopSource = NULL;
|
||||
|
||||
[self registerNotificationListener];
|
||||
|
||||
if ([self initInternetConfig] == NO) {
|
||||
@ -115,6 +135,8 @@ static BOOL gMadePrefManager;
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
if (self == gSharedInstance)
|
||||
gSharedInstance = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@ -123,6 +145,13 @@ static BOOL gMadePrefManager;
|
||||
::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
|
||||
@ -145,14 +174,14 @@ static BOOL gMadePrefManager;
|
||||
object: nil];
|
||||
}
|
||||
|
||||
- (void) savePrefsFile
|
||||
- (void)savePrefsFile
|
||||
{
|
||||
nsCOMPtr<nsIPrefService> prefsService = do_GetService(NS_PREF_CONTRACTID);
|
||||
if (prefsService)
|
||||
prefsService->SavePrefFile(nsnull);
|
||||
}
|
||||
|
||||
- (BOOL) initInternetConfig
|
||||
- (BOOL)initInternetConfig
|
||||
{
|
||||
OSStatus error;
|
||||
error = ::ICStart(&mInternetConfig, 'CHIM');
|
||||
@ -164,7 +193,7 @@ static BOOL gMadePrefManager;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) initMozillaPrefs
|
||||
- (BOOL)initMozillaPrefs
|
||||
{
|
||||
|
||||
#ifdef _BUILD_STATIC_BIN
|
||||
@ -246,15 +275,8 @@ static BOOL gMadePrefManager;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) syncMozillaPrefs
|
||||
- (void)syncMozillaPrefs
|
||||
{
|
||||
CFArrayRef cfArray;
|
||||
CFDictionaryRef cfDictionary;
|
||||
CFNumberRef cfNumber;
|
||||
CFStringRef cfString;
|
||||
char strbuf[1024];
|
||||
int numbuf;
|
||||
|
||||
if (!mPrefs) {
|
||||
NSLog(@"Mozilla prefs not set up successfully");
|
||||
return;
|
||||
@ -268,19 +290,101 @@ static BOOL gMadePrefManager;
|
||||
// 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";
|
||||
static const char* kCookieBehaviorPref = "network.cookie.cookieBehavior";
|
||||
mPrefs->GetIntPref(kCookieBehaviorPref, &acceptCookies);
|
||||
if ( acceptCookies == 1 ) { // accept foreign cookies, assume off
|
||||
if ( acceptCookies == 1 ) { // accept foreign cookies, assume off
|
||||
acceptCookies = 2;
|
||||
mPrefs->SetIntPref(kCookieBehaviorPref, acceptCookies);
|
||||
}
|
||||
mPrefs->SetIntPref(kCookieBehaviorPref, acceptCookies);
|
||||
}
|
||||
else if ( acceptCookies == 3 ) { // p3p, assume all cookies on
|
||||
acceptCookies = 0;
|
||||
mPrefs->SetIntPref(kCookieBehaviorPref, acceptCookies);
|
||||
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->SetIntPref("network.proxy.type", 0); // 0 == no proxies
|
||||
mPrefs->ClearUserPref("network.proxy.http");
|
||||
mPrefs->ClearUserPref("network.proxy.http_port");
|
||||
mPrefs->ClearUserPref("network.proxy.ssl");
|
||||
@ -293,94 +397,66 @@ static BOOL gMadePrefManager;
|
||||
mPrefs->ClearUserPref("network.proxy.socks_port");
|
||||
mPrefs->ClearUserPref("network.proxy.no_proxies_on");
|
||||
|
||||
if ((cfDictionary = SCDynamicStoreCopyProxies (NULL)) != NULL) {
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesHTTPEnable, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE && numbuf == 1) {
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesHTTPProxy, (const void **)&cfString) == TRUE) {
|
||||
if (CFStringGetCString (cfString, strbuf, sizeof(strbuf)-1, kCFStringEncodingASCII) == TRUE) {
|
||||
mPrefs->SetCharPref("network.proxy.http", strbuf);
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesHTTPPort, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE) {
|
||||
mPrefs->SetIntPref("network.proxy.http_port", numbuf);
|
||||
}
|
||||
mPrefs->SetIntPref("network.proxy.type", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
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];
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesHTTPSEnable, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE && numbuf == 1) {
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesHTTPSProxy, (const void **)&cfString) == TRUE) {
|
||||
if (CFStringGetCString (cfString, strbuf, sizeof(strbuf)-1, kCFStringEncodingASCII) == TRUE) {
|
||||
mPrefs->SetCharPref("network.proxy.ssl", strbuf);
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesHTTPSPort, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE) {
|
||||
mPrefs->SetIntPref("network.proxy.ssl_port", numbuf);
|
||||
}
|
||||
mPrefs->SetIntPref("network.proxy.type", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesFTPEnable, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE && numbuf == 1) {
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesFTPProxy, (const void **)&cfString) == TRUE) {
|
||||
if (CFStringGetCString (cfString, strbuf, sizeof(strbuf)-1, kCFStringEncodingASCII) == TRUE) {
|
||||
mPrefs->SetCharPref("network.proxy.ftp", strbuf);
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesFTPPort, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE) {
|
||||
mPrefs->SetIntPref("network.proxy.ftp_port", numbuf);
|
||||
}
|
||||
mPrefs->SetIntPref("network.proxy.type", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesGopherEnable, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE && numbuf == 1) {
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesGopherProxy, (const void **)&cfString) == TRUE) {
|
||||
if (CFStringGetCString (cfString, strbuf, sizeof(strbuf)-1, kCFStringEncodingASCII) == TRUE) {
|
||||
mPrefs->SetCharPref("network.proxy.gopher", strbuf);
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesGopherPort, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE) {
|
||||
mPrefs->SetIntPref("network.proxy.gopher_port", numbuf);
|
||||
}
|
||||
mPrefs->SetIntPref("network.proxy.type", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesSOCKSEnable, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE && numbuf == 1) {
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesSOCKSProxy, (const void **)&cfString) == TRUE) {
|
||||
if (CFStringGetCString (cfString, strbuf, sizeof(strbuf)-1, kCFStringEncodingASCII) == TRUE) {
|
||||
mPrefs->SetCharPref("network.proxy.socks", strbuf);
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesSOCKSPort, (const void **)&cfNumber) == TRUE) {
|
||||
if (CFNumberGetValue (cfNumber, kCFNumberIntType, &numbuf) == TRUE) {
|
||||
mPrefs->SetIntPref("network.proxy.socks_port", numbuf);
|
||||
}
|
||||
mPrefs->SetIntPref("network.proxy.type", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CFDictionaryGetValueIfPresent (cfDictionary, kSCPropNetProxiesExceptionsList, (const void **)&cfArray) == TRUE) {
|
||||
cfString = CFStringCreateByCombiningStrings (NULL, cfArray, CFSTR(", "));
|
||||
if (CFStringGetLength (cfString) > 0) {
|
||||
if (CFStringGetCString (cfString, strbuf, sizeof(strbuf)-1, kCFStringEncodingASCII) == TRUE) {
|
||||
mPrefs->SetCharPref("network.proxy.no_proxies_on", strbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
CFRelease (cfDictionary);
|
||||
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 = @"";
|
||||
@ -406,16 +482,16 @@ static BOOL gMadePrefManager;
|
||||
{
|
||||
// colors are stored in HTML-like #FFFFFF strings
|
||||
NSString* colorString = [self getStringPref:prefName withSuccess:outSuccess];
|
||||
NSColor* returnColor = [NSColor blackColor];
|
||||
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);
|
||||
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];
|
||||
}
|
||||
@ -548,7 +624,7 @@ static BOOL gMadePrefManager;
|
||||
mPrefs->SetCharPref("browser.startup.homepage", [homepagePref UTF8String]);
|
||||
}
|
||||
else {
|
||||
homepagePref = [self getStringPref:"browser.startup.homepage" withSuccess:NULL];
|
||||
homepagePref = [self getStringPref:"browser.startup.homepage" withSuccess:NULL];
|
||||
}
|
||||
|
||||
if (homepagePref && [homepagePref length] > 0 && ![homepagePref isEqualToString:@"HomePageDefault"])
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>646 106 458 263 0 0 1600 1002 </string>
|
||||
<string>674 107 458 263 0 0 1600 1002 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>214</key>
|
||||
@ -12,6 +12,6 @@
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6D52</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
@ -17,11 +17,7 @@
|
||||
</dict>
|
||||
<key>IBLastGroupID</key>
|
||||
<string>8</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
BIN
chimera/resources/images/app/disclosureArrowDown.tiff
Normal file
BIN
chimera/resources/images/app/disclosureArrowDown.tiff
Normal file
Binary file not shown.
BIN
chimera/resources/images/app/disclosureArrowRight.tiff
Normal file
BIN
chimera/resources/images/app/disclosureArrowRight.tiff
Normal file
Binary file not shown.
BIN
chimera/resources/images/app/small_close.tiff
Normal file
BIN
chimera/resources/images/app/small_close.tiff
Normal file
Binary file not shown.
@ -68,6 +68,7 @@
|
||||
closeCurrentTab = id;
|
||||
closeOtherTabs = id;
|
||||
closeSendersTab = id;
|
||||
copyImage = id;
|
||||
copyImageLocation = id;
|
||||
copyLinkLocation = id;
|
||||
endAddBookmarkSheet = id;
|
||||
@ -80,6 +81,7 @@
|
||||
goToLocationFromToolbarURLField = id;
|
||||
home = id;
|
||||
manageBookmarks = id;
|
||||
manageHistory = id;
|
||||
moveTabToNewWindow = id;
|
||||
newTab = id;
|
||||
nextTab = id;
|
||||
|
@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>66 21 653 383 0 0 1152 848 </string>
|
||||
<string>65 36 653 383 0 0 1152 848 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>124</key>
|
||||
@ -15,17 +15,17 @@
|
||||
<key>297</key>
|
||||
<string>107 466 213 294 0 0 1600 1002 </string>
|
||||
<key>314</key>
|
||||
<string>73 542 213 132 0 0 1600 1002 </string>
|
||||
<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>97 693 213 246 0 0 1600 1002 </string>
|
||||
<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>206 785 198 144 0 0 1600 1002 </string>
|
||||
<string>140 644 198 144 0 0 1152 848 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
@ -42,6 +42,6 @@
|
||||
<key>IBLockedObjects</key>
|
||||
<array/>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
14
chimera/resources/localized/English.lproj/Keychain.nib/classes.nib
generated
Normal file
14
chimera/resources/localized/English.lproj/Keychain.nib/classes.nib
generated
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{CLASS = KeychainBrowserListener; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
ACTIONS = {hitButtonCancel = id; hitButtonOK = id; hitButtonOther = id; shutdown = id; };
|
||||
CLASS = KeychainService;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {confirmChangePasswordPanel = id; confirmStorePasswordPanel = id; };
|
||||
SUPERCLASS = NSObject;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
12
chimera/resources/localized/English.lproj/Keychain.nib/info.nib
generated
Normal file
12
chimera/resources/localized/English.lproj/Keychain.nib/info.nib
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?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>240 146 356 240 0 0 1024 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>283.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
chimera/resources/localized/English.lproj/Keychain.nib/objects.nib
generated
Normal file
BIN
chimera/resources/localized/English.lproj/Keychain.nib/objects.nib
generated
Normal file
Binary file not shown.
Binary file not shown.
@ -20,6 +20,7 @@
|
||||
doReload = id;
|
||||
doSearch = id;
|
||||
doStop = id;
|
||||
downloadsWindow = id;
|
||||
exportBookmarks = id;
|
||||
feedbackLink = id;
|
||||
findAgain = id;
|
||||
@ -61,7 +62,6 @@
|
||||
mCreateBookmarksFolderMenuItem = NSMenuItem;
|
||||
mCreateBookmarksSeparatorMenuItem = NSMenuItem;
|
||||
mDockMenu = NSMenu;
|
||||
mFilterList = NSPopUpButton;
|
||||
mFilterView = NSView;
|
||||
mGoMenu = NSMenu;
|
||||
mServersSubmenu = NSMenu;
|
||||
|
@ -3,11 +3,11 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>237 33 482 372 0 0 1600 1002 </string>
|
||||
<string>105 33 482 372 0 0 1600 1002 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>437 533 277 90 0 0 1152 848 </string>
|
||||
<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>
|
||||
@ -31,7 +31,11 @@
|
||||
</dict>
|
||||
<key>IBLastGroupID</key>
|
||||
<string>2</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>29</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
@ -1,18 +1,40 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{
|
||||
CLASS = CHStackView;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {mDataSource = id; };
|
||||
SUPERCLASS = NSView;
|
||||
},
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{CLASS = NSObject; LANGUAGE = ObjC; },
|
||||
{CLASS = NSView; LANGUAGE = ObjC; SUPERCLASS = NSResponder; },
|
||||
{
|
||||
CLASS = ProgressDlgController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mElapsedTimeLabel = NSTextField;
|
||||
mFromField = NSTextField;
|
||||
mProgressBar = NSProgressIndicator;
|
||||
mStatusLabel = NSTextField;
|
||||
mTimeLeftLabel = NSTextField;
|
||||
mToField = NSTextField;
|
||||
mNoDownloadsText = NSTextField;
|
||||
mScrollView = NSScrollView;
|
||||
mStackView = CHStackView;
|
||||
};
|
||||
SUPERCLASS = NSWindowController;
|
||||
},
|
||||
{
|
||||
ACTIONS = {stop = id; toggleDisclosure = id; };
|
||||
CLASS = ProgressViewController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mLocationsLabel = NSTextField;
|
||||
mLocationsLabelCompact = NSTextField;
|
||||
mProgressBar = NSProgressIndicator;
|
||||
mProgressView = NSView;
|
||||
mProgressViewCompact = NSView;
|
||||
mServerLabel = NSTextField;
|
||||
mStatusLabel = NSTextField;
|
||||
mTimeLeftLabel = NSTextField;
|
||||
mTimeLeftLabelCompact = NSTextField;
|
||||
};
|
||||
SUPERCLASS = NSObject;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
|
||||
<plist version="0.9">
|
||||
<!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>94 26 404 250 0 0 1152 746 </string>
|
||||
<string>24 42 592 284 0 0 1600 1002 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
<string>286.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>5S60</string>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
22
chimera/resources/localized/English.lproj/ProgressView.nib/classes.nib
generated
Normal file
22
chimera/resources/localized/English.lproj/ProgressView.nib/classes.nib
generated
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
ACTIONS = {close = id; open = id; reveal = id; stop = id; toggleDisclosure = id; };
|
||||
CLASS = ProgressViewController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mCompletedView = NSView;
|
||||
mCompletedViewCompact = NSView;
|
||||
mExpandedCancelButton = NSButton;
|
||||
mExpandedOpenButton = NSButton;
|
||||
mExpandedRevealButton = NSButton;
|
||||
mProgressBar = NSProgressIndicator;
|
||||
mProgressView = NSView;
|
||||
mProgressViewCompact = NSView;
|
||||
};
|
||||
SUPERCLASS = NSObject;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
27
chimera/resources/localized/English.lproj/ProgressView.nib/info.nib
generated
Normal file
27
chimera/resources/localized/English.lproj/ProgressView.nib/info.nib
generated
Normal file
@ -0,0 +1,27 @@
|
||||
<?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>75 299 448 284 0 0 1600 1002 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>27</key>
|
||||
<string>573 628 420 80 0 0 1600 1002 </string>
|
||||
<key>5</key>
|
||||
<string>573 564 420 208 0 0 1600 1002 </string>
|
||||
<key>71</key>
|
||||
<string>573 564 420 208 0 0 1600 1002 </string>
|
||||
<key>97</key>
|
||||
<string>573 628 420 80 0 0 1600 1002 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6G30</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
chimera/resources/localized/English.lproj/ProgressView.nib/objects.nib
generated
Normal file
BIN
chimera/resources/localized/English.lproj/ProgressView.nib/objects.nib
generated
Normal file
Binary file not shown.
@ -3,13 +3,9 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>410 67 356 301 0 0 1152 848 </string>
|
||||
<string>325 55 356 301 0 0 1024 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>286.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>251</integer>
|
||||
</array>
|
||||
<string>283.0</string>
|
||||
<key>IBSystem Version</key>
|
||||
<string>6F21</string>
|
||||
</dict>
|
||||
|
Binary file not shown.
@ -37,10 +37,14 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "SecurityDialogs.h"
|
||||
#import "CocoaPromptService.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#import "KeychainService.h"
|
||||
#import "nsDownloadListener.h"
|
||||
#import "ProgressDlgController.h"
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
// {0ffd3880-7a1a-11d6-a384-975d1d5f86fc}
|
||||
#define NS_SECURITYDIALOGS_CID \
|
||||
@ -55,6 +59,27 @@
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(SecurityDialogs);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(CocoaPromptService);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(KeychainPrompt);
|
||||
//NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadListener);
|
||||
|
||||
static NS_IMETHODIMP
|
||||
nsDownloadListenerConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
*aResult = NULL;
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsDownloadListener* inst;
|
||||
NS_NEWXPCOM(inst, nsDownloadListener);
|
||||
if (!inst)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(inst);
|
||||
inst->SetDisplayFactory([ProgressDlgController sharedDownloadController]);
|
||||
nsresult rv = inst->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(inst);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// used by MainController to register the components in which we want to override
|
||||
// with the Gecko embed layer.
|
||||
@ -83,6 +108,12 @@ static const nsModuleComponentInfo gAppComponents[] = {
|
||||
NS_KEYCHAINPROMPT_CID,
|
||||
"@mozilla.org/wallet/single-sign-on-prompt;1",
|
||||
KeychainPromptConstructor
|
||||
},
|
||||
{
|
||||
"Download",
|
||||
NS_DOWNLOAD_CID,
|
||||
NS_DOWNLOAD_CONTRACTID,
|
||||
nsDownloadListenerConstructor
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -52,9 +52,8 @@
|
||||
{
|
||||
IBOutlet NSApplication* mApplication;
|
||||
|
||||
// The following two items are used by the filter list when saving files.
|
||||
// The following item is added to NSSavePanels as an accessory view
|
||||
IBOutlet NSView* mFilterView;
|
||||
IBOutlet NSPopUpButton* mFilterList;
|
||||
|
||||
// IBOutlet NSMenuItem* mOfflineMenuItem;
|
||||
IBOutlet NSMenuItem* mCloseWindowMenuItem;
|
||||
@ -137,11 +136,12 @@
|
||||
-(IBAction) addFolder:(id)aSender;
|
||||
-(IBAction) addSeparator:(id)aSender;
|
||||
|
||||
//Window menu actions
|
||||
// Window menu actions
|
||||
-(IBAction) newTab:(id)aSender;
|
||||
-(IBAction) closeTab:(id)aSender;
|
||||
-(IBAction) downloadsWindow:(id)aSender;
|
||||
|
||||
//Help menu actions
|
||||
// Help menu actions
|
||||
-(IBAction) infoLink:(id)aSender;
|
||||
-(IBAction) feedbackLink:(id)aSender;
|
||||
|
||||
@ -154,7 +154,8 @@
|
||||
|
||||
- (void)adjustBookmarksMenuItemsEnabling:(BOOL)inBrowserWindowFrontmost;
|
||||
|
||||
-(NSWindow*)getFrontmostBrowserWindow;
|
||||
- (NSView*)getSavePanelView;
|
||||
- (NSWindow*)getFrontmostBrowserWindow;
|
||||
|
||||
- (MVPreferencesController *)preferencesController;
|
||||
- (void)displayPreferencesWindow:sender;
|
||||
|
@ -260,19 +260,7 @@ const int kReuseWindowOnAE = 2;
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
if ([ProgressDlgController numDownloadInProgress] > 0)
|
||||
{
|
||||
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)
|
||||
if (NSRunAlertPanel(alert, message, okButton, altButton, nil) == NSAlertDefaultReturn)
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
return NSTerminateNow;
|
||||
return [[ProgressDlgController sharedDownloadController] allowTerminate];
|
||||
}
|
||||
|
||||
-(void)applicationWillTerminate: (NSNotification*)aNotification
|
||||
@ -439,7 +427,7 @@ const int kReuseWindowOnAE = 2;
|
||||
{
|
||||
BrowserWindowController* browserController = [self getMainWindowBrowserController];
|
||||
if (browserController)
|
||||
[browserController saveDocument:NO filterView:mFilterView filterList: mFilterList];
|
||||
[browserController saveDocument:NO filterView:mFilterView];
|
||||
}
|
||||
|
||||
-(IBAction) pageSetup:(id)aSender
|
||||
@ -584,6 +572,11 @@ const int kReuseWindowOnAE = 2;
|
||||
}
|
||||
}
|
||||
|
||||
-(IBAction) downloadsWindow:(id)aSender
|
||||
{
|
||||
[[ProgressDlgController sharedDownloadController] showWindow:aSender];
|
||||
}
|
||||
|
||||
- (void)adjustBookmarksMenuItemsEnabling:(BOOL)inBrowserWindowFrontmost;
|
||||
{
|
||||
[mAddBookmarkMenuItem setEnabled:inBrowserWindowFrontmost];
|
||||
@ -591,6 +584,11 @@ const int kReuseWindowOnAE = 2;
|
||||
[mCreateBookmarksSeparatorMenuItem setEnabled:NO]; // separators are not implemented yet
|
||||
}
|
||||
|
||||
- (NSView*)getSavePanelView
|
||||
{
|
||||
return mFilterView;
|
||||
}
|
||||
|
||||
-(NSWindow*)getFrontmostBrowserWindow
|
||||
{
|
||||
// for some reason, [NSApp mainWindow] doesn't always work, so we have to
|
||||
|
@ -47,7 +47,58 @@ NSGETMODULE(_name) (nsIComponentManager* aCompMgr, \
|
||||
}
|
||||
|
||||
// NSGetModule entry points
|
||||
DECL_NSGETMODULE(UcharUtil) DECL_NSGETMODULE(nsUConvModule) 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) DECL_NSGETMODULE(nsPrefModule) DECL_NSGETMODULE(nsCJVMManagerModule) DECL_NSGETMODULE(nsSecurityManagerModule) 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(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(nsTextServicesModule) 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)
|
||||
DECL_NSGETMODULE(UcharUtil)
|
||||
DECL_NSGETMODULE(nsUConvModule)
|
||||
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)
|
||||
DECL_NSGETMODULE(nsPrefModule)
|
||||
DECL_NSGETMODULE(nsCJVMManagerModule)
|
||||
DECL_NSGETMODULE(nsSecurityManagerModule)
|
||||
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)
|
||||
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(nsTextServicesModule)
|
||||
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"
|
||||
|
||||
/**
|
||||
@ -55,7 +106,58 @@ DECL_NSGETMODULE(UcharUtil) DECL_NSGETMODULE(nsUConvModule) DECL_NSGETMODULE(nsU
|
||||
*/
|
||||
static nsStaticModuleInfo gStaticModuleInfo[] = {
|
||||
#define MODULE(_name) { (#_name), NSGETMODULE(_name) }
|
||||
MODULE(UcharUtil), MODULE(nsUConvModule), 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), MODULE(nsPrefModule), MODULE(nsCJVMManagerModule), MODULE(nsSecurityManagerModule), MODULE(nsChromeModule), MODULE(nsRDFModule), MODULE(nsParserModule), MODULE(nsGfxMacModule), MODULE(nsGfx2Module), MODULE(nsImageLib2Module), MODULE(nsPNGDecoderModule), MODULE(nsGIFModule2), MODULE(nsJPEGDecoderModule), 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(nsTextServicesModule), MODULE(nsProfileModule), MODULE(Session_History_Module), MODULE(application), MODULE(nsCookieModule), MODULE(nsXMLExtrasModule), MODULE(nsUniversalCharDetModule), MODULE(BOOT), MODULE(NSS),
|
||||
MODULE(UcharUtil),
|
||||
MODULE(nsUConvModule),
|
||||
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),
|
||||
MODULE(nsPrefModule),
|
||||
MODULE(nsCJVMManagerModule),
|
||||
MODULE(nsSecurityManagerModule),
|
||||
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),
|
||||
MODULE(nsContentModule),
|
||||
MODULE(nsLayoutModule),
|
||||
MODULE(nsMorkModule),
|
||||
MODULE(docshell_provider),
|
||||
MODULE(embedcomponents),
|
||||
MODULE(Browser_Embedding_Module),
|
||||
MODULE(nsEditorModule),
|
||||
MODULE(nsTransactionManagerModule),
|
||||
MODULE(nsTextServicesModule),
|
||||
MODULE(nsProfileModule),
|
||||
MODULE(Session_History_Module),
|
||||
MODULE(application),
|
||||
MODULE(nsCookieModule),
|
||||
MODULE(nsXMLExtrasModule),
|
||||
MODULE(nsUniversalCharDetModule),
|
||||
MODULE(BOOT),
|
||||
MODULE(NSS),
|
||||
#line 60 "nsStaticComponents.cpp.in"
|
||||
};
|
||||
|
||||
|
@ -601,7 +601,7 @@ const int kBookmarksRootItemTag = -2;
|
||||
|
||||
//Set cell's textual contents
|
||||
//[cellValue replaceCharactersInRange:NSMakeRange(0, [cellValue length]) withString:[NSString stringWith_nsAString: nameAttr]];
|
||||
cellValue = [[NSMutableAttributedString alloc] initWithString:[NSString stringWith_nsAString: nameAttr]];
|
||||
cellValue = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWith_nsAString: nameAttr]] autorelease];
|
||||
|
||||
//Create an attributed string to hold the empty attachment, then release the components.
|
||||
NSMutableAttributedString* attachmentAttrString = [NSMutableAttributedString attributedStringWithAttachment:textAttachment];
|
||||
|
@ -100,6 +100,7 @@
|
||||
|
||||
- (BOOL)isOpaque
|
||||
{
|
||||
// see http://developer.apple.com/qa/qa2001/qa1117.html
|
||||
if ( ([self tabViewType] == NSNoTabsBezelBorder) && (NSAppKitVersionNumber < 633) )
|
||||
return NO;
|
||||
|
||||
|
@ -54,6 +54,8 @@ static const int kEscapeKeyCode = 53;
|
||||
BOOL madeFirstResponder = [super makeFirstResponder:responder];
|
||||
if (madeFirstResponder && oldResponder != [self firstResponder])
|
||||
[(BrowserWindowController*)[self delegate] focusChangedFrom:oldResponder to:[self firstResponder]];
|
||||
|
||||
//NSLog(@"Old FR %@, new FR %@, responder %@, made %d", oldResponder, [self firstResponder], responder, madeFirstResponder);
|
||||
return madeFirstResponder;
|
||||
}
|
||||
|
||||
|
@ -109,12 +109,12 @@ typedef enum
|
||||
IBOutlet NSTextField* mLocationSheetURLField;
|
||||
IBOutlet NSView* mStatusBar; // contains the status text, progress bar, and lock
|
||||
IBOutlet PageProxyIcon* mProxyIcon;
|
||||
IBOutlet BrowserContentView* mContentView;
|
||||
IBOutlet BrowserContentView* mContentView;
|
||||
|
||||
IBOutlet BookmarksDataSource* mSidebarBookmarksDataSource;
|
||||
IBOutlet HistoryDataSource* mHistoryDataSource;
|
||||
IBOutlet HistoryDataSource* mHistoryDataSource;
|
||||
|
||||
IBOutlet BookmarksToolbar* mPersonalToolbar;
|
||||
IBOutlet BookmarksToolbar* mPersonalToolbar;
|
||||
|
||||
IBOutlet NSWindow* mAddBookmarkSheetWindow;
|
||||
IBOutlet NSTextField* mAddBookmarkTitleField;
|
||||
@ -191,6 +191,8 @@ typedef enum
|
||||
- (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
|
||||
@ -211,9 +213,9 @@ typedef enum
|
||||
- (IBAction)viewSource:(id)aSender; // focussed frame or page
|
||||
- (IBAction)viewPageSource:(id)aSender; // top-level page
|
||||
|
||||
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList;
|
||||
- (void)saveURL: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
|
||||
url: (NSString*)aURLSpec suggestedFilename: (NSString*)aFilename;
|
||||
- (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;
|
||||
@ -302,6 +304,7 @@ typedef enum
|
||||
- (IBAction)bookmarkLink: (id)aSender;
|
||||
|
||||
- (IBAction)copyLinkLocation:(id)aSender;
|
||||
- (IBAction)copyImage:(id)sender;
|
||||
- (IBAction)copyImageLocation:(id)sender;
|
||||
|
||||
- (BookmarksToolbar*) bookmarksToolbar;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user