Fix bug 159048: implement Page Info for camino. This uses a new set of views that have size-to-fix behavior, which are also used now for the certificate view, and the downloads window.

This commit is contained in:
smfr%smfr.org 2005-12-02 05:20:36 +00:00
Родитель bc6968bdaf
Коммит 8639bf0c77
43 изменённых файлов: 2026 добавлений и 484 удалений

Просмотреть файл

@ -1387,6 +1387,48 @@
isa = PBXCopyFilesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
0F7EAA9609326B770082C3EA = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.objc;
name = AutoSizingTextField.m;
path = src/extensions/AutoSizingTextField.m;
refType = 2;
sourceTree = SOURCE_ROOT;
};
0F7EAA9709326B770082C3EA = {
fileRef = 0F7EAA9609326B770082C3EA;
isa = PBXBuildFile;
settings = {
};
};
0F7EAA9809326B770082C3EA = {
fileRef = 0F7EAA9609326B770082C3EA;
isa = PBXBuildFile;
settings = {
};
};
0F7EAA9909326B860082C3EA = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = AutoSizingTextField.h;
path = src/extensions/AutoSizingTextField.h;
refType = 2;
sourceTree = SOURCE_ROOT;
};
0F7EAA9A09326B860082C3EA = {
fileRef = 0F7EAA9909326B860082C3EA;
isa = PBXBuildFile;
settings = {
};
};
0F7EAA9B09326B860082C3EA = {
fileRef = 0F7EAA9909326B860082C3EA;
isa = PBXBuildFile;
settings = {
};
};
0F84BF1208862E3E00E23BC4 = {
fileEncoding = 30;
isa = PBXFileReference;
@ -1429,6 +1471,57 @@
settings = {
};
};
0F8FC52C092ED71C0042429E = {
children = (
0F8FC52D092ED71C0042429E,
);
isa = PBXVariantGroup;
name = PageInfo.nib;
path = "";
refType = 4;
sourceTree = "<group>";
};
0F8FC52D092ED71C0042429E = {
isa = PBXFileReference;
lastKnownFileType = wrapper.nib;
name = English;
path = resources/localized/English.lproj/PageInfo.nib;
refType = 4;
sourceTree = "<group>";
};
0F8FC52E092ED71C0042429E = {
fileRef = 0F8FC52C092ED71C0042429E;
isa = PBXBuildFile;
settings = {
};
};
0F8FC52F092ED71C0042429E = {
fileRef = 0F8FC52C092ED71C0042429E;
isa = PBXBuildFile;
settings = {
};
};
0F8FC582092ED8C70042429E = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.objcpp;
name = PageInfoWindowController.mm;
path = src/browser/PageInfoWindowController.mm;
refType = 4;
sourceTree = "<group>";
};
0F8FC583092ED8C70042429E = {
fileRef = 0F8FC582092ED8C70042429E;
isa = PBXBuildFile;
settings = {
};
};
0F8FC584092ED8C70042429E = {
fileRef = 0F8FC582092ED8C70042429E;
isa = PBXBuildFile;
settings = {
};
};
0FA8EF970423B1A500A80166 = {
isa = PBXFileReference;
lastKnownFileType = "compiled.mach-o.dylib";
@ -2232,6 +2325,48 @@
settings = {
};
};
0FD75057093ABEBA00B6A3A4 = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = TruncatingTextFieldCell.h;
path = src/extensions/TruncatingTextFieldCell.h;
refType = 2;
sourceTree = SOURCE_ROOT;
};
0FD75058093ABEBA00B6A3A4 = {
fileRef = 0FD75057093ABEBA00B6A3A4;
isa = PBXBuildFile;
settings = {
};
};
0FD75059093ABEBA00B6A3A4 = {
fileRef = 0FD75057093ABEBA00B6A3A4;
isa = PBXBuildFile;
settings = {
};
};
0FD7505A093ABEC600B6A3A4 = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.objcpp;
name = TruncatingTextFieldCell.mm;
path = src/extensions/TruncatingTextFieldCell.mm;
refType = 4;
sourceTree = "<group>";
};
0FD7505B093ABEC600B6A3A4 = {
fileRef = 0FD7505A093ABEC600B6A3A4;
isa = PBXBuildFile;
settings = {
};
};
0FD7505C093ABEC600B6A3A4 = {
fileRef = 0FD7505A093ABEC600B6A3A4;
isa = PBXBuildFile;
settings = {
};
};
0FD8181E08CB8E8900D8F88C = {
children = (
0FD8181F08CB8E8900D8F88C,
@ -3657,6 +3792,8 @@
0F08FB1508D37DA90022DD45,
0F0F5E3D08FC660300B4EBCD,
0F07686B0927B0AA00E1BD6F,
0F7EAA9B09326B860082C3EA,
0FD75059093ABEBA00B6A3A4,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -4284,6 +4421,7 @@
0FBB8CCA08D260D800D58D8D,
0F01117408F2FE7C00423C02,
0FEA7E650926BFC600B06154,
0F8FC52F092ED71C0042429E,
);
isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -4809,6 +4947,9 @@
0F07686A0927B09E00E1BD6F,
0F07688F0927B0B300E1BD6F,
0F0768900927B0B600E1BD6F,
0F8FC584092ED8C70042429E,
0F7EAA9809326B770082C3EA,
0FD7505C093ABEC600B6A3A4,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -7570,6 +7711,8 @@
0F08FB1608D37DA90022DD45,
0F0F5E3E08FC660300B4EBCD,
0FEA7DDF0926BBEA00B06154,
0F7EAA9A09326B860082C3EA,
0FD75058093ABEBA00B6A3A4,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -8203,6 +8346,7 @@
0FBB8CCF08D260D800D58D8D,
0F01117508F2FE7C00423C02,
0FEA7E660926BFC600B06154,
0F8FC52E092ED71C0042429E,
);
isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -8729,6 +8873,9 @@
0F0F5E3B08FC65FB00B4EBCD,
0FEA7DE20926BBF500B06154,
0FEA7DE50926BC0C00B06154,
0F8FC583092ED8C70042429E,
0F7EAA9709326B770082C3EA,
0FD7505B093ABEC600B6A3A4,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -14198,6 +14345,7 @@
F5DE10E90209DC0601A967DF,
F528E21A020FD9620168DE43,
F566BD1302EFA9AD01A967F3,
0F8FC582092ED8C70042429E,
);
isa = PBXGroup;
name = Dialogs;
@ -16036,6 +16184,7 @@
children = (
F507A84103116E1D01026D5D,
F507A84403116E5501026D5D,
0F8FC52C092ED71C0042429E,
0FBC0EC90798F92600E8E0E2,
0FACBFEC07DC020D00DEE23A,
F507A84A03116E6E01026D5D,
@ -16448,6 +16597,7 @@
F5B950BA030C833301A96654 = {
children = (
3489ADC90753B717005ADF6C,
0F7EAA9909326B860082C3EA,
F541495E02711B0001A80166,
0F0F5E3C08FC660300B4EBCD,
F583E3C203B8228F01A80166,
@ -16475,6 +16625,7 @@
3FF08F0606E7CF9C001C9B19,
3FF08F0706E7CF9C001C9B19,
3FF08F0806E7CF9C001C9B19,
0FD75057093ABEBA00B6A3A4,
);
isa = PBXGroup;
name = Headers;
@ -16484,6 +16635,7 @@
F5B950BB030C833301A96654 = {
children = (
3489ADCA0753B717005ADF6C,
0F7EAA9609326B770082C3EA,
F541495F02711B0001A80166,
0F0F5E3908FC65FB00B4EBCD,
F583E3BF03B8228701A80166,
@ -16512,6 +16664,7 @@
3FF08EFD06E7CF86001C9B19,
3FF08EFE06E7CF86001C9B19,
3FF08EFF06E7CF86001C9B19,
0FD7505A093ABEC600B6A3A4,
);
isa = PBXGroup;
name = Source;

Просмотреть файл

@ -42,6 +42,10 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = \
IBPalette \
$(NULL)
APP_NAME = Camino
ifdef MOZ_DEBUG

Просмотреть файл

@ -83,6 +83,7 @@ embed[type="application/x-shockwave-flash"][src*=".tribalfusion.com/media/"],
embed[type="application/x-shockwave-flash"][src*="/flash/promotions/"],
embed[type="application/x-shockwave-flash"][src*=".adtrix.com"],
embed[type="application/x-shockwave-flash"][src*=".netshelter.net"],
embed[type="application/x-shockwave-flash"][src*=".gms1.net"],
img[src*="googlesyndication.com"],
img[src*="mediaplex.com"],
@ -111,6 +112,7 @@ img[src*="kermit.macnn.com"],
img[src*="media.adlegend.com"],
img[src*=".adtrix.com"],
img[src*=".netshelter.net"],
img[src*=".gms1.net"],
iframe[src*="/ad."],
iframe[src*="/ads."],
@ -156,6 +158,7 @@ iframe[src*=".yieldmanager.com"],
iframe[src*=".mspaceads.com"],
iframe[src*=".adtrix.com"],
iframe[src*=".netshelter.net"],
iframe[src*=".gms1.net"],
table#overtureLinksWrapper,
table.adbritetable,

Просмотреть файл

@ -141,6 +141,8 @@
savePageAs = id;
sendURL = id;
sendURLFromLink = id;
showBookmarksInfo = id;
showPageInfo = id;
smallerTextSize = id;
stop = id;
unblockAllSites = id;

Просмотреть файл

@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>3 3 530 384 0 0 1280 832 </string>
<string>33 23 530 384 0 0 1600 1002 </string>
<key>IBEditorPositions</key>
<dict>
<key>1014</key>
@ -38,6 +38,6 @@
<integer>889</integer>
</array>
<key>IBSystem Version</key>
<string>8C46</string>
<string>8F46</string>
</dict>
</plist>

Двоичные данные
camino/resources/localized/English.lproj/BrowserWindow.nib/keyedobjects.nib сгенерированный

Двоичный файл не отображается.

Просмотреть файл

@ -14,6 +14,6 @@
<key>IBFramework Version</key>
<string>437.0</string>
<key>IBSystem Version</key>
<string>8C46</string>
<string>8F46</string>
</dict>
</plist>

Двоичный файл не отображается.

Просмотреть файл

@ -18,6 +18,8 @@
addBookmarkFolder = id;
addBookmarkSeparator = id;
fillForm = id;
getInfo = id;
showPageInfo = id;
};
CLASS = FirstResponder;
LANGUAGE = ObjC;
@ -47,10 +49,7 @@
emptyCache = id;
exportBookmarks = id;
feedbackLink = id;
findAgain = id;
findInPage = id;
findPrevious = id;
getInfo = id;
goBack = id;
goForward = id;
goHome = id;
@ -73,6 +72,7 @@
searchCustomizeLink = id;
sendURL = id;
setFileExtension = id;
showCertificates = id;
showHistory = id;
smallerTextSize = id;
supportLink = id;

Просмотреть файл

@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>24 23 409 367 0 0 1600 1002 </string>
<string>134 210 409 367 0 0 1600 1002 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
@ -15,7 +15,11 @@
</dict>
<key>IBFramework Version</key>
<string>437.0</string>
<key>IBOpenObjects</key>
<array>
<integer>29</integer>
</array>
<key>IBSystem Version</key>
<string>8C46</string>
<string>8F46</string>
</dict>
</plist>

Двоичные данные
camino/resources/localized/English.lproj/MainMenu.nib/keyedobjects.nib сгенерированный

Двоичный файл не отображается.

45
camino/resources/localized/English.lproj/PageInfo.nib/classes.nib сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,45 @@
{
IBClasses = (
{CLASS = AutoSizingTextField; LANGUAGE = ObjC; SUPERCLASS = NSTextField; },
{
CLASS = CHFlippedShrinkWrapView;
LANGUAGE = ObjC;
SUPERCLASS = CHShrinkWrapView;
},
{CLASS = CHShrinkWrapView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
{
CLASS = CHStackView;
LANGUAGE = ObjC;
OUTLETS = {mDataSource = id; };
SUPERCLASS = CHShrinkWrapView;
},
{
ACTIONS = {saveTrustSettings = id; toggleDetails = id; toggleTrustSettings = id; };
CLASS = CertificateView;
LANGUAGE = ObjC;
OUTLETS = {mDelegate = id; };
SUPERCLASS = NSView;
},
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; },
{
ACTIONS = {viewCertificate = id; };
CLASS = PageInfoWindowController;
LANGUAGE = ObjC;
OUTLETS = {
mConnectionDetailsField = NSTextField;
mConnectionImageView = NSImageView;
mConnectionTextField = NSTextField;
mPageLocationField = NSTextField;
mPageModDateField = NSTextField;
mPageTitleField = NSTextField;
mShowCertificateButton = NSButton;
mSiteVerifiedDetailsField = NSTextField;
mSiteVerifiedImageView = NSImageView;
mSiteVerifiedTextField = NSTextField;
};
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

12
camino/resources/localized/English.lproj/PageInfo.nib/info.nib сгенерированный 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>18 49 367 240 0 0 1600 1002 </string>
<key>IBFramework Version</key>
<string>437.0</string>
<key>IBSystem Version</key>
<string>8F46</string>
</dict>
</plist>

Двоичные данные
camino/resources/localized/English.lproj/PageInfo.nib/keyedobjects.nib сгенерированный Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -1,10 +1,16 @@
{
IBClasses = (
{
CLASS = CHFlippedShrinkWrapView;
LANGUAGE = ObjC;
SUPERCLASS = CHShrinkWrapView;
},
{CLASS = CHShrinkWrapView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
{
CLASS = CHStackView;
LANGUAGE = ObjC;
OUTLETS = {mDataSource = id; };
SUPERCLASS = NSView;
SUPERCLASS = CHShrinkWrapView;
},
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; },

Просмотреть файл

@ -5,11 +5,7 @@
<key>IBDocumentLocation</key>
<string>24 42 592 284 0 0 1600 1002 </string>
<key>IBFramework Version</key>
<string>439.0</string>
<key>IBOpenObjects</key>
<array>
<integer>121</integer>
</array>
<string>437.0</string>
<key>IBSystem Version</key>
<string>8F46</string>
</dict>

Двоичные данные
camino/resources/localized/English.lproj/ProgressDialog.nib/keyedobjects.nib сгенерированный

Двоичный файл не отображается.

Просмотреть файл

@ -3,26 +3,21 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>101 124 448 284 0 0 1280 832 </string>
<string>35 161 448 284 0 0 1600 1002 </string>
<key>IBEditorPositions</key>
<dict>
<key>5</key>
<string>339 461 346 92 0 0 1024 746 </string>
<string>606 622 346 92 0 0 1600 1002 </string>
<key>71</key>
<string>339 462 346 92 0 0 1024 746 </string>
<string>606 622 346 92 0 0 1600 1002 </string>
</dict>
<key>IBFramework Version</key>
<string>439.0</string>
<string>437.0</string>
<key>IBLockedObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBOpenObjects</key>
<array>
<integer>71</integer>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8C46</string>
<string>8F46</string>
</dict>
</plist>

Двоичные данные
camino/resources/localized/English.lproj/ProgressView.nib/keyedobjects.nib сгенерированный

Двоичный файл не отображается.

Просмотреть файл

@ -7,6 +7,6 @@
<key>IBFramework Version</key>
<string>437.0</string>
<key>IBSystem Version</key>
<string>8C46</string>
<string>8F46</string>
</dict>
</plist>

Двоичные данные
camino/resources/localized/English.lproj/ViewCertificateDialog.nib/keyedobjects.nib сгенерированный

Двоичный файл не отображается.

Просмотреть файл

@ -92,6 +92,7 @@ typedef enum EBookmarkOpenBehavior
BOOL mGeckoInitted;
BOOL mBookmarksMenuUpdatePending;
BOOL mFileMenuUpdatePending;
BOOL mPageInfoUpdatePending;
BookmarkMenu* mMenuBookmarks;
BookmarkMenu* mDockBookmarks;
@ -120,7 +121,6 @@ typedef enum EBookmarkOpenBehavior
// Edit menu actions.
-(IBAction) findInPage:(id)aSender;
-(IBAction) getInfo:(id)aSender;
// Go menu actions.
-(IBAction) goBack:(id)aSender;
@ -182,6 +182,7 @@ typedef enum EBookmarkOpenBehavior
- (void)delayedFixCloseMenuItemKeyEquivalents;
- (void)delayedAdjustBookmarksMenuItemsEnabling;
- (void)delayedUpdatePageInfo;
- (NSView*)getSavePanelView;
- (NSWindow*)getFrontmostBrowserWindow;

Просмотреть файл

@ -66,6 +66,7 @@
#import "NetworkServices.h"
#import "MVPreferencesController.h"
#import "CertificatesWindowController.h"
#import "PageInfoWindowController.h"
#import "FindDlgController.h"
#import "PreferenceManager.h"
#import "SharedMenusObj.h"
@ -386,6 +387,7 @@ const int kReuseWindowOnAE = 2;
{
[self delayedAdjustBookmarksMenuItemsEnabling];
[self delayedFixCloseMenuItemKeyEquivalents];
[self delayedUpdatePageInfo];
}
- (NSMenu *)applicationDockMenu:(NSApplication *)sender
@ -651,6 +653,7 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
}
}
// XXX move to BWC
-(IBAction)closeTab:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -658,6 +661,7 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
[browserController closeCurrentTab:aSender];
}
// XXX move to BWC
-(IBAction) previousTab:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -665,6 +669,7 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
[browserController previousTab:aSender];
}
// XXX move to BWC
-(IBAction) nextTab:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -818,14 +823,7 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
[mFindDialog showWindow:self];
}
-(IBAction) getInfo:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
if (browserController)
[browserController getInfo: aSender];
}
// XXX move to BWC
-(IBAction) goBack:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -833,6 +831,7 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
[browserController back: aSender];
}
// XXX move to BWC
-(IBAction) goForward:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -840,6 +839,7 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
[browserController forward: aSender];
}
// XXX move to BWC
-(IBAction) doReload:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -847,6 +847,7 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
[browserController reload: aSender];
}
// XXX move to BWC
-(IBAction) reloadWithCharset:(id)aSender
{
// Figure out which charset to tell gecko to load based on the sender's tag. There
@ -869,6 +870,7 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
[self doReload:nil];
}
// XXX move to BWC
-(IBAction) doStop:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -1327,6 +1329,22 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
mFileMenuUpdatePending = NO;
}
- (void)delayedUpdatePageInfo
{
if (!mPageInfoUpdatePending)
{
[self performSelector:@selector(updatePageInfo) withObject:nil afterDelay:0];
mPageInfoUpdatePending = YES;
}
}
- (void)updatePageInfo
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
[[PageInfoWindowController visiblePageInfoWindowController] updateFromBrowserView:[browserController activeBrowserView]];
mPageInfoUpdatePending = NO;
}
- (void)adjustTextEncodingMenu
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -1402,9 +1420,6 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
return NO;
}
if ( action == @selector(getInfo:) )
return (browserController && [browserController canGetInfo]);
// only enable newTab if there is a browser window frontmost, or if there is no window
// (i.e. disable it for non-browser windows).
if (action == @selector(newTab:))

Просмотреть файл

@ -95,6 +95,7 @@ typedef enum
} ETabOpenPolicy;
@class CHBrowserView;
@class BookmarkViewController;
@class BookmarkToolbar;
@class BrowserTabView;
@ -176,9 +177,6 @@ typedef enum
// someone from messing up in the nib when making changes.
NSView* mProgressSuperview; // WEAK ptr
NSView* mPopupBlockSuperview; // WEAK ptr
// saving window titles when opening the bookmark manager
NSString* mSavedTitle;
}
- (BrowserTabView*)getTabBrowser;
@ -188,9 +186,6 @@ typedef enum
- (void)focusURLBar;
// call to update the image of the lock icon with a value from nsIWebProgressListener
- (void)updateLock:(unsigned int)securityState;
// call to update (show/hide) the image of the blocked-popup indicator and handle
// the items of the popup un-blocker menu
- (void)showPopupBlocked:(BOOL)inBlocked;
@ -232,8 +227,7 @@ typedef enum
- (IBAction)biggerTextSize:(id)aSender;
- (IBAction)smallerTextSize:(id)aSender;
- (void)getInfo:(id)sender;
- (BOOL)canGetInfo;
- (IBAction)getInfo:(id)sender;
- (BOOL)shouldShowBookmarkToolbar;
@ -314,6 +308,9 @@ typedef enum
- (IBAction)viewOnlyThisImage:(id)aSender;
- (IBAction)showPageInfo:(id)sender;
- (IBAction)showBookmarksInfo:(id)sender;
- (IBAction)addBookmark:(id)aSender;
- (IBAction)addBookmarkForLink:(id)aSender;
- (IBAction)addBookmarkFolder:(id)aSender;
@ -352,8 +349,8 @@ typedef enum
// Accessor for the bm data source
- (BookmarkViewController *)bookmarkViewController;
- (NSString*)savedTitle;
- (void)setSavedTitle:(NSString *)aTitle;
// Browser view of the frontmost tab (nil if bookmarks are showing?)
- (CHBrowserView*)activeBrowserView;
// return a weak reference to the current web navigation object. Callers should
// not hold onto this for longer than the current call unless they addref it.

Просмотреть файл

@ -48,6 +48,7 @@
#import "BookmarkManager.h"
#import "AddBookmarkDialogController.h"
#import "ProgressDlgController.h"
#import "PageInfoWindowController.h"
#import "BrowserContentViews.h"
#import "BrowserWrapper.h"
@ -436,6 +437,7 @@ enum BWCOpenDest {
- (void)bookmarkableTitle:(NSString **)outTitle URL:(NSString**)outURLString forWrapper:(BrowserWrapper*)inWrapper;
- (void)clearContextMenuTarget;
- (void)updateLock:(unsigned int)securityState;
// create back/forward session history menus on toolbar button
- (IBAction)backMenu:(id)inSender;
@ -466,7 +468,6 @@ enum BWCOpenDest {
mProgressSuperview = nil;
mBookmarkToolbarItem = nil;
mSidebarToolbarItem = nil;
mSavedTitle = nil;
// register for services
NSArray* sendTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
@ -669,16 +670,22 @@ enum BWCOpenDest {
// it only works if it's here.
[[[self window] undoManager] removeAllActions];
// release top-level nib items
[mPageMenu release];
[mImageMenu release];
[mInputMenu release];
[mLinkMenu release];
[mMailToLinkMenu release];
[mImageLinkMenu release];
[mImageMailToLinkMenu release];
[mTabMenu release];
// active Gecko connections have already been shut down in |windowWillClose|
// so we don't need to worry about that here. We only have to be careful
// not to access anything related to the document, as it's been destroyed. The
// superclass dealloc takes care of our child NSView's, which include the
// BrowserWrappers and their child CHBrowserViews.
//if (mSidebarBrowserView)
// [mSidebarBrowserView windowClosed];
[mSavedTitle release];
[mProgress release];
[mPopupBlocked release];
[mSearchBar release];
@ -1376,7 +1383,7 @@ enum BWCOpenDest {
if (action == @selector(fillForm:))
return ![self bookmarkManagerIsVisible];
return YES;
}
@ -1405,6 +1412,9 @@ enum BWCOpenDest {
else
[[self window] makeFirstResponder:[mBrowserView getBrowserView]];
}
if ([[self window] isMainWindow])
[[PageInfoWindowController visiblePageInfoWindowController] updateFromBrowserView:[self activeBrowserView]];
}
- (void)setLoadingActive:(BOOL)active
@ -1461,10 +1471,8 @@ enum BWCOpenDest {
[mURLBar setURI:url];
[mLocationSheetURLField setStringValue:url];
// don't call [window display] here, no matter how much you might want
// to, because it forces a redraw of every view in the window and with a lot
// of tabs, it's dog slow.
// [[self window] display];
if ([[self window] isMainWindow])
[[PageInfoWindowController visiblePageInfoWindowController] updateFromBrowserView:[self activeBrowserView]];
}
- (void)updateSiteIcons:(NSImage*)icon ignoreTyping:(BOOL)ignoreTyping
@ -1501,6 +1509,8 @@ enum BWCOpenDest {
{
// update bookmarks menu
[[NSApp delegate] delayedAdjustBookmarksMenuItemsEnabling];
// should we change page info for bookmarks?
}
- (void)updateFromFrontmostTab
@ -2954,16 +2964,12 @@ enum BWCOpenDest {
[[mBrowserView getBrowserView] smallerTextSize];
}
- (void)getInfo:(id)sender
- (IBAction)getInfo:(id)sender
{
BookmarkViewController* bookmarksController = [self bookmarkViewControllerForCurrentTab];
[bookmarksController ensureBookmarks];
[bookmarksController showBookmarkInfo:sender];
}
- (BOOL)canGetInfo
{
return [self singleBookmarkIsSelected];
if ([self bookmarkManagerIsVisible])
[self showBookmarksInfo:sender];
else
[self showPageInfo:sender];
}
- (BOOL)shouldShowBookmarkToolbar
@ -3281,6 +3287,21 @@ enum BWCOpenDest {
}
}
- (IBAction)showPageInfo:(id)sender
{
PageInfoWindowController* pageInfoController = [PageInfoWindowController sharedPageInfoWindowController];
[pageInfoController updateFromBrowserView:[[self getBrowserWrapper] getBrowserView]];
[[pageInfoController window] makeKeyAndOrderFront:nil];
}
- (IBAction)showBookmarksInfo:(id)sender
{
BookmarkViewController* bookmarksController = [self bookmarkViewControllerForCurrentTab];
[bookmarksController ensureBookmarks];
[bookmarksController showBookmarkInfo:sender];
}
- (BookmarkToolbar*) bookmarkToolbar
{
return mPersonalToolbar;
@ -3443,20 +3464,6 @@ enum BWCOpenDest {
return sBrokenIcon;
}
// return the window's saved title
- (NSString *)savedTitle
{
return mSavedTitle;
}
// save the window title before showing
// bookmark manager or History manager
- (void)setSavedTitle:(NSString *)aTitle
{
[mSavedTitle autorelease];
mSavedTitle = [aTitle retain];
}
+ (NSDictionary *)searchURLDictionary
{
static NSDictionary *searchURLDictionary = nil;
@ -3536,6 +3543,11 @@ enum BWCOpenDest {
return [self bookmarkViewControllerForCurrentTab];
}
- (CHBrowserView*)activeBrowserView
{
return [mBrowserView getBrowserView];
}
- (id)windowWillReturnFieldEditor:(NSWindow *)aWindow toObject:(id)anObject
{
if ([anObject isEqual:mURLBar]) {

Просмотреть файл

@ -261,20 +261,7 @@ static NSString* const kOfflineNotificationName = @"offlineModeChanged";
- (NSString*)pageTitle
{
nsCOMPtr<nsIDOMWindow> window = getter_AddRefs([mBrowserView getContentWindow]);
if (!window)
return @"";
nsCOMPtr<nsIDOMDocument> htmlDoc;
window->GetDocument(getter_AddRefs(htmlDoc));
nsCOMPtr<nsIDOMHTMLDocument> htmlDocument(do_QueryInterface(htmlDoc));
if (!htmlDocument)
return @"";
nsAutoString titleString;
htmlDocument->GetTitle(titleString);
return [NSString stringWith_nsAString:titleString];
return [mBrowserView pageTitle];
}
- (NSImage*)siteIcon

Просмотреть файл

@ -0,0 +1,73 @@
/* ***** 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 Camino 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 <smfr@smfr.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#import <Cocoa/Cocoa.h>
@class CertificateItem;
@class CHBrowserView;
@interface PageInfoWindowController : NSWindowController
{
// general tab
IBOutlet NSTextField* mPageTitleField;
IBOutlet NSTextField* mPageLocationField;
IBOutlet NSTextField* mPageModDateField;
// security tab
IBOutlet NSImageView* mSiteVerifiedImageView;
IBOutlet NSTextField* mSiteVerifiedTextField;
IBOutlet NSTextField* mSiteVerifiedDetailsField;
IBOutlet NSButton* mShowCertificateButton;
IBOutlet NSImageView* mConnectionImageView;
IBOutlet NSTextField* mConnectionTextField;
IBOutlet NSTextField* mConnectionDetailsField;
CertificateItem* mCertificateItem; // retained
}
+ (PageInfoWindowController*)sharedPageInfoWindowController;
// return nil if page info is not open
+ (PageInfoWindowController*)visiblePageInfoWindowController;
- (IBAction)viewCertificate:(id)sender;
- (void)updateFromBrowserView:(CHBrowserView*)inBrowserView;
@end

Просмотреть файл

@ -0,0 +1,287 @@
/* ***** 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 Camino 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 <smfr@smfr.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#import "NSString+Utils.h"
#include "nsXPIDLString.h"
#include "nsIDOMWindow.h"
#include "nsISecureBrowserUI.h"
#include "nsISSLStatusProvider.h"
#include "nsISSLStatus.h"
#include "nsIX509Cert.h"
#include "nsIWebProgressListener.h"
#import "CHBrowserView.h"
#import "CertificateItem.h"
#import "CertificateView.h"
#import "ViewCertificateDialogController.h"
#import "PageInfoWindowController.h"
static PageInfoWindowController* gSingletonPageInfoController;
@interface PageInfoWindowController(Private)
- (void)updateGeneralInfoFromBrowserView:(CHBrowserView*)inBrowserView;
- (void)updateSecurityInfoFromBrowserView:(CHBrowserView*)inBrowserView;
- (void)clearInfo;
- (void)enableButtons;
- (CertificateItem*)certificateItem;
- (void)setCertificateItem:(CertificateItem*)inCertItem;
@end
#pragma mark -
@implementation PageInfoWindowController
+ (PageInfoWindowController*)sharedPageInfoWindowController
{
if (!gSingletonPageInfoController)
{
gSingletonPageInfoController = [[PageInfoWindowController alloc] initWithWindowNibName:@"PageInfo"];
}
return gSingletonPageInfoController;
}
+ (PageInfoWindowController*)visiblePageInfoWindowController
{
return gSingletonPageInfoController;
}
- (void)dealloc
{
NSLog(@"%@ dealloc", self);
[mCertificateItem release];
[super dealloc];
}
- (void)awakeFromNib
{
[self setShouldCascadeWindows:NO];
[[self window] setFrameAutosaveName:@"PageInfoWindow"];
}
- (void)windowDidLoad
{
[self clearInfo];
}
- (void)windowWillClose:(NSNotification *)aNotification
{
[self clearInfo]; // clear stuff
if (self == gSingletonPageInfoController)
gSingletonPageInfoController = nil;
// balance the init from when the window was shown
[self autorelease];
}
- (IBAction)viewCertificate:(id)sender
{
if (mCertificateItem)
{
[ViewCertificateDialogController showCertificateWindowWithCertificateItem:mCertificateItem
certTypeForTrustSettings:nsIX509Cert::CA_CERT];
}
}
- (void)clearInfo
{
[mPageTitleField setStringValue:@""];
[mPageLocationField setStringValue:@""];
[mPageModDateField setStringValue:@""];
[mSiteVerifiedTextField setStringValue:@""];
[mSiteVerifiedDetailsField setStringValue:@""];
[mSiteVerifiedImageView setImage:nil];
[mConnectionTextField setStringValue:@""];
[mConnectionDetailsField setStringValue:@""];
[mConnectionImageView setImage:nil];
[self setCertificateItem:nil];
}
- (void)enableButtons
{
[mShowCertificateButton setEnabled:(mCertificateItem != nil)];
}
- (CertificateItem*)certificateItem
{
return mCertificateItem;
}
- (void)setCertificateItem:(CertificateItem*)inCertItem
{
[mCertificateItem autorelease];
mCertificateItem = [inCertItem retain];
[self enableButtons];
}
- (void)updateFromBrowserView:(CHBrowserView*)inBrowserView
{
[self window]; // force window loading
[self clearInfo];
if (!inBrowserView) return;
[self updateGeneralInfoFromBrowserView:inBrowserView];
[self updateSecurityInfoFromBrowserView:inBrowserView];
}
- (void)updateGeneralInfoFromBrowserView:(CHBrowserView*)inBrowserView
{
nsCOMPtr<nsIDOMWindow> contentWindow = [inBrowserView getContentWindow];
if (!contentWindow) return;
// general info
[mPageTitleField setStringValue:[inBrowserView pageTitle]];
[mPageLocationField setStringValue:[inBrowserView getCurrentURI]];
NSDate* lastModDate = [inBrowserView pageLastModifiedDate];
if (lastModDate)
{
NSString* dateFormat = NSLocalizedString(@"PageInfoDateFormat", @"");
NSDictionary* curCalendarLocale = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
NSString* dateString = [lastModDate descriptionWithCalendarFormat:dateFormat
timeZone:nil
locale:curCalendarLocale];
[mPageModDateField setStringValue:dateString];
}
}
- (void)updateSecurityInfoFromBrowserView:(CHBrowserView*)inBrowserView
{
// let's see how many hoops we have to jump through
nsCOMPtr<nsISecureBrowserUI> secureBrowserUI = [inBrowserView getSecureBrowserUI];
nsCOMPtr<nsISSLStatusProvider> statusProvider = do_QueryInterface(secureBrowserUI);
if (!statusProvider) return;
nsCOMPtr<nsIX509Cert> serverCert;
PRUint32 sekritKeyLength = 0;
NSString* cipherNameString = @"";
nsCOMPtr<nsISupports> secStatus;
statusProvider->GetSSLStatus(getter_AddRefs(secStatus));
nsCOMPtr<nsISSLStatus> sslStatus = do_QueryInterface(secStatus);
if (sslStatus)
{
sslStatus->GetServerCert(getter_AddRefs(serverCert));
sslStatus->GetSecretKeyLength(&sekritKeyLength);
nsXPIDLCString cipherName;
sslStatus->GetCipherName(getter_Copies(cipherName));
cipherNameString = [NSString stringWith_nsACString:cipherName];
}
// encryption info
PRUint32 pageState;
nsresult rv = secureBrowserUI->GetState(&pageState);
BOOL isBroken = NS_FAILED(rv) || (pageState == nsIWebProgressListener::STATE_IS_BROKEN);
if (serverCert)
{
[mSiteVerifiedTextField setStringValue:NSLocalizedString(@"WebSiteVerified", @"")];
CertificateItem* certItem = [CertificateItem certificateItemWithCert:serverCert];
NSString* issuerOrg = [certItem issuerOrganization];
if ([issuerOrg length] == 0)
issuerOrg = [certItem issuerName];
NSString* detailsString = [NSString stringWithFormat:NSLocalizedString(@"WebSiteVerifiedDetailsFormat", @""),
[inBrowserView pageLocationHost],
issuerOrg];
[mSiteVerifiedDetailsField setStringValue:detailsString];
[mSiteVerifiedImageView setImage:[NSImage imageNamed:@"security_lock"]];
[self setCertificateItem:certItem];
}
else
{
[mSiteVerifiedImageView setImage:[NSImage imageNamed:@"security_broken"]];
[mSiteVerifiedTextField setStringValue:NSLocalizedString(@"WebSiteNotVerified", @"")];
[mSiteVerifiedDetailsField setStringValue:@""];
}
if (isBroken)
{
[mConnectionTextField setStringValue:NSLocalizedString(@"WebSiteNotVerified", @"")];
[mConnectionDetailsField setStringValue:NSLocalizedString(@"ConnectionMixedContentDetails", @"")];
[mConnectionImageView setImage:[NSImage imageNamed:@"security_broken"]]; // XXX need "mixed" lock
}
else if (sekritKeyLength >= 90)
{
NSString* connectionString = [NSString stringWithFormat:NSLocalizedString(@"ConnectionStrongEncryptionFormat", @""),
cipherNameString,
sekritKeyLength];
[mConnectionTextField setStringValue:connectionString];
[mConnectionDetailsField setStringValue:NSLocalizedString(@"ConnectionStrongEncryptionDetails", @"")];
[mConnectionImageView setImage:[NSImage imageNamed:@"security_lock"]];
}
else if (sekritKeyLength > 0)
{
NSString* connectionString = [NSString stringWithFormat:NSLocalizedString(@"ConnectionWeakEncryptionFormat", @""),
cipherNameString,
sekritKeyLength];
[mConnectionTextField setStringValue:connectionString];
[mConnectionDetailsField setStringValue:NSLocalizedString(@"ConnectionWeakEncryptionDetails", @"")];
[mConnectionImageView setImage:[NSImage imageNamed:@"security_lock"]]; // XXX nead "weak" lock
}
else
{
[mConnectionTextField setStringValue:NSLocalizedString(@"ConnectionNoneEncryption", @"")];
[mConnectionDetailsField setStringValue:NSLocalizedString(@"ConnectionNoneEncryptionDetails", @"")];
[mConnectionImageView setImage:[NSImage imageNamed:@"security_broken"]];
}
}
- (void)autosaveWindowFrame
{
}
@end

Просмотреть файл

@ -68,6 +68,8 @@ static NSString* const kProgressWindowFrameSaveName = @"ProgressWindow";
@end
#pragma mark -
@implementation ProgressDlgController
static id gSharedProgressController = nil;
@ -88,7 +90,8 @@ static id gSharedProgressController = nil;
-(id)init
{
if ((self == [super initWithWindowNibName:@"ProgressDialog"])) {
if ((self = [super initWithWindowNibName:@"ProgressDialog"]))
{
mProgressViewControllers = [[NSMutableArray alloc] init];
mDefaultWindowSize = [[self window] frame].size;
// it would be nice if we could get the frame from the name, and then
@ -101,12 +104,17 @@ static id gSharedProgressController = nil;
mShouldCloseWindow = NO;
// We provide the views for the stack view, from mProgressViewControllers
[mStackView setShowsSeparators:YES];
[mStackView setDataSource:self];
mSelectionPivotIndex = -1;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(DLInstanceSelected:)
name:@"DownloadInstanceSelected" object:nil];
name:kDownloadInstanceSelectedNotificationName
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(DLInstanceOpened:)
name:@"DownloadInstanceOpened" object:nil];
name:kDownloadInstanceOpenedNotificationName
object:nil];
}
return self;
@ -592,7 +600,7 @@ static id gSharedProgressController = nil;
-(void)rebuildViews
{
[mStackView reloadSubviews];
[mStackView adaptToSubviews];
}
-(int)numDownloadsInProgress
@ -990,14 +998,15 @@ static id gSharedProgressController = nil;
CHStackView datasource methods
*/
-(int)subviewsForStackView:(CHStackView *)stackView
- (NSArray*)subviewsForStackView:(CHStackView *)stackView
{
return [mProgressViewControllers count];
}
-(NSView *)viewForStackView:(CHStackView *)aResizingView atIndex:(int)index
{
return [((ProgressViewController*)[mProgressViewControllers objectAtIndex:index]) view];
NSMutableArray* viewsArray = [NSMutableArray arrayWithCapacity:[mProgressViewControllers count]];
unsigned int numViews = [mProgressViewControllers count];
for (unsigned int i = 0; i < numViews; i ++)
[viewsArray addObject:[((ProgressViewController*)[mProgressViewControllers objectAtIndex:i]) view]];
return viewsArray;
}
#pragma mark -

Просмотреть файл

@ -40,6 +40,9 @@
#import <AppKit/AppKit.h>
#import "ProgressViewController.h"
extern NSString* const kDownloadInstanceSelectedNotificationName;
extern NSString* const kDownloadInstanceOpenedNotificationName;
//
// interface ProgressView
//

Просмотреть файл

@ -40,6 +40,9 @@
#import "ProgressView.h"
NSString* const kDownloadInstanceSelectedNotificationName = @"DownloadInstanceSelected";
NSString* const kDownloadInstanceOpenedNotificationName = @"DownloadInstanceOpened";
@interface ProgressView(Private)
-(BOOL)isSelected;
@ -87,14 +90,14 @@
}
}
[self setSelected:shouldSelect];
[[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadInstanceSelected" object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:kDownloadInstanceSelectedNotificationName object:self];
// after we've processed selection and modifiers, see if it's a double-click. If so,
// send a notification off to the controller which will handle it accordingly. Doing it after
// processing the modifiers allows someone to shift-dblClick and open all selected items
// in the list in one action.
if ([theEvent type] == NSLeftMouseDown && [theEvent clickCount] == 2)
[[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadInstanceOpened" object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:kDownloadInstanceOpenedNotificationName object:self];
}
-(int)lastModifier
@ -130,7 +133,7 @@
mLastModifier = kNoKey; // control is only special because it means its contextual menu time
[self setSelected:YES];
[self display]; // change selection immediately
[[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadInstanceSelected" object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:kDownloadInstanceSelectedNotificationName object:self];
}
return [[self getController] contextualMenu];
}

Просмотреть файл

@ -50,14 +50,12 @@ class nsIDOMWindow;
class nsIWebBrowser;
class nsIDOMNode;
class nsIDOMEvent;
class nsIWebBrowserFind;
class nsIEventSink;
class nsIDragHelperService;
class nsIPrintSettings;
class nsIURI;
class nsISupports;
// Protocol implemented by anyone interested in progress
// related to a BrowserView. A listener should explicitly
// register itself with the view using the addListener
@ -176,8 +174,14 @@ enum {
- (void)goForward;
- (void)gotoIndex:(int)index;
- (void)stop:(unsigned int)flags;
- (NSString*)getCurrentURI;
- (NSString*)pageLocation; // from window.location. can differ from the document's URI, and possibly from getCurrentURI
- (NSString*)pageLocationHost;
- (NSString*)pageTitle;
- (NSDate*)pageLastModifiedDate;
// nsIWebBrowserSetup methods
- (void)setProperty:(unsigned int)property toValue:(unsigned int)value;

Просмотреть файл

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Simon Fraser <smfr@smfr.org>
*
* 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,6 +38,7 @@
#import "NSString+Utils.h"
#import "NSPasteboard+Utils.h"
#import "NSDate+Utils.h"
#import "CHClickListener.h"
@ -75,6 +77,7 @@
// Saving of links/images/docs
#include "nsIWebBrowserFocus.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMLocation.h"
#include "nsIWebBrowserPersist.h"
#include "nsIProperties.h"
@ -131,9 +134,10 @@ const long NSFindPanelActionSetFindString = 7;
- (nsIContentViewer*)getContentViewer; // addrefs return value
- (float)getTextZoom;
- (void)incrementTextZoom:(float)increment min:(float)min max:(float)max;
- (nsIDocShell*)getDocShell;
- (nsIDocShell*)getDocShell; // does NOT addref
- (NSString*)getSelection;
- (already_AddRefed<nsIDOMWindow>)focussedDOMWindow;
- (NSString*)locationFromDOMWindow:(nsIDOMWindow*)inDOMWindow;
- (void)ensurePrintSettings;
- (void)savePrintSettings;
@ -345,6 +349,7 @@ const long NSFindPanelActionSetFindString = 7;
_listener->SetContainer(container);
}
// addrefs return value
- (nsIDOMWindow*)getContentWindow
{
nsIDOMWindow* window = nsnull;
@ -489,6 +494,7 @@ const long NSFindPanelActionSetFindString = 7;
browserSetup->SetProperty(property, value);
}
// should we be using the window.location URL instead? see nsIDOMLocation.h
- (NSString*)getCurrentURI
{
nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
@ -505,6 +511,76 @@ const long NSFindPanelActionSetFindString = 7;
return [NSString stringWithUTF8String:spec.get()];
}
- (NSString*)pageLocation
{
nsCOMPtr<nsIDOMWindow> contentWindow = getter_AddRefs([self getContentWindow]);
NSString* location = [self locationFromDOMWindow:contentWindow];
return location ? location : @"";
}
- (NSString*)pageLocationHost
{
nsCOMPtr<nsIDOMWindow> domWindow = getter_AddRefs([self getContentWindow]);
if (!domWindow) return @"";
nsCOMPtr<nsIDOMDocument> domDocument;
domWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument) return @"";
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
if (!nsDoc) return @"";
nsCOMPtr<nsIDOMLocation> location;
nsDoc->GetLocation(getter_AddRefs(location));
if (!location) return @"";
nsAutoString hostStr;
location->GetHost(hostStr);
return [NSString stringWith_nsAString:hostStr];
}
- (NSString*)pageTitle
{
nsCOMPtr<nsIDOMWindow> window = getter_AddRefs([self getContentWindow]);
if (!window)
return @"";
nsCOMPtr<nsIDOMDocument> htmlDoc;
window->GetDocument(getter_AddRefs(htmlDoc));
nsCOMPtr<nsIDOMHTMLDocument> htmlDocument(do_QueryInterface(htmlDoc));
if (!htmlDocument)
return @"";
nsAutoString titleString;
htmlDocument->GetTitle(titleString);
return [NSString stringWith_nsAString:titleString];
}
- (NSDate*)pageLastModifiedDate
{
nsCOMPtr<nsIDOMWindow> domWindow = getter_AddRefs([self getContentWindow]);
nsCOMPtr<nsIDOMDocument> domDocument;
domWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return nil;
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
if (!nsDoc)
return nil;
nsAutoString lastModifiedDate;
nsDoc->GetLastModified(lastModifiedDate);
// sucks that we have to parse this back to a PRTime, thence back
// again to an NSDate. Why doesn't nsIDOMNSDocument have an accessor
// which can give me a date directly?
PRTime time;
PRStatus st = PR_ParseTimeString(NS_ConvertUCS2toUTF8(lastModifiedDate).get(), PR_FALSE /* local time */, &time);
if (st == PR_SUCCESS)
return [NSDate dateWithPRTime:time];
return nil;
}
- (CHBrowserListener*)getCocoaBrowserListener
{
return _listener;
@ -766,32 +842,46 @@ const long NSFindPanelActionSetFindString = 7;
filterView: aFilterView];
}
- (already_AddRefed<nsIDOMWindow>)focussedDOMWindow
{
if (!_webBrowser)
return nsnull;
nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
nsIDOMWindow* domWindow;
wbf->GetFocusedWindow(&domWindow);
if (!domWindow)
_webBrowser->GetContentDOMWindow(&domWindow);
return domWindow;
}
- (NSString*)locationFromDOMWindow:(nsIDOMWindow*)inDOMWindow
{
if (!inDOMWindow) return nil;
nsCOMPtr<nsIDOMDocument> domDocument;
inDOMWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return nil;
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
if (!nsDoc)
return nil;
nsCOMPtr<nsIDOMLocation> location;
nsDoc->GetLocation(getter_AddRefs(location));
if (!location)
return nil;
nsAutoString urlStr;
location->GetHref(urlStr);
return [NSString stringWith_nsAString:urlStr];
}
-(NSString*)getFocusedURLString
{
if (!_webBrowser)
return @"";
nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
nsCOMPtr<nsIDOMWindow> domWindow;
wbf->GetFocusedWindow(getter_AddRefs(domWindow));
if (!domWindow)
_webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (!domWindow)
return @"";
nsCOMPtr<nsIDOMDocument> domDocument;
domWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return @"";
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
if (!nsDoc)
return @"";
nsCOMPtr<nsIDOMLocation> location;
nsDoc->GetLocation(getter_AddRefs(location));
if (!location)
return @"";
nsAutoString urlStr;
location->GetHref(urlStr);
return [NSString stringWith_nsAString: urlStr];
nsCOMPtr<nsIDOMWindow> focussedWindow = [self focussedDOMWindow];
NSString* locationString = [self locationFromDOMWindow:focussedWindow];
return locationString ? locationString : @"";
}
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView
@ -801,13 +891,9 @@ const long NSFindPanelActionSetFindString = 7;
nsCOMPtr<nsIDOMWindow> domWindow;
if (focusedFrame)
{
nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
wbf->GetFocusedWindow(getter_AddRefs(domWindow));
}
domWindow = [self focussedDOMWindow];
else
_webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (!domWindow)
return;
@ -815,26 +901,19 @@ const long NSFindPanelActionSetFindString = 7;
domWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return;
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
if (!nsDoc)
return;
nsCOMPtr<nsIDOMLocation> location;
nsDoc->GetLocation(getter_AddRefs(location));
if (!location)
return;
nsAutoString urlStr;
location->GetHref(urlStr);
NSString* windowLocation = [self locationFromDOMWindow:domWindow];
nsCOMPtr<nsIURI> url;
nsresult rv = NS_NewURI(getter_AddRefs(url), NS_ConvertUCS2toUTF8(urlStr).get());
nsresult rv = NS_NewURI(getter_AddRefs(url), [windowLocation UTF8String]);
if (NS_FAILED(rv))
return;
[self saveInternal: url.get()
withDocument: domDocument
suggestedFilename: @""
bypassCache: NO
filterView: aFilterView];
[self saveInternal:url.get()
withDocument:domDocument
suggestedFilename:@""
bypassCache:NO
filterView:aFilterView];
}
-(void)doCommand:(const char*)commandName
@ -1011,38 +1090,6 @@ const long NSFindPanelActionSetFindString = 7;
[[self getBrowserContainer] didDismissPrompt];
}
#if 0
// how does this differ from getCurrentURI?
-(NSString*)getCurrentURLSpec
{
NSString* empty = @"";
if (!_webBrowser)
return empty;
nsCOMPtr<nsIDOMWindow> domWindow;
_webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (!domWindow)
return empty;
nsCOMPtr<nsIDOMDocument> domDocument;
domWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return empty;
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
if (!nsDoc)
return empty;
nsCOMPtr<nsIDOMLocation> location;
nsDoc->GetLocation(getter_AddRefs(location));
if (!location)
return empty;
nsAutoString urlStr;
location->GetHref(urlStr);
return [NSString stringWith_nsAString: urlStr];
}
#endif
- (void)setActive: (BOOL)aIsActive
{
nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
@ -1095,7 +1142,7 @@ const long NSFindPanelActionSetFindString = 7;
}
}
// does NOT addref return value
- (nsIDocShell*)getDocShell
{
if (!_webBrowser)

Просмотреть файл

@ -0,0 +1,55 @@
/* ***** 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
* Calum Robinson.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Simon Fraser <smfr@smfr.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#import <Cocoa/Cocoa.h>
//
// AutoSizingTextField
//
// This is a text field that automatically adjusts its height
// to fit the text. The width remains unchanged. It will never
// shrink to be less that one lineheight tall.
//
// Can be used in Interface Builder, if you have built and installed
// the CaminoView.palette IB Palette.
//
@interface AutoSizingTextField : NSTextField
{
BOOL mSettingFrameSize;
}
@end

Просмотреть файл

@ -0,0 +1,114 @@
/* ***** 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
* Calum Robinson.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Simon Fraser <smfr@smfr.org>
*
* 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"
#import "AutoSizingTextField.h"
@interface AutoSizingTextField(Private)
- (NSSize)sizeForFrame:(NSRect)inFrame;
- (void)adjustSize;
@end
#pragma mark -
@implementation AutoSizingTextField
- (void)setStringValue:(NSString*)inString
{
[super setStringValue:inString];
[self adjustSize];
}
- (void)setAttributedStringValue:(NSAttributedString *)inString
{
[super setAttributedStringValue:inString];
[self adjustSize];
}
- (void)setFrame:(NSRect)frameRect
{
NSSize origSize = frameRect.size;
frameRect.size = [self sizeForFrame:frameRect];
if (![[self superview] isFlipped])
frameRect.origin.y -= (frameRect.size.height - origSize.height);
mSettingFrameSize = YES;
[super setFrame:frameRect];
mSettingFrameSize = NO;
}
- (void)setFrameSize:(NSSize)newSize
{
if (mSettingFrameSize)
{
[super setFrameSize:newSize];
return;
}
NSRect newFrame = [self frame];
newFrame.size = newSize;
[super setFrameSize:[self sizeForFrame:newFrame]];
}
- (NSSize)sizeForFrame:(NSRect)inFrame
{
inFrame.size.height = 10000.0f;
NSSize newSize = [[self cell] cellSizeForBounds:inFrame];
// don't let it get zero height
if (newSize.height == 0.0f)
{
NSFont* cellFont = [[self cell] font];
float lineHeight = [cellFont ascender] - [cellFont descender];
newSize.height = lineHeight;
}
newSize.width = inFrame.size.width;
return newSize;
}
- (void)adjustSize
{
// NSLog(@"%@ adjustSize (%@)", self, [self stringValue]);
[self setFrameSizeMaintainingTopLeftOrigin:[self sizeForFrame:[self frame]]];
//[self setFrameSize:[self sizeForFrame:[self frame]]];
}
@end

Просмотреть файл

@ -20,6 +20,7 @@
*
* Contributor(s):
* Calum Robinson <calumr@mac.com>
* Simon Fraser <smfr@smfr.org>
*
* 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,24 +39,98 @@
#import <AppKit/AppKit.h>
// views contained in the stack should send this notification when they change size
extern NSString* StackViewReloadNotificationName;
extern NSString* const kStackViewReloadNotificationName;
// the stack view sends this notification after it has adjusted to subview sizes
extern NSString* StackViewResizedNotificationName;
extern NSString* const kStackViewResizedNotificationName;
@interface CHStackView : NSView
//
// CHShrinkWrapView
//
// A view that resizes to contain its subviews.
//
// Early on, it will look at its subview positions, and calculate
// the "intrinsic padding" (i.e. the space around the subviews),
// and use this when sizing itself. It will then resize itself to
// contain its subviews, plus the padding, whenever one if its
// direct subviews resizes.
//
// Can be used in Interface Builder, if you have built and installed
// the CaminoView.palette IB Palette.
//
@interface CHShrinkWrapView : NSView
{
float mIntrinsicPadding[4]; // NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge
BOOL mFetchedIntrinsicPadding;
BOOL mPaddingSetManually;
BOOL mSelfResizing;
}
// padding will normally be calculated automatically from the subview positions,
// but you can set it explicilty if you wish.
- (void)setIntrinsicPadding:(float)inPadding forEdge:(NSRectEdge)inEdge;
- (float)paddingForEdge:(NSRectEdge)inEdge;
- (void)adaptToSubviews;
@end
//
// CHFlippedShrinkWrapView
//
// A subview of CHShrinkWrapView that is flipped.
//
// This is used when nesting a CHStackView inside an NSScrollView,
// because NSScrollView messes up is its containerView isn't flipped
// (really).
//
// If you have one of these in IB, editing contained views is broken
// (view outlines draw flipped, mouse interaction is busted).
//
@interface CHFlippedShrinkWrapView : CHShrinkWrapView
{
}
@end
//
// CHStackView
//
// A view that lays out its subviews top to bottom.
//
// It can either manage a static set of subviws as specified in
// the nib, or the subviews can be supplied by a "data source".
// If using a data source, the stack view can optionally insert
// a separator view after each supplied view.
//
// The data source, if used, must retain the views.
//
// Can be used in Interface Builder, if you have built and installed
// the CaminoView.palette IB Palette.
//
@interface CHStackView : CHShrinkWrapView
{
IBOutlet id mDataSource;
BOOL mShowsSeparators;
// BOOL mIsResizingSubviews;
}
- (void)setDataSource:(id)aDataSource;
- (void)reloadSubviews;
// default is NO
- (BOOL)showsSeparators;
- (void)setShowsSeparators:(BOOL)inShowSeparators;
@end
@protocol CHStackViewDataSource
- (int)subviewsForStackView:(CHStackView *)stackView;
- (NSView *)viewForStackView:(CHStackView *)stackView atIndex:(int)index;
- (NSArray*)subviewsForStackView:(CHStackView *)stackView;
@end

Просмотреть файл

@ -22,6 +22,7 @@
* Contributor(s):
* Calum Robinson <calumr@mac.com>
* Josh Aas <josha@mac.com>
* Simon Fraser <smfr@smfr.org>
*
* 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,34 +38,292 @@
*
* ***** 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 "NSView+Utils.h"
#import "CHStackView.h"
NSString* StackViewReloadNotificationName = @"ReloadStackView";
NSString* StackViewResizedNotificationName = @"StackViewResized";
@interface NSObject(PrivateAPI)
+ (BOOL)isInInterfaceBuilder;
+ (BOOL)editingInInterfaceBuilder;
@end
@interface CHShrinkWrapView(Private)
+ (BOOL)drawPlacementRect;
- (void)setupNotifications;
- (void)viewBoundsChangedNotification:(NSNotification*)inNotification;
- (void)viewFrameChangedNotification:(NSNotification*)inNotification;
- (void)recalcPadding;
@end
#pragma mark -
@implementation CHShrinkWrapView
- (id)initWithFrame:(NSRect)inFrame
{
if ((self = [super initWithFrame:inFrame]))
{
[self setupNotifications];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder
{
if ((self = [super initWithCoder:decoder]))
{
[self setupNotifications];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
}
- (void)awakeFromNib
{
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)drawRect:(NSRect)inRect
{
if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] &&
[NSObject editingInInterfaceBuilder])
{
[[NSColor blueColor] set];
NSFrameRect([self bounds]);
}
}
- (void)setIntrinsicPadding:(float)inPadding forEdge:(NSRectEdge)inEdge
{
if ((int)inEdge < 0 || (int)inEdge > 3)
return;
mIntrinsicPadding[inEdge] = inPadding;
mPaddingSetManually = YES;
}
- (float)paddingForEdge:(NSRectEdge)inEdge
{
if ((int)inEdge < 0 || (int)inEdge > 3)
return 0.0f;
return mIntrinsicPadding[inEdge];
}
- (void)didAddSubview:(NSView *)subview
{
[subview setPostsBoundsChangedNotifications:YES];
[subview setPostsFrameChangedNotifications:YES];
mFetchedIntrinsicPadding = NO;
}
- (void)willRemoveSubview:(NSView *)subview
{
}
- (void)viewDidMoveToWindow
{
if ([self window])
{
[self adaptToSubviews];
}
}
- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize
{
BOOL alreadyResizing = mSelfResizing;
// avoid layout out our subviews once for every subview resize...
mSelfResizing = YES;
[super resizeSubviewsWithOldSize:oldBoundsSize];
mSelfResizing = alreadyResizing;
// ...by doing it just once here
if (!alreadyResizing)
[self adaptToSubviews];
}
- (void)recalcPadding
{
if (mPaddingSetManually || mFetchedIntrinsicPadding)
return;
NSRect subframeBounds = NSZeroRect;
NSEnumerator* subviewsEnum = [[self subviews] objectEnumerator];
NSView* curSubView;
while ((curSubView = [subviewsEnum nextObject]))
{
NSRect subviewFrame = [curSubView frame];
subframeBounds = NSUnionRect(subviewFrame, subframeBounds);
}
NSRect myBounds = [self bounds];
mIntrinsicPadding[NSMinXEdge] = NSMinX(subframeBounds);
mIntrinsicPadding[NSMinYEdge] = NSMinY(subframeBounds);
mIntrinsicPadding[NSMaxXEdge] = NSWidth(myBounds) - NSMaxX(subframeBounds);
mIntrinsicPadding[NSMaxYEdge] = NSHeight(myBounds) - NSMaxY(subframeBounds);
mFetchedIntrinsicPadding = YES;
}
- (void)adaptToSubviews
{
// we can't rely on -awakeFromNib being called in any particular order,
// so we have to call -recalcPadding here, rather than from -awakeFromNib.
[self recalcPadding];
if (mSelfResizing) return;
if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] &&
[NSObject editingInInterfaceBuilder])
{
return;
}
#if 0
NSLog(@"%@ padding: %f %f %f %f", self, mIntrinsicPadding[0],
mIntrinsicPadding[1],
mIntrinsicPadding[2],
mIntrinsicPadding[3]);
#endif
NSRect subframeBounds = NSZeroRect;
NSEnumerator* subviewsEnum = [[self subviews] objectEnumerator];
NSView* curSubView;
while ((curSubView = [subviewsEnum nextObject]))
{
NSRect subviewFrame = [curSubView frame];
subframeBounds = NSUnionRect(subviewFrame, subframeBounds);
}
subframeBounds.origin.x = mIntrinsicPadding[NSMinXEdge];
subframeBounds.origin.y = mIntrinsicPadding[NSMinYEdge];
subframeBounds.size.width += mIntrinsicPadding[NSMaxXEdge];
subframeBounds.size.height += mIntrinsicPadding[NSMaxYEdge];
NSSize curSize = [self frame].size;
NSSize newSize = curSize;
if (!([self autoresizingMask] & NSViewWidthSizable))
newSize.width = NSMaxX(subframeBounds);
if (!([self autoresizingMask] & NSViewHeightSizable))
newSize.height = NSMaxY(subframeBounds);
if (!NSEqualSizes(curSize, newSize))
{
// NSLog(@"resize %@ to %@", self, NSStringFromSize(newSize));
mSelfResizing = YES;
[self setFrameSizeMaintainingTopLeftOrigin:newSize];
mSelfResizing = NO;
[super setNeedsDisplay:YES];
}
}
- (void)setupNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(viewBoundsChangedNotification:)
name:NSViewBoundsDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(viewFrameChangedNotification:)
name:NSViewFrameDidChangeNotification
object:nil];
}
- (void)viewBoundsChangedNotification:(NSNotification*)inNotification
{
NSView* changedView = [inNotification object];
if (changedView == self)
[self recalcPadding];
else if ([self hasSubview:changedView])
[self adaptToSubviews];
}
- (void)viewFrameChangedNotification:(NSNotification*)inNotification
{
NSView* changedView = [inNotification object];
if (changedView == self)
[self recalcPadding];
else if ([self hasSubview:changedView])
[self adaptToSubviews];
}
- (BOOL)isFlipped
{
// not flipped because that IB freaks out when editing if it is
return NO;
}
@end
#pragma mark -
@implementation CHFlippedShrinkWrapView
- (BOOL)isFlipped
{
return YES;
}
@end
#pragma mark -
NSString* const kStackViewReloadNotificationName = @"ReloadStackView";
NSString* const kStackViewResizedNotificationName = @"StackViewResized";
@interface CHStackView(Private)
- (NSArray*)managedSubviews;
@end
@implementation CHStackView
-(id)initWithFrame:(NSRect)frameRect
{
if ((self = [super initWithFrame:frameRect])) {
// Register for notifications when one of the subviews changes size
if ((self = [super initWithFrame:frameRect]))
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadNotification:)
name:StackViewReloadNotificationName
name:kStackViewReloadNotificationName
object:nil];
}
return self;
}
- (void)awakeFromNib
{
// if we're thawed from a nib, and we don't have any subviews, then we seem
// to have subview resizing turned off, but we want it on.
[self setAutoresizesSubviews:YES];
if ([super respondsToSelector:@selector(awakeFromNib)])
[super awakeFromNib];
[self adaptToSubviews];
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
@ -74,66 +333,144 @@ NSString* StackViewResizedNotificationName = @"StackViewResized";
-(void)setDataSource:(id)aDataSource
{
mDataSource = aDataSource; // should this retain?
[self reloadSubviews];
[self adaptToSubviews];
}
-(void)reloadNotification:(NSNotification*)notification
{
[self reloadSubviews];
[self adaptToSubviews];
}
-(void)reloadSubviews
- (void)didAddSubview:(NSView *)subview
{
NSRect newFrame = [self frame];
NSSize oldSize = [self bounds].size;
int i, subviewCount = [mDataSource subviewsForStackView:self];
NSPoint nextOrigin = NSZeroPoint;
// maintain the width of the stack view, assuming that it's scaled by its superview.
newFrame.size.height = 0.0;
[self removeAllSubviews];
for (i = 0; i < subviewCount; i++) {
NSView *subview = [mDataSource viewForStackView:self atIndex:i];
NSRect subviewFrame = [subview frame];
NSBox *separator;
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];
// always add a separator
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];
[super didAddSubview:subview];
// [subview setAutoresizingMask:([subview autoresizingMask] | NSViewMinYMargin)];
}
- (void)drawRect:(NSRect)inRect
{
if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] &&
[NSObject editingInInterfaceBuilder])
{
[[NSColor orangeColor] set];
NSFrameRect([self bounds]);
}
}
-(void)adaptToSubviews
{
if (mSelfResizing) return; // avoid re-entry
if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] &&
[NSObject editingInInterfaceBuilder])
{
return;
}
// NSLog(@"%@ frame %@", self, NSStringFromRect([self frame]));
const float kSeparatorHeight = 1.0f;
NSRect newBounds = newFrame;
newBounds.origin = NSZeroPoint;
NSSize mySize = [self frame].size;
NSSize oldSize = mySize;
float totalHeightOfSubviews = 0.0f;
// we're not flipped because that freaks out editing in IB. So
// we have to do this in 2 passes; one to resize the subviews, and
// a second to place them (after sizing ourselves).
NSEnumerator* stackViewsEnum = [[self managedSubviews] objectEnumerator];
NSView* curView;
while ((curView = [stackViewsEnum nextObject]))
{
NSSize subviewFrameSize = [curView frame].size;
unsigned int autoResizeMask = [curView autoresizingMask];
if ((autoResizeMask & NSViewWidthSizable) && (subviewFrameSize.width != mySize.width))
{
subviewFrameSize.width = mySize.width;
mSelfResizing = YES;
[curView setFrameSize:subviewFrameSize];
mSelfResizing = NO;
// setting the width may have changed the height, so fetch it again
subviewFrameSize = [curView frame].size;
}
totalHeightOfSubviews += subviewFrameSize.height;
if (mShowsSeparators && mDataSource)
totalHeightOfSubviews += kSeparatorHeight;
}
// resize self now
mySize.height = totalHeightOfSubviews;
[self setFrame:newFrame];
mSelfResizing = YES;
[self setFrameSizeMaintainingTopLeftOrigin:mySize];
mSelfResizing = NO;
[self setNeedsDisplay:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:StackViewResizedNotificationName
// now place the subviews
if (mDataSource)
[self removeAllSubviews]; // should we keep a copy of the array to make sure they survive?
float curMaxY = totalHeightOfSubviews;
stackViewsEnum = [[self managedSubviews] objectEnumerator];
while ((curView = [stackViewsEnum nextObject]))
{
NSRect subviewFrame = [curView frame];
curMaxY -= NSHeight(subviewFrame);
subviewFrame.origin.y = curMaxY;
mSelfResizing = YES;
[curView setFrameOrigin:subviewFrame.origin];
mSelfResizing = NO;
if (mDataSource)
[self addSubview:curView];
if (mShowsSeparators && mDataSource)
{
curMaxY -= kSeparatorHeight;
NSBox* separator = [[NSBox alloc] initWithFrame:
NSMakeRect(subviewFrame.origin.x, curMaxY, NSWidth(subviewFrame), kSeparatorHeight)];
[separator setBoxType:NSBoxSeparator];
[separator setAutoresizingMask:NSViewWidthSizable];
[self addSubview:separator];
[separator release];
}
}
[[NSNotificationCenter defaultCenter] postNotificationName:kStackViewResizedNotificationName
object:self
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithSize:oldSize], @"oldsize", nil]];
}
- (BOOL)showsSeparators
{
return mShowsSeparators;
}
- (void)setShowsSeparators:(BOOL)inShowSeparators
{
mShowsSeparators = inShowSeparators;
}
-(BOOL)isFlipped
{
return YES;
// not flipped because that IB freaks out when editing if it is
// (so the math is harder in -adaptToSubviews. oh well).
return NO;
}
- (NSArray*)managedSubviews
{
if (mDataSource)
return [mDataSource subviewsForStackView:self];
return [self subviews];
}
@end

Просмотреть файл

@ -67,4 +67,12 @@ BOOL CHCloseSizes(NSSize aSize, NSSize bSize, float slop);
- (void)removeAllSubviews;
// is 'inView' an immediate subview of the receiver
- (BOOL)hasSubview:(NSView*)inView;
- (void)setFrameSizeMaintainingTopLeftOrigin:(NSSize)inNewSize;
// convert inRect to view coords depending on whether the view is flipped
- (NSRect)subviewRectFromTopRelativeRect:(NSRect)inRect;
@end

Просмотреть файл

@ -191,4 +191,33 @@ static void RedistributeSpace(int resizeMask, float newWidth, /* in out */ float
[subviewsArray release];
}
- (BOOL)hasSubview:(NSView*)inView
{
return [[self subviews] containsObject:inView];
}
- (void)setFrameSizeMaintainingTopLeftOrigin:(NSSize)inNewSize
{
if ([[self superview] isFlipped])
[self setFrameSize:inNewSize];
else
{
NSRect newFrame = [self frame];
newFrame.origin.y -= (inNewSize.height - newFrame.size.height);
newFrame.size = inNewSize;
[self setFrame:newFrame];
}
}
- (NSRect)subviewRectFromTopRelativeRect:(NSRect)inRect
{
if ([self isFlipped])
return inRect;
NSRect theRect = inRect;
theRect.origin.y = NSHeight([self bounds]) - NSMaxY(inRect);
return theRect;
}
@end

Просмотреть файл

@ -0,0 +1,61 @@
/* ***** 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Simon Fraser <smfr@smfr.org>
*
* 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>
#import "NSString+Utils.h" // for ETruncationType
//
// TruncatingTextFieldCell
//
// Text field cell that can be used to truncate text in a text field.
//
// Use by creating one and setting it as the cell on an NSTextField.
//
@interface TruncatingTextFieldCell : NSTextFieldCell
{
NSString* mOriginalStringValue; // copy of the whole string
ETruncationType mTruncationPosition;
}
- (id)initTextCell:(NSString*)inTextValue truncation:(ETruncationType)truncType;
- (void)setTruncationPosition:(ETruncationType)truncType;
- (ETruncationType)truncationPosition;
@end

Просмотреть файл

@ -0,0 +1,122 @@
/* ***** 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Simon Fraser <smfr@smfr.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#import "NSString+Utils.h"
#import "TruncatingTextFieldCell.h"
@interface TruncatingTextFieldCell(Private)
- (NSString*)truncatedStringForRect:(NSRect)inRect;
- (NSDictionary*)fontAttributes;
- (NSRect)textBoundsForFrame:(NSRect)inFrameRect;
@end
@implementation TruncatingTextFieldCell
// designated initializer
- (id)initTextCell:(NSString*)inTextValue
{
if ((self = [super initTextCell:inTextValue]))
{
mTruncationPosition = kTruncateAtEnd;
}
return self;
}
- (id)initTextCell:(NSString*)inTextValue truncation:(ETruncationType)truncType
{
if ((self = [self initTextCell:inTextValue]))
{
mTruncationPosition = truncType;
}
return self;
}
- (void)setTruncationPosition:(ETruncationType)truncType
{
mTruncationPosition = truncType;
// redo truncation?
}
- (ETruncationType)truncationPosition
{
return mTruncationPosition;
}
- (void)setStringValue:(NSString*)inValue
{
NSString* oldValue = mOriginalStringValue;
mOriginalStringValue = [inValue retain];
[oldValue release];
[super setStringValue:inValue];
}
- (NSString*)stringValue
{
return mOriginalStringValue;
}
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
[super setStringValue:[self truncatedStringForRect:cellFrame]];
[super drawInteriorWithFrame:cellFrame inView:controlView];
}
- (NSString*)truncatedStringForRect:(NSRect)inRect
{
NSRect textRect = [self textBoundsForFrame:inRect];
return [mOriginalStringValue stringByTruncatingToWidth:NSWidth(textRect)
at:mTruncationPosition
withAttributes:[self fontAttributes]];
}
- (NSDictionary*)fontAttributes
{
return [NSDictionary dictionaryWithObject:[self font] forKey:NSFontAttributeName];
}
- (NSRect)textBoundsForFrame:(NSRect)inFrameRect
{
// values derived empirically
return NSInsetRect(inFrameRect, 2.0f, 0.0f);
}
@end

Просмотреть файл

@ -37,13 +37,18 @@
* ***** END LICENSE BLOCK ***** */
#import <AppKit/AppKit.h>
#import "CHStackView.h"
@class CertificateItem;
// this is a view that builds its contents dynamically from the cert.
@interface CertificateView : NSView
@interface CertificateView : CHShrinkWrapView
{
NSView* mContentView; // created dynamically, retained
CHStackView* mContentView; // created dynamically, retained
NSView* mTrustItemsView; // weak
NSView* mDetailsItemsView; // weak
BOOL mDetailsExpanded;
BOOL mTrustExpanded;

Просмотреть файл

@ -50,35 +50,20 @@
#import "nsServiceManagerUtils.h"
#import "AutoSizingTextField.h"
#import "CHStackView.h"
#import "CertificateItem.h"
#import "CertificateView.h"
#pragma mark CertificateContentsView
#pragma mark -
@interface CertificateContentsView : NSView
{
}
@end
@implementation CertificateContentsView
- (BOOL)isFlipped
{
return YES;
}
@end
#pragma mark -
const float kCertImageViewSize = 64.0f;
const float kCertHeaderFieldVerticalGap = 4.0f;
const float kCertHeaderFieldRightGap = 4.0f;
const float kStatusImageSize = 12.0f;
const float kGroupHeaderLeftOffset = 4.0f;
const float kGapAboveGroup = 2.0f;
const float kGapUnderGroupHeader = 5.0f;
const float kDisclosureLabelGap = 4.0f;
@ -87,12 +72,14 @@ const float kDisclosureButtonSize = 12.0f;
const float kGeneralRightGap = 4.0f;
const float kHeaderLeftOffset = 16.0f;
const float kGapUnderHeader = 5.0f;
const float kGapAboveHeader = 2.0f;
const float kGapUnderHeader = 3.0f;
const float kGapUnderGroup = 5.0f;
const float kLabelLeftOffset = 16.0f;
const float kLabelGutterWidth = 10.0f;
const float kGapUnderLine = 5.0f;
const float kGapUnderLine = 5.0f;
const float kGapUnderCheckboxLine = 3.0f;
#pragma mark -
#pragma mark CertificateView
@ -102,20 +89,25 @@ const float kGapUnderLine = 5.0f;
- (float)labelColumnWidth;
- (NSTextField*)textFieldWithInitialFrame:(NSRect)inFrame stringValue:(NSString*)inString small:(BOOL)useSmallFont bold:(BOOL)useBold;
- (CHShrinkWrapView*)containerViewWithTopPadding:(float)inTop bottomPadding:(float)inBottom;
- (NSTextField*)textFieldWithInitialFrame:(NSRect)inFrame stringValue:(NSString*)inString autoSizing:(BOOL)inAutosize small:(BOOL)useSmallFont bold:(BOOL)useBold;
- (void)addGroupingWithKey:(NSString*)inLabelKey expanded:(BOOL)inExpanded action:(SEL)inAction atOffset:(float*)ioOffset;
- (void)addHeaderWithKey:(NSString*)inLabelKey atOffset:(float*)ioOffset;
- (void)addLineWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData atOffset:(float*)ioOffset ignoreBlankLines:(BOOL)inIgnoreBlank;
- (void)addScrollingTextFieldWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData atOffset:(float*)ioOffset ignoreBlankLines:(BOOL)inIgnoreBlank;
- (NSButton*)addButtonLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction atOffset:(float*)ioOffset;
- (NSButton*)addCheckboxLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction atOffset:(float*)ioOffset;
- (CHStackView *)groupingWithKey:(NSString*)inLabelKey expanded:(BOOL)inExpanded action:(SEL)inAction;
- (NSView*)headerWithKey:(NSString*)inLabelKey;
- (NSTextField*)addLineLabelWithKey:(NSString*)inLabelKey toView:(NSView*)inLineContainerView;
- (NSView*)wholeLineLabelWithKey:(NSString*)inLabelKey;
- (NSView*)lineWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData ignoreBlankLines:(BOOL)inIgnoreBlank;
- (NSView*)scrollingTextFieldWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData ignoreBlankLines:(BOOL)inIgnoreBlank;
- (NSView*)buttonLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction button:(NSButton**)outButton;
- (NSView*)checkboxLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction button:(NSButton**)outButton;
- (void)refreshView;
- (float)rebuildCertHeader;
- (void)rebuildCertHeader;
- (void)rebuildCertContent;
- (float)rebuildDetails:(float)inOffset;
- (float)rebuildTrustSettings:(float)inOffset;
- (void)rebuildDetails;
- (void)rebuildTrustSettings;
- (BOOL)showTrustSettings;
- (IBAction)trustCheckboxClicked:(id)inSender;
@ -290,13 +282,83 @@ const float kGapUnderLine = 5.0f;
- (float)labelColumnWidth
{
// measure all the label strings?
return 120.0f;
static BOOL sGotWidth = NO;
static float sLongestLabelWidth = 0.0f;
if (!sGotWidth)
{
NSArray* labelKeys = [NSArray arrayWithObjects:
@"IssuedTo",
@"OwnerCommonName",
@"OwnerEmailAddress",
@"OwnerOrganization",
@"OwnerOrgUnit",
@"Version",
@"SerialNumber",
@"IssuedBy",
@"IssuerCommonName",
@"IssuerOrganization",
@"IssuerOrgUnit",
@"ShowIssuerCertLabel",
@"Validity",
@"NotBeforeLocalTime",
@"NotAfterLocalTime",
@"SigAlgorithm",
@"Signature",
@"PublicKeyInfo",
@"PublicKeyAlgorithm",
@"PublicKey",
@"UsagesTitle",
@"Usages",
@"Fingerprints",
@"SHA1Fingerprint",
@"MD5Fingerprint",
nil];
float maxWidth = 0.0f;
NSDictionary* fontAttributes = [NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]
forKey:NSFontAttributeName];
NSEnumerator* keysEnum = [labelKeys objectEnumerator];
NSString* curKey;
while ((curKey = [keysEnum nextObject]))
{
NSString* theLabel = NSLocalizedStringFromTable(curKey, @"CertificateDialogs", @"");
NSSize stringSize = [theLabel sizeWithAttributes:fontAttributes];
if (stringSize.width > maxWidth)
maxWidth = stringSize.width;
}
if (maxWidth < 120.0f)
maxWidth = 120.0f;
sLongestLabelWidth = maxWidth;
sGotWidth = YES;
}
return sLongestLabelWidth;
}
- (NSTextField*)textFieldWithInitialFrame:(NSRect)inFrame stringValue:(NSString*)inString small:(BOOL)useSmallFont bold:(BOOL)useBold
- (CHShrinkWrapView*)containerViewWithTopPadding:(float)inTop bottomPadding:(float)inBottom
{
NSTextField* theTextField = [[[NSTextField alloc] initWithFrame:inFrame] autorelease];
// the origin of the rect doesn't matter, and we'll resize the height later
NSRect headerRect = NSMakeRect(0, 0, NSWidth([self frame]), NSHeight([self frame]));
CHShrinkWrapView* containerView = [[[CHShrinkWrapView alloc] initWithFrame:headerRect] autorelease];
[containerView setIntrinsicPadding:kGroupHeaderLeftOffset forEdge:NSMinXEdge];
[containerView setIntrinsicPadding:inBottom forEdge:NSMinYEdge];
[containerView setIntrinsicPadding:kGroupHeaderLeftOffset forEdge:NSMaxXEdge];
[containerView setIntrinsicPadding:inTop forEdge:NSMaxYEdge];
[containerView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
return containerView;
}
- (NSTextField*)textFieldWithInitialFrame:(NSRect)inFrame stringValue:(NSString*)inString autoSizing:(BOOL)inAutosize small:(BOOL)useSmallFont bold:(BOOL)useBold
{
NSTextField* theTextField;
if (inAutosize)
theTextField = [[[AutoSizingTextField alloc] initWithFrame:inFrame] autorelease];
else
theTextField = [[[NSTextField alloc] initWithFrame:inFrame] autorelease];
[theTextField setEditable:NO];
[theTextField setSelectable:YES];
NSFont* fieldFont;
@ -310,210 +372,241 @@ const float kGapUnderLine = 5.0f;
[theTextField setDrawsBackground:NO];
[theTextField setBezeled:NO];
[theTextField setStringValue:inString ? inString : @""];
[[theTextField cell] setWraps:NO];
[[theTextField cell] setWraps:inAutosize];
[theTextField setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
NSSize theCellSize = [[theTextField cell] cellSizeForBounds:inFrame];
theCellSize.width = NSWidth(inFrame); // keep the provided width
[theTextField setFrameSize:theCellSize];
//[theTextField sizeToFit];
[theTextField setFrameSizeMaintainingTopLeftOrigin:theCellSize];
return theTextField;
}
- (void)addGroupingWithKey:(NSString*)inLabelKey expanded:(BOOL)inExpanded action:(SEL)inAction atOffset:(float*)ioOffset
- (CHStackView *)groupingWithKey:(NSString*)inLabelKey expanded:(BOOL)inExpanded action:(SEL)inAction
{
NSRect lineRect = NSMakeRect(kGroupHeaderLeftOffset, *ioOffset + kGroupHeaderLeftOffset, NSWidth([self frame]) - 2 * kGroupHeaderLeftOffset, 100.0f);
NSRect stackFrame = [self bounds];
CHStackView* groupContainer = [[[CHStackView alloc] initWithFrame:stackFrame] autorelease];
[groupContainer setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
NSView* lineContainer = [self containerViewWithTopPadding:kGapAboveGroup bottomPadding:kGapUnderGroupHeader];
NSRect buttonRect;
NSRect lineRect = NSMakeRect(kGroupHeaderLeftOffset, 0.0f, NSWidth([self frame]) - 2 * kGroupHeaderLeftOffset, 100.0f);
NSRect buttonRect = NSMakeRect(0, 0, kDisclosureButtonSize, kDisclosureButtonSize);
buttonRect.origin = lineRect.origin;
buttonRect.size = NSMakeSize(kDisclosureButtonSize, kDisclosureButtonSize);
NSButton* theButton = [[[NSButton alloc] initWithFrame:buttonRect] autorelease];
NSButton* theButton = [[[NSButton alloc] initWithFrame:[groupContainer subviewRectFromTopRelativeRect:buttonRect]] autorelease];
[theButton setBordered:NO];
[theButton setImage: inExpanded ? [NSImage imageNamed:@"triangle_down_normal"] : [NSImage imageNamed:@"triangle_right_normal"]];
[theButton setAlternateImage:inExpanded ? [NSImage imageNamed:@"triangle_down_pressed"] : [NSImage imageNamed:@"triangle_right_pressed"]];
[theButton setButtonType:NSMomentaryChangeButton];
[theButton setAction:inAction];
[theButton setTarget:self];
[mContentView addSubview:theButton];
[theButton setAutoresizingMask:NSViewMinYMargin];
[lineContainer addSubview:theButton];
lineRect.origin.x = NSMaxX(buttonRect) + kDisclosureLabelGap;
NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @"");
NSTextField* headerField = [self textFieldWithInitialFrame:lineRect stringValue:theLabel small:YES bold:YES];
[mContentView addSubview:headerField];
NSTextField* headerField = [self textFieldWithInitialFrame:[groupContainer subviewRectFromTopRelativeRect:lineRect] stringValue:theLabel autoSizing:NO small:YES bold:YES];
[lineContainer addSubview:headerField];
float buttonBottom = NSMaxY([theButton frame]);
float labelBottom = NSMaxY([headerField frame]);
float maxYPos = (buttonBottom > labelBottom) ? buttonBottom : labelBottom;
*ioOffset = maxYPos + kGapUnderGroupHeader;
[groupContainer addSubview:lineContainer];
return groupContainer;
}
- (void)addHeaderWithKey:(NSString*)inLabelKey atOffset:(float*)ioOffset
- (NSView*)headerWithKey:(NSString*)inLabelKey
{
NSView* headerContainer = [self containerViewWithTopPadding:kGapAboveHeader bottomPadding:kGapUnderHeader];
float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap;
NSRect headerRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f);
NSRect headerRect = NSMakeRect(labelOffset, 0.0f, [self labelColumnWidth], 100.0f);
NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @"");
NSTextField* headerField = [self textFieldWithInitialFrame:headerRect stringValue:theLabel small:YES bold:YES];
[mContentView addSubview:headerField];
NSTextField* headerField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:headerRect] stringValue:theLabel autoSizing:NO small:YES bold:YES];
[headerField setAlignment:NSRightTextAlignment];
[headerField setTextColor:[NSColor lightGrayColor]];
[headerField setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
[headerContainer addSubview:headerField];
*ioOffset = NSMaxY([headerField frame]) + kGapUnderHeader;
NSFont* labelFont = [[headerField cell] font];
float baselineOffset = [labelFont ascender];
float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth;
NSRect boxFrame = NSMakeRect(xPos, baselineOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 2.0f);
NSBox* lineBox = [[[NSBox alloc] initWithFrame:[headerContainer subviewRectFromTopRelativeRect:boxFrame]] autorelease];
[lineBox setBoxType:NSBoxSeparator];
[lineBox setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
[headerContainer addSubview:lineBox];
return headerContainer;
}
// returns current V offset
- (void)addLineWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData atOffset:(float*)ioOffset ignoreBlankLines:(BOOL)inIgnoreBlank
- (NSTextField*)addLineLabelWithKey:(NSString*)inLabelKey toView:(NSView*)inLineContainerView
{
float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap;
NSRect labelRect = NSMakeRect(labelOffset, 0.0f, [self labelColumnWidth], 100.0f);
NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @"");
NSTextField* labelField = [self textFieldWithInitialFrame:[inLineContainerView subviewRectFromTopRelativeRect:labelRect] stringValue:theLabel autoSizing:NO small:YES bold:NO];
[labelField setAlignment:NSRightTextAlignment];
[labelField setTextColor:[NSColor darkGrayColor]];
[labelField setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
[inLineContainerView addSubview:labelField];
return labelField;
}
- (NSView*)wholeLineLabelWithKey:(NSString*)inLabelKey
{
NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderLine];
float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap;
NSRect labelRect = NSMakeRect(labelOffset, 0.0f, NSWidth([self frame]) - labelOffset, 100.0f);
NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @"");
NSTextField* labelField = [self textFieldWithInitialFrame:[lineContainer subviewRectFromTopRelativeRect:labelRect] stringValue:theLabel autoSizing:YES small:YES bold:NO];
[lineContainer addSubview:labelField];
return lineContainer;
}
- (NSView*)lineWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData ignoreBlankLines:(BOOL)inIgnoreBlank
{
if (inIgnoreBlank && [inData length] == 0)
return;
float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap;
NSRect labelRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f);
NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @"");
NSTextField* labelField = [self textFieldWithInitialFrame:labelRect stringValue:theLabel small:YES bold:NO];
[mContentView addSubview:labelField];
return nil;
NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderLine];
[self addLineLabelWithKey:inLabelKey toView:lineContainer];
float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth;
NSRect dataRect = NSMakeRect(xPos, *ioOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f);
NSTextField* dataField = [self textFieldWithInitialFrame:dataRect stringValue:inData small:YES bold:NO];
[dataField setAutoresizingMask:NSViewWidthSizable | NSViewMaxYMargin];
[mContentView addSubview:dataField];
float labelBottom = NSMaxY([labelField frame]);
float dataBottom = NSMaxY([dataField frame]);
float maxYPos = (dataBottom > labelBottom) ? dataBottom : labelBottom;
*ioOffset = maxYPos + kGapUnderLine;
NSRect dataRect = NSMakeRect(xPos, 0.0f, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f);
NSTextField* dataField = [self textFieldWithInitialFrame:[lineContainer subviewRectFromTopRelativeRect:dataRect] stringValue:inData autoSizing:YES small:YES bold:NO];
[lineContainer addSubview:dataField];
return lineContainer;
}
- (void)addScrollingTextFieldWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData atOffset:(float*)ioOffset ignoreBlankLines:(BOOL)inIgnoreBlank
- (NSView*)scrollingTextFieldWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData ignoreBlankLines:(BOOL)inIgnoreBlank
{
if (inIgnoreBlank && [inData length] == 0)
return;
return nil;
float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap;
NSRect labelRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f);
NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @"");
NSTextField* labelField = [self textFieldWithInitialFrame:labelRect stringValue:theLabel small:YES bold:NO];
[mContentView addSubview:labelField];
NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderLine];
[self addLineLabelWithKey:inLabelKey toView:lineContainer];
float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth;
NSRect dataRect = NSMakeRect(xPos, *ioOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 56.0f);
NSRect dataRect = NSMakeRect(xPos, 0.0f, NSWidth([self frame]) - xPos - kLabelLeftOffset, 56.0f);
dataRect = [lineContainer subviewRectFromTopRelativeRect:dataRect];
NSScrollView* dataScrollView = [[[NSScrollView alloc] initWithFrame:dataRect] autorelease];
NSTextView* scrolledTextView = [[[NSTextView alloc] initWithFrame:dataRect] autorelease];
[dataScrollView setHasVerticalScroller:YES];
[dataScrollView setBorderType:NSBezelBorder];
[dataScrollView setAutoresizingMask:NSViewWidthSizable | NSViewMaxYMargin];
[dataScrollView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
[[dataScrollView verticalScroller] setControlSize:NSSmallControlSize];
if (inData)
[[[scrolledTextView textStorage] mutableString] setString:[inData stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
[scrolledTextView setFont:[NSFont fontWithName:@"Monaco" size:10.0f]];
[scrolledTextView setEditable:NO];
[dataScrollView setAutoresizingMask:NSViewWidthSizable];
[dataScrollView setDocumentView:scrolledTextView];
[mContentView addSubview:dataScrollView];
float labelBottom = NSMaxY([labelField frame]);
float dataBottom = NSMaxY([dataScrollView frame]);
float maxYPos = (dataBottom > labelBottom) ? dataBottom : labelBottom;
*ioOffset = maxYPos + kGapUnderLine;
[lineContainer addSubview:dataScrollView];
return lineContainer;
}
- (NSButton*)addButtonLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction atOffset:(float*)ioOffset
- (NSView*)buttonLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction button:(NSButton**)outButton
{
float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap;
NSRect labelRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f);
NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @"");
NSTextField* labelField = [self textFieldWithInitialFrame:labelRect stringValue:theLabel small:YES bold:NO];
[mContentView addSubview:labelField];
NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderLine];
[self addLineLabelWithKey:inLabelKey toView:lineContainer];
float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth;
NSRect buttonRect = NSMakeRect(xPos, *ioOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f);
NSButton* theButton = [[[NSButton alloc] initWithFrame:buttonRect] autorelease];
NSRect buttonRect = NSMakeRect(xPos, 0.0f, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f);
NSButton* theButton = [[[NSButton alloc] initWithFrame:[lineContainer subviewRectFromTopRelativeRect:buttonRect]] autorelease];
[theButton setTitle:NSLocalizedStringFromTable(buttonKey, @"CertificateDialogs", @"")];
[theButton setBezelStyle:NSRoundedBezelStyle];
[theButton setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
[[theButton cell] setControlSize:NSSmallControlSize];
[theButton sizeToFit];
//[theButton sizeToFit];
NSSize theCellSize = [[theButton cell] cellSizeForBounds:[theButton frame]];
[theButton setFrameSizeMaintainingTopLeftOrigin:theCellSize];
[theButton setAutoresizingMask:NSViewMinYMargin];
[theButton setAction:inAction];
[theButton setTarget:self];
[mContentView addSubview:theButton];
[lineContainer addSubview:theButton];
float labelBottom = NSMaxY([labelField frame]);
float buttonBottom = NSMaxY([theButton frame]);
float maxYPos = (buttonBottom > labelBottom) ? buttonBottom : labelBottom;
*ioOffset = maxYPos + kGapUnderLine;
return theButton;
if (outButton)
*outButton = theButton;
return lineContainer;
}
- (NSButton*)addCheckboxLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction atOffset:(float*)ioOffset
- (NSView*)checkboxLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction button:(NSButton**)outButton
{
float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap;
NSRect labelRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f);
NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @"");
NSTextField* labelField = [self textFieldWithInitialFrame:labelRect stringValue:theLabel small:YES bold:NO];
[mContentView addSubview:labelField];
NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderCheckboxLine];
if ([inLabelKey length] > 0)
[self addLineLabelWithKey:inLabelKey toView:lineContainer];
float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth;
NSRect buttonRect = NSMakeRect(xPos, *ioOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f);
NSButton* theButton = [[[NSButton alloc] initWithFrame:buttonRect] autorelease];
NSRect buttonRect = NSMakeRect(xPos, 0.0f, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f);
NSButton* theButton = [[[NSButton alloc] initWithFrame:[lineContainer subviewRectFromTopRelativeRect:buttonRect]] autorelease];
[theButton setTitle:NSLocalizedStringFromTable(buttonKey, @"CertificateDialogs", @"")];
[theButton setButtonType:NSSwitchButton];
[theButton setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
[[theButton cell] setControlSize:NSSmallControlSize];
[theButton sizeToFit];
[theButton setAutoresizingMask:NSViewWidthSizable | NSViewMaxYMargin];
// resize maintaining the width
NSRect wideButtonRect = buttonRect;
wideButtonRect.size.width = 1000.0f; // if the width is narrow, -cellSizeForBounds: returns a greater height, which we don't want.
NSSize theCellSize = [[theButton cell] cellSizeForBounds:wideButtonRect];
theCellSize.width = NSWidth(buttonRect);
[theButton setFrameSizeMaintainingTopLeftOrigin:theCellSize];
[theButton setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
[theButton setAction:inAction];
[theButton setTarget:self];
[mContentView addSubview:theButton];
[lineContainer addSubview:theButton];
float labelBottom = NSMaxY([labelField frame]);
float buttonBottom = NSMaxY([theButton frame]);
float maxYPos = (buttonBottom > labelBottom) ? buttonBottom : labelBottom;
*ioOffset = maxYPos + kGapUnderLine;
return theButton;
if (outButton)
*outButton = theButton;
return lineContainer;
}
- (float)rebuildDetails:(float)inOffset
- (void)rebuildDetails
{
float curOffset = inOffset;
[self addGroupingWithKey:@"CertDetailsGroupHeader" expanded:mDetailsExpanded action:@selector(toggleDetails:) atOffset:&curOffset];
curOffset += kGapUnderHeader;
mDetailsItemsView = [self groupingWithKey:@"CertDetailsGroupHeader" expanded:mDetailsExpanded action:@selector(toggleDetails:)];
[mContentView addSubview:mDetailsItemsView];
if (!mDetailsExpanded)
return curOffset;
[self addHeaderWithKey:@"IssuedTo" atOffset:&curOffset];
return;
//
// NOTE: add label string keys to the array in -labelColumnWidth if you add new ones.
//
[mDetailsItemsView addSubview:[self headerWithKey:@"IssuedTo"]];
// Owner stuff
[self addLineWithLabelKey:@"OwnerCommonName" data:[mCertItem commonName] atOffset:&curOffset ignoreBlankLines:YES];
[self addLineWithLabelKey:@"OwnerEmailAddress" data:[mCertItem emailAddress] atOffset:&curOffset ignoreBlankLines:YES];
[self addLineWithLabelKey:@"OwnerOrganization" data:[mCertItem organization] atOffset:&curOffset ignoreBlankLines:YES];
[self addLineWithLabelKey:@"OwnerOrgUnit" data:[mCertItem organizationalUnit] atOffset:&curOffset ignoreBlankLines:YES];
[self addLineWithLabelKey:@"Version" data:[mCertItem version] atOffset:&curOffset ignoreBlankLines:YES];
[self addLineWithLabelKey:@"SerialNumber" data:[mCertItem serialNumber] atOffset:&curOffset ignoreBlankLines:YES];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"OwnerCommonName" data:[mCertItem commonName] ignoreBlankLines:YES]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"OwnerEmailAddress" data:[mCertItem emailAddress] ignoreBlankLines:YES]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"OwnerOrganization" data:[mCertItem organization] ignoreBlankLines:YES]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"OwnerOrgUnit" data:[mCertItem organizationalUnit] ignoreBlankLines:YES]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"Version" data:[mCertItem version] ignoreBlankLines:YES]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"SerialNumber" data:[mCertItem serialNumber] ignoreBlankLines:YES]];
// Issuer stuff
curOffset += kGapUnderGroup;
[self addHeaderWithKey:@"IssuedBy" atOffset:&curOffset];
[mDetailsItemsView addSubview:[self headerWithKey:@"IssuedBy"]];
[self addLineWithLabelKey:@"IssuerCommonName" data:[mCertItem issuerCommonName] atOffset:&curOffset ignoreBlankLines:YES];
[self addLineWithLabelKey:@"IssuerOrganization" data:[mCertItem issuerOrganization] atOffset:&curOffset ignoreBlankLines:YES];
[self addLineWithLabelKey:@"IssuerOrgUnit" data:[mCertItem issuerOrganizationalUnit] atOffset:&curOffset ignoreBlankLines:YES];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"IssuerCommonName" data:[mCertItem issuerCommonName] ignoreBlankLines:YES]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"IssuerOrganization" data:[mCertItem issuerOrganization] ignoreBlankLines:YES]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"IssuerOrgUnit" data:[mCertItem issuerOrganizationalUnit] ignoreBlankLines:YES]];
nsCOMPtr<nsIX509Cert> issuerCert;
nsIX509Cert* thisCert = [mCertItem cert];
@ -521,93 +614,83 @@ const float kGapUnderLine = 5.0f;
thisCert->GetIssuer(getter_AddRefs(issuerCert));
if (issuerCert && ![mCertItem isSameCertAs:issuerCert])
{
[self addButtonLineWithLabelKey:@"ShowIssuerCertLabel"
buttonLabelKey:@"ShowIssuerCertButton"
action:@selector(showIssuerCert:)
atOffset:&curOffset];
[mDetailsItemsView addSubview:[self buttonLineWithLabelKey:@"ShowIssuerCertLabel"
buttonLabelKey:@"ShowIssuerCertButton"
action:@selector(showIssuerCert:)
button:NULL]];
}
// validity
curOffset += kGapUnderGroup;
[self addHeaderWithKey:@"Validity" atOffset:&curOffset];
[mDetailsItemsView addSubview:[self headerWithKey:@"Validity"]];
[self addLineWithLabelKey:@"NotBeforeLocalTime" data:[mCertItem longValidFromString] atOffset:&curOffset ignoreBlankLines:NO];
[self addLineWithLabelKey:@"NotAfterLocalTime" data:[mCertItem longExpiresString] atOffset:&curOffset ignoreBlankLines:NO];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"NotBeforeLocalTime" data:[mCertItem longValidFromString] ignoreBlankLines:NO]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"NotAfterLocalTime" data:[mCertItem longExpiresString] ignoreBlankLines:NO]];
// signature
[self addLineWithLabelKey:@"SigAlgorithm" data:[mCertItem signatureAlgorithm] atOffset:&curOffset ignoreBlankLines:NO];
[self addScrollingTextFieldWithLabelKey:@"Signature" data:[mCertItem signatureValue] atOffset:&curOffset ignoreBlankLines:NO];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"SigAlgorithm" data:[mCertItem signatureAlgorithm] ignoreBlankLines:NO]];
[mDetailsItemsView addSubview:[self scrollingTextFieldWithLabelKey:@"Signature" data:[mCertItem signatureValue] ignoreBlankLines:NO]];
// public key info
curOffset += kGapUnderGroup;
[self addHeaderWithKey:@"PublicKeyInfo" atOffset:&curOffset];
[self addLineWithLabelKey:@"PublicKeyAlgorithm" data:[mCertItem publicKeyAlgorithm] atOffset:&curOffset ignoreBlankLines:NO];
//[self addLineWithLabelKey:@"PublicKeySize" data:[mCertItem publicKeySizeBits] atOffset:&curOffset ignoreBlankLines:NO];
[self addScrollingTextFieldWithLabelKey:@"PublicKey" data:[mCertItem publicKey] atOffset:&curOffset ignoreBlankLines:NO];
[mDetailsItemsView addSubview:[self headerWithKey:@"PublicKeyInfo"]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"PublicKeyAlgorithm" data:[mCertItem publicKeyAlgorithm] ignoreBlankLines:NO]];
//[self lineWithLabelKey:@"PublicKeySize" data:[mCertItem publicKeySizeBits] ignoreBlankLines:NO];
[mDetailsItemsView addSubview:[self scrollingTextFieldWithLabelKey:@"PublicKey" data:[mCertItem publicKey] ignoreBlankLines:NO]];
// usages
NSArray* certUsages = [mCertItem validUsages];
if ([certUsages count])
{
curOffset += kGapUnderGroup;
[self addHeaderWithKey:@"UsagesTitle" atOffset:&curOffset];
[mDetailsItemsView addSubview:[self headerWithKey:@"UsagesTitle"]];
for (unsigned int i = 0; i < [certUsages count]; i ++)
{
NSString* labelKey = (i == 0) ? @"Usages" : @"";
[self addLineWithLabelKey:labelKey data:[certUsages objectAtIndex:i] atOffset:&curOffset ignoreBlankLines:NO];
[mDetailsItemsView addSubview:[self lineWithLabelKey:labelKey data:[certUsages objectAtIndex:i] ignoreBlankLines:NO]];
}
}
// fingerprints
curOffset += kGapUnderGroup;
[self addHeaderWithKey:@"Fingerprints" atOffset:&curOffset];
[mDetailsItemsView addSubview:[self headerWithKey:@"Fingerprints"]];
[self addLineWithLabelKey:@"SHA1Fingerprint" data:[mCertItem sha1Fingerprint] atOffset:&curOffset ignoreBlankLines:NO];
[self addLineWithLabelKey:@"MD5Fingerprint" data:[mCertItem md5Fingerprint] atOffset:&curOffset ignoreBlankLines:NO];
curOffset += kGapUnderGroup;
return curOffset;
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"SHA1Fingerprint" data:[mCertItem sha1Fingerprint] ignoreBlankLines:NO]];
[mDetailsItemsView addSubview:[self lineWithLabelKey:@"MD5Fingerprint" data:[mCertItem md5Fingerprint] ignoreBlankLines:NO]];
}
- (float)rebuildTrustSettings:(float)inOffset
- (void)rebuildTrustSettings
{
float curOffset = inOffset;
[self addGroupingWithKey:@"CertTrustGroupHeader" expanded:mTrustExpanded action:@selector(toggleTrustSettings:) atOffset:&curOffset];
curOffset += kGapUnderHeader;
mTrustItemsView = [self groupingWithKey:@"CertTrustGroupHeader" expanded:mTrustExpanded action:@selector(toggleTrustSettings:)];
[mContentView addSubview:mTrustItemsView];
if (!mTrustExpanded)
return curOffset;
return;
// XXX do we need a more comprehensive check than this?
BOOL enableCheckboxes = YES; // [mCertItem isValid] || [mCertItem isUntrustedRootCACert];
// XXX only show relevant checkboxes? (see nsNSSCertificateDB::SetCertTrust)
// XXX only show checkboxes for allowed usages?
[self addLineWithLabelKey:@"TrustSettingsLabel" data:@"" atOffset:&curOffset ignoreBlankLines:NO];
mTrustForWebSitesCheckbox = [self addCheckboxLineWithLabelKey:@""
buttonLabelKey:@"TrustWebSitesCheckboxLabel"
action:@selector(trustCheckboxClicked:)
atOffset:&curOffset];
[mTrustItemsView addSubview:[self wholeLineLabelWithKey:@"TrustSettingsLabel"]];
[mTrustItemsView addSubview:[self checkboxLineWithLabelKey:@""
buttonLabelKey:@"TrustWebSitesCheckboxLabel"
action:@selector(trustCheckboxClicked:)
button:&mTrustForWebSitesCheckbox]];
[mTrustForWebSitesCheckbox setState:mTrustedForWebSites];
[mTrustForWebSitesCheckbox setEnabled:enableCheckboxes];
mTrustForEmailCheckbox = [self addCheckboxLineWithLabelKey:@""
[mTrustItemsView addSubview:[self checkboxLineWithLabelKey:@""
buttonLabelKey:@"TrustEmailUsersCheckboxLabel"
action:@selector(trustCheckboxClicked:)
atOffset:&curOffset];
button:&mTrustForEmailCheckbox]];
[mTrustForEmailCheckbox setState:mTrustedForEmail];
[mTrustForEmailCheckbox setEnabled:enableCheckboxes];
mTrustForObjSigningCheckbox = [self addCheckboxLineWithLabelKey:@""
buttonLabelKey:@"TrustObjectSignersCheckboxLabel"
action:@selector(trustCheckboxClicked:)
atOffset:&curOffset];
[mTrustItemsView addSubview:[self checkboxLineWithLabelKey:@""
buttonLabelKey:@"TrustObjectSignersCheckboxLabel"
action:@selector(trustCheckboxClicked:)
button:&mTrustForObjSigningCheckbox]];
[mTrustForObjSigningCheckbox setState:mTrustedForObjectSigning];
[mTrustForObjSigningCheckbox setEnabled:enableCheckboxes];
curOffset += kGapUnderGroup;
return curOffset;
}
- (void)refreshView
@ -620,58 +703,63 @@ const float kGapUnderLine = 5.0f;
mTrustForEmailCheckbox = nil;
mTrustForObjSigningCheckbox = nil;
float headerHeight = [self rebuildCertHeader];
NSRect contentFrame = [self bounds];
NSRect headerRect, contentsRect;
NSDivideRect(contentFrame, &headerRect, &contentsRect, headerHeight, NSMinYEdge);
mContentView = [[CertificateContentsView alloc] initWithFrame:contentsRect];
mContentView = [[CHStackView alloc] initWithFrame:[self bounds]];
[mContentView setAutoresizingMask:NSViewWidthSizable | NSViewMaxYMargin];
[self setIntrinsicPadding:0.0f forEdge:NSMinXEdge];
[self setIntrinsicPadding:0.0f forEdge:NSMinYEdge];
[self setIntrinsicPadding:0.0f forEdge:NSMaxXEdge];
[self setIntrinsicPadding:0.0f forEdge:NSMaxYEdge];
[self addSubview:mContentView];
[self rebuildCertHeader];
[self rebuildCertContent];
}
- (float)rebuildCertHeader
- (void)rebuildCertHeader
{
// We do all this laborious manual view construction to avoid having to load a nib file each
// time. This way, we can just have a single custom view in the nib, and do everything in code.
// cert image
NSRect certImageFrame = NSMakeRect(kGroupHeaderLeftOffset, kGroupHeaderLeftOffset, kCertImageViewSize, kCertImageViewSize);
NSImageView* certImageView = [[[NSImageView alloc] initWithFrame:certImageFrame] autorelease];
[certImageView setImage:[NSImage imageNamed:@"certificate"]];
[self addSubview:certImageView];
// description
// container for the header
float headerFieldsLeftEdge = kGroupHeaderLeftOffset + kCertImageViewSize + kGroupHeaderLeftOffset;
float headerFieldYOffset = kGroupHeaderLeftOffset;
float headerFieldWith = NSWidth([self frame]) - headerFieldYOffset - kCertHeaderFieldRightGap;
NSView* headerContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderGroup];
// cert image
NSRect certImageFrame = NSMakeRect(0.0f, 0.0f, kCertImageViewSize, kCertImageViewSize);
NSImageView* certImageView = [[[NSImageView alloc] initWithFrame:[headerContainer subviewRectFromTopRelativeRect:certImageFrame]] autorelease];
[certImageView setImage:[NSImage imageNamed:@"certificate"]];
[certImageView setAutoresizingMask:NSViewMinYMargin];
[headerContainer addSubview:certImageView];
// description
NSRect decriptionRect = NSMakeRect(headerFieldsLeftEdge, headerFieldYOffset, headerFieldWith, 100.0f);
NSTextField* descField = [self textFieldWithInitialFrame:decriptionRect stringValue:[mCertItem displayName] small:NO bold:NO];
[self addSubview:descField];
NSTextField* descField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:decriptionRect] stringValue:[mCertItem displayName] autoSizing:NO small:NO bold:NO];
[headerContainer addSubview:descField];
headerFieldYOffset += NSHeight([descField frame]) + kCertHeaderFieldVerticalGap;
// issuer info
NSRect issuerRect = NSMakeRect(headerFieldsLeftEdge, headerFieldYOffset, headerFieldWith, 100.0f);
NSString* formatString = NSLocalizedStringFromTable(@"IssuedByHeaderFormat", @"CertificateDialogs", @"");
NSString* issuerString = [NSString stringWithFormat:formatString, [mCertItem issuerCommonName]];
NSTextField* issuerField = [self textFieldWithInitialFrame:issuerRect stringValue:issuerString small:YES bold:NO];
[self addSubview:issuerField];
NSTextField* issuerField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:issuerRect] stringValue:issuerString autoSizing:NO small:YES bold:NO];
[headerContainer addSubview:issuerField];
headerFieldYOffset += NSHeight([issuerField frame]) + kCertHeaderFieldVerticalGap;
// expiry info
NSRect expiryRect = NSMakeRect(headerFieldsLeftEdge, headerFieldYOffset, headerFieldWith, 100.0f);
formatString = NSLocalizedStringFromTable(@"ExpiresHeaderFormat", @"CertificateDialogs", @"");
NSString* expiryString = [NSString stringWithFormat:formatString, [mCertItem longExpiresString]];
NSTextField* expiryField = [self textFieldWithInitialFrame:expiryRect stringValue:expiryString small:YES bold:NO];
[self addSubview:expiryField];
NSTextField* expiryField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:expiryRect] stringValue:expiryString autoSizing:NO small:YES bold:NO];
[headerContainer addSubview:expiryField];
headerFieldYOffset += NSHeight([expiryField frame]) + kCertHeaderFieldVerticalGap;
NSRect statusImageRect = NSMakeRect(headerFieldsLeftEdge, headerFieldYOffset, kStatusImageSize, kStatusImageSize);
NSImageView* statusImageView = [[[NSImageView alloc] initWithFrame:statusImageRect] autorelease];
NSImageView* statusImageView = [[[NSImageView alloc] initWithFrame:[headerContainer subviewRectFromTopRelativeRect:statusImageRect]] autorelease];
NSString* imageName = @"";
if ([mCertItem isUntrustedRootCACert])
@ -682,44 +770,34 @@ const float kGapUnderLine = 5.0f;
imageName = @"mini_cert_invalid";
[statusImageView setImage:[NSImage imageNamed:imageName]];
[self addSubview:statusImageView];
[statusImageView setAutoresizingMask:NSViewMinYMargin];
[headerContainer addSubview:statusImageView];
// status info
float statusLeftEdge = headerFieldsLeftEdge + kStatusImageSize + kGroupHeaderLeftOffset;
float statusFieldWith = NSWidth([self frame]) - statusLeftEdge - kCertHeaderFieldRightGap;
NSRect statusRect = NSMakeRect(statusLeftEdge, headerFieldYOffset, statusFieldWith, 100.0f);
NSTextField* statusField = [self textFieldWithInitialFrame:statusRect stringValue:@"" small:YES bold:NO];
NSTextField* statusField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:statusRect] stringValue:@"" autoSizing:NO small:YES bold:NO];
[statusField setAttributedStringValue:[mCertItem attributedLongValidityString]];
[statusField sizeToFit];
[self addSubview:statusField];
[headerContainer addSubview:statusField];
headerFieldYOffset += NSHeight([statusField frame]) + kCertHeaderFieldVerticalGap;
return headerFieldYOffset;
[mContentView addSubview:headerContainer];
}
- (void)rebuildCertContent
{
// blow away the subviews of the content view
[mContentView removeAllSubviews];
[mTrustItemsView removeFromSuperviewWithoutNeedingDisplay];
mTrustItemsView = nil;
[mDetailsItemsView removeFromSuperviewWithoutNeedingDisplay];
mDetailsItemsView = nil;
float curHeight = 0.0f;
if ([self showTrustSettings])
curHeight = [self rebuildTrustSettings:curHeight];
[self rebuildTrustSettings];
curHeight = [self rebuildDetails:curHeight];
// make sure the details view is big enough to contain all its subviews
NSSize curSize = [mContentView frame].size;
curSize.height = curHeight;
[mContentView setFrameSize:curSize];
// and then resize us too
NSRect contentViewFrame = [mContentView frame];
float myHeight = NSHeight(contentViewFrame) + NSMinY(contentViewFrame);
curSize = [self frame].size;
curSize.height = myHeight;
[self setFrameSize:curSize];
[self rebuildDetails];
}
- (void)certificateChanged:(NSNotification*)inNotification