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; isa = PBXCopyFilesBuildPhase;
runOnlyForDeploymentPostprocessing = 0; 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 = { 0F84BF1208862E3E00E23BC4 = {
fileEncoding = 30; fileEncoding = 30;
isa = PBXFileReference; isa = PBXFileReference;
@ -1429,6 +1471,57 @@
settings = { 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 = { 0FA8EF970423B1A500A80166 = {
isa = PBXFileReference; isa = PBXFileReference;
lastKnownFileType = "compiled.mach-o.dylib"; lastKnownFileType = "compiled.mach-o.dylib";
@ -2232,6 +2325,48 @@
settings = { 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 = { 0FD8181E08CB8E8900D8F88C = {
children = ( children = (
0FD8181F08CB8E8900D8F88C, 0FD8181F08CB8E8900D8F88C,
@ -3657,6 +3792,8 @@
0F08FB1508D37DA90022DD45, 0F08FB1508D37DA90022DD45,
0F0F5E3D08FC660300B4EBCD, 0F0F5E3D08FC660300B4EBCD,
0F07686B0927B0AA00E1BD6F, 0F07686B0927B0AA00E1BD6F,
0F7EAA9B09326B860082C3EA,
0FD75059093ABEBA00B6A3A4,
); );
isa = PBXHeadersBuildPhase; isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -4284,6 +4421,7 @@
0FBB8CCA08D260D800D58D8D, 0FBB8CCA08D260D800D58D8D,
0F01117408F2FE7C00423C02, 0F01117408F2FE7C00423C02,
0FEA7E650926BFC600B06154, 0FEA7E650926BFC600B06154,
0F8FC52F092ED71C0042429E,
); );
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -4809,6 +4947,9 @@
0F07686A0927B09E00E1BD6F, 0F07686A0927B09E00E1BD6F,
0F07688F0927B0B300E1BD6F, 0F07688F0927B0B300E1BD6F,
0F0768900927B0B600E1BD6F, 0F0768900927B0B600E1BD6F,
0F8FC584092ED8C70042429E,
0F7EAA9809326B770082C3EA,
0FD7505C093ABEC600B6A3A4,
); );
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -7570,6 +7711,8 @@
0F08FB1608D37DA90022DD45, 0F08FB1608D37DA90022DD45,
0F0F5E3E08FC660300B4EBCD, 0F0F5E3E08FC660300B4EBCD,
0FEA7DDF0926BBEA00B06154, 0FEA7DDF0926BBEA00B06154,
0F7EAA9A09326B860082C3EA,
0FD75058093ABEBA00B6A3A4,
); );
isa = PBXHeadersBuildPhase; isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -8203,6 +8346,7 @@
0FBB8CCF08D260D800D58D8D, 0FBB8CCF08D260D800D58D8D,
0F01117508F2FE7C00423C02, 0F01117508F2FE7C00423C02,
0FEA7E660926BFC600B06154, 0FEA7E660926BFC600B06154,
0F8FC52E092ED71C0042429E,
); );
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -8729,6 +8873,9 @@
0F0F5E3B08FC65FB00B4EBCD, 0F0F5E3B08FC65FB00B4EBCD,
0FEA7DE20926BBF500B06154, 0FEA7DE20926BBF500B06154,
0FEA7DE50926BC0C00B06154, 0FEA7DE50926BC0C00B06154,
0F8FC583092ED8C70042429E,
0F7EAA9709326B770082C3EA,
0FD7505B093ABEC600B6A3A4,
); );
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -14198,6 +14345,7 @@
F5DE10E90209DC0601A967DF, F5DE10E90209DC0601A967DF,
F528E21A020FD9620168DE43, F528E21A020FD9620168DE43,
F566BD1302EFA9AD01A967F3, F566BD1302EFA9AD01A967F3,
0F8FC582092ED8C70042429E,
); );
isa = PBXGroup; isa = PBXGroup;
name = Dialogs; name = Dialogs;
@ -16036,6 +16184,7 @@
children = ( children = (
F507A84103116E1D01026D5D, F507A84103116E1D01026D5D,
F507A84403116E5501026D5D, F507A84403116E5501026D5D,
0F8FC52C092ED71C0042429E,
0FBC0EC90798F92600E8E0E2, 0FBC0EC90798F92600E8E0E2,
0FACBFEC07DC020D00DEE23A, 0FACBFEC07DC020D00DEE23A,
F507A84A03116E6E01026D5D, F507A84A03116E6E01026D5D,
@ -16448,6 +16597,7 @@
F5B950BA030C833301A96654 = { F5B950BA030C833301A96654 = {
children = ( children = (
3489ADC90753B717005ADF6C, 3489ADC90753B717005ADF6C,
0F7EAA9909326B860082C3EA,
F541495E02711B0001A80166, F541495E02711B0001A80166,
0F0F5E3C08FC660300B4EBCD, 0F0F5E3C08FC660300B4EBCD,
F583E3C203B8228F01A80166, F583E3C203B8228F01A80166,
@ -16475,6 +16625,7 @@
3FF08F0606E7CF9C001C9B19, 3FF08F0606E7CF9C001C9B19,
3FF08F0706E7CF9C001C9B19, 3FF08F0706E7CF9C001C9B19,
3FF08F0806E7CF9C001C9B19, 3FF08F0806E7CF9C001C9B19,
0FD75057093ABEBA00B6A3A4,
); );
isa = PBXGroup; isa = PBXGroup;
name = Headers; name = Headers;
@ -16484,6 +16635,7 @@
F5B950BB030C833301A96654 = { F5B950BB030C833301A96654 = {
children = ( children = (
3489ADCA0753B717005ADF6C, 3489ADCA0753B717005ADF6C,
0F7EAA9609326B770082C3EA,
F541495F02711B0001A80166, F541495F02711B0001A80166,
0F0F5E3908FC65FB00B4EBCD, 0F0F5E3908FC65FB00B4EBCD,
F583E3BF03B8228701A80166, F583E3BF03B8228701A80166,
@ -16512,6 +16664,7 @@
3FF08EFD06E7CF86001C9B19, 3FF08EFD06E7CF86001C9B19,
3FF08EFE06E7CF86001C9B19, 3FF08EFE06E7CF86001C9B19,
3FF08EFF06E7CF86001C9B19, 3FF08EFF06E7CF86001C9B19,
0FD7505A093ABEC600B6A3A4,
); );
isa = PBXGroup; isa = PBXGroup;
name = Source; name = Source;

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

@ -42,6 +42,10 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk include $(DEPTH)/config/autoconf.mk
DIRS = \
IBPalette \
$(NULL)
APP_NAME = Camino APP_NAME = Camino
ifdef MOZ_DEBUG 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*="/flash/promotions/"],
embed[type="application/x-shockwave-flash"][src*=".adtrix.com"], 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*=".netshelter.net"],
embed[type="application/x-shockwave-flash"][src*=".gms1.net"],
img[src*="googlesyndication.com"], img[src*="googlesyndication.com"],
img[src*="mediaplex.com"], img[src*="mediaplex.com"],
@ -111,6 +112,7 @@ img[src*="kermit.macnn.com"],
img[src*="media.adlegend.com"], img[src*="media.adlegend.com"],
img[src*=".adtrix.com"], img[src*=".adtrix.com"],
img[src*=".netshelter.net"], img[src*=".netshelter.net"],
img[src*=".gms1.net"],
iframe[src*="/ad."], iframe[src*="/ad."],
iframe[src*="/ads."], iframe[src*="/ads."],
@ -156,6 +158,7 @@ iframe[src*=".yieldmanager.com"],
iframe[src*=".mspaceads.com"], iframe[src*=".mspaceads.com"],
iframe[src*=".adtrix.com"], iframe[src*=".adtrix.com"],
iframe[src*=".netshelter.net"], iframe[src*=".netshelter.net"],
iframe[src*=".gms1.net"],
table#overtureLinksWrapper, table#overtureLinksWrapper,
table.adbritetable, table.adbritetable,

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

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

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

@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>IBDocumentLocation</key> <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> <key>IBEditorPositions</key>
<dict> <dict>
<key>1014</key> <key>1014</key>
@ -38,6 +38,6 @@
<integer>889</integer> <integer>889</integer>
</array> </array>
<key>IBSystem Version</key> <key>IBSystem Version</key>
<string>8C46</string> <string>8F46</string>
</dict> </dict>
</plist> </plist>

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

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

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

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

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

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

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

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

@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>IBDocumentLocation</key> <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> <key>IBEditorPositions</key>
<dict> <dict>
<key>29</key> <key>29</key>
@ -15,7 +15,11 @@
</dict> </dict>
<key>IBFramework Version</key> <key>IBFramework Version</key>
<string>437.0</string> <string>437.0</string>
<key>IBOpenObjects</key>
<array>
<integer>29</integer>
</array>
<key>IBSystem Version</key> <key>IBSystem Version</key>
<string>8C46</string> <string>8F46</string>
</dict> </dict>
</plist> </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 = ( IBClasses = (
{
CLASS = CHFlippedShrinkWrapView;
LANGUAGE = ObjC;
SUPERCLASS = CHShrinkWrapView;
},
{CLASS = CHShrinkWrapView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
{ {
CLASS = CHStackView; CLASS = CHStackView;
LANGUAGE = ObjC; LANGUAGE = ObjC;
OUTLETS = {mDataSource = id; }; OUTLETS = {mDataSource = id; };
SUPERCLASS = NSView; SUPERCLASS = CHShrinkWrapView;
}, },
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; }, {CLASS = NSObject; LANGUAGE = ObjC; },

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

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

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

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

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

@ -3,26 +3,21 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>IBDocumentLocation</key> <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> <key>IBEditorPositions</key>
<dict> <dict>
<key>5</key> <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> <key>71</key>
<string>339 462 346 92 0 0 1024 746 </string> <string>606 622 346 92 0 0 1600 1002 </string>
</dict> </dict>
<key>IBFramework Version</key> <key>IBFramework Version</key>
<string>439.0</string> <string>437.0</string>
<key>IBLockedObjects</key> <key>IBLockedObjects</key>
<array> <array>
<integer>5</integer> <integer>5</integer>
</array> </array>
<key>IBOpenObjects</key>
<array>
<integer>71</integer>
<integer>5</integer>
</array>
<key>IBSystem Version</key> <key>IBSystem Version</key>
<string>8C46</string> <string>8F46</string>
</dict> </dict>
</plist> </plist>

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

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

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

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

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

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

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

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

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

@ -66,6 +66,7 @@
#import "NetworkServices.h" #import "NetworkServices.h"
#import "MVPreferencesController.h" #import "MVPreferencesController.h"
#import "CertificatesWindowController.h" #import "CertificatesWindowController.h"
#import "PageInfoWindowController.h"
#import "FindDlgController.h" #import "FindDlgController.h"
#import "PreferenceManager.h" #import "PreferenceManager.h"
#import "SharedMenusObj.h" #import "SharedMenusObj.h"
@ -386,6 +387,7 @@ const int kReuseWindowOnAE = 2;
{ {
[self delayedAdjustBookmarksMenuItemsEnabling]; [self delayedAdjustBookmarksMenuItemsEnabling];
[self delayedFixCloseMenuItemKeyEquivalents]; [self delayedFixCloseMenuItemKeyEquivalents];
[self delayedUpdatePageInfo];
} }
- (NSMenu *)applicationDockMenu:(NSApplication *)sender - (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 -(IBAction)closeTab:(id)aSender
{ {
BrowserWindowController* browserController = [self getMainWindowBrowserController]; 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]; [browserController closeCurrentTab:aSender];
} }
// XXX move to BWC
-(IBAction) previousTab:(id)aSender -(IBAction) previousTab:(id)aSender
{ {
BrowserWindowController* browserController = [self getMainWindowBrowserController]; 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]; [browserController previousTab:aSender];
} }
// XXX move to BWC
-(IBAction) nextTab:(id)aSender -(IBAction) nextTab:(id)aSender
{ {
BrowserWindowController* browserController = [self getMainWindowBrowserController]; 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]; [mFindDialog showWindow:self];
} }
// XXX move to BWC
-(IBAction) getInfo:(id)aSender
{
BrowserWindowController* browserController = [self getMainWindowBrowserController];
if (browserController)
[browserController getInfo: aSender];
}
-(IBAction) goBack:(id)aSender -(IBAction) goBack:(id)aSender
{ {
BrowserWindowController* browserController = [self getMainWindowBrowserController]; 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]; [browserController back: aSender];
} }
// XXX move to BWC
-(IBAction) goForward:(id)aSender -(IBAction) goForward:(id)aSender
{ {
BrowserWindowController* browserController = [self getMainWindowBrowserController]; 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]; [browserController forward: aSender];
} }
// XXX move to BWC
-(IBAction) doReload:(id)aSender -(IBAction) doReload:(id)aSender
{ {
BrowserWindowController* browserController = [self getMainWindowBrowserController]; 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]; [browserController reload: aSender];
} }
// XXX move to BWC
-(IBAction) reloadWithCharset:(id)aSender -(IBAction) reloadWithCharset:(id)aSender
{ {
// Figure out which charset to tell gecko to load based on the sender's tag. There // 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]; [self doReload:nil];
} }
// XXX move to BWC
-(IBAction) doStop:(id)aSender -(IBAction) doStop:(id)aSender
{ {
BrowserWindowController* browserController = [self getMainWindowBrowserController]; BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -1327,6 +1329,22 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
mFileMenuUpdatePending = NO; 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 - (void)adjustTextEncodingMenu
{ {
BrowserWindowController* browserController = [self getMainWindowBrowserController]; BrowserWindowController* browserController = [self getMainWindowBrowserController];
@ -1402,9 +1420,6 @@ Otherwise, we return the URL we originally got. Right now this supports .url and
return NO; 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 // only enable newTab if there is a browser window frontmost, or if there is no window
// (i.e. disable it for non-browser windows). // (i.e. disable it for non-browser windows).
if (action == @selector(newTab:)) if (action == @selector(newTab:))

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

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

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

@ -48,6 +48,7 @@
#import "BookmarkManager.h" #import "BookmarkManager.h"
#import "AddBookmarkDialogController.h" #import "AddBookmarkDialogController.h"
#import "ProgressDlgController.h" #import "ProgressDlgController.h"
#import "PageInfoWindowController.h"
#import "BrowserContentViews.h" #import "BrowserContentViews.h"
#import "BrowserWrapper.h" #import "BrowserWrapper.h"
@ -436,6 +437,7 @@ enum BWCOpenDest {
- (void)bookmarkableTitle:(NSString **)outTitle URL:(NSString**)outURLString forWrapper:(BrowserWrapper*)inWrapper; - (void)bookmarkableTitle:(NSString **)outTitle URL:(NSString**)outURLString forWrapper:(BrowserWrapper*)inWrapper;
- (void)clearContextMenuTarget; - (void)clearContextMenuTarget;
- (void)updateLock:(unsigned int)securityState;
// create back/forward session history menus on toolbar button // create back/forward session history menus on toolbar button
- (IBAction)backMenu:(id)inSender; - (IBAction)backMenu:(id)inSender;
@ -466,7 +468,6 @@ enum BWCOpenDest {
mProgressSuperview = nil; mProgressSuperview = nil;
mBookmarkToolbarItem = nil; mBookmarkToolbarItem = nil;
mSidebarToolbarItem = nil; mSidebarToolbarItem = nil;
mSavedTitle = nil;
// register for services // register for services
NSArray* sendTypes = [NSArray arrayWithObjects:NSStringPboardType, nil]; NSArray* sendTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
@ -669,16 +670,22 @@ enum BWCOpenDest {
// it only works if it's here. // it only works if it's here.
[[[self window] undoManager] removeAllActions]; [[[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| // 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 // 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 // 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 // superclass dealloc takes care of our child NSView's, which include the
// BrowserWrappers and their child CHBrowserViews. // BrowserWrappers and their child CHBrowserViews.
//if (mSidebarBrowserView)
// [mSidebarBrowserView windowClosed];
[mSavedTitle release];
[mProgress release]; [mProgress release];
[mPopupBlocked release]; [mPopupBlocked release];
[mSearchBar release]; [mSearchBar release];
@ -1376,7 +1383,7 @@ enum BWCOpenDest {
if (action == @selector(fillForm:)) if (action == @selector(fillForm:))
return ![self bookmarkManagerIsVisible]; return ![self bookmarkManagerIsVisible];
return YES; return YES;
} }
@ -1405,6 +1412,9 @@ enum BWCOpenDest {
else else
[[self window] makeFirstResponder:[mBrowserView getBrowserView]]; [[self window] makeFirstResponder:[mBrowserView getBrowserView]];
} }
if ([[self window] isMainWindow])
[[PageInfoWindowController visiblePageInfoWindowController] updateFromBrowserView:[self activeBrowserView]];
} }
- (void)setLoadingActive:(BOOL)active - (void)setLoadingActive:(BOOL)active
@ -1461,10 +1471,8 @@ enum BWCOpenDest {
[mURLBar setURI:url]; [mURLBar setURI:url];
[mLocationSheetURLField setStringValue:url]; [mLocationSheetURLField setStringValue:url];
// don't call [window display] here, no matter how much you might want if ([[self window] isMainWindow])
// to, because it forces a redraw of every view in the window and with a lot [[PageInfoWindowController visiblePageInfoWindowController] updateFromBrowserView:[self activeBrowserView]];
// of tabs, it's dog slow.
// [[self window] display];
} }
- (void)updateSiteIcons:(NSImage*)icon ignoreTyping:(BOOL)ignoreTyping - (void)updateSiteIcons:(NSImage*)icon ignoreTyping:(BOOL)ignoreTyping
@ -1501,6 +1509,8 @@ enum BWCOpenDest {
{ {
// update bookmarks menu // update bookmarks menu
[[NSApp delegate] delayedAdjustBookmarksMenuItemsEnabling]; [[NSApp delegate] delayedAdjustBookmarksMenuItemsEnabling];
// should we change page info for bookmarks?
} }
- (void)updateFromFrontmostTab - (void)updateFromFrontmostTab
@ -2954,16 +2964,12 @@ enum BWCOpenDest {
[[mBrowserView getBrowserView] smallerTextSize]; [[mBrowserView getBrowserView] smallerTextSize];
} }
- (void)getInfo:(id)sender - (IBAction)getInfo:(id)sender
{ {
BookmarkViewController* bookmarksController = [self bookmarkViewControllerForCurrentTab]; if ([self bookmarkManagerIsVisible])
[bookmarksController ensureBookmarks]; [self showBookmarksInfo:sender];
[bookmarksController showBookmarkInfo:sender]; else
} [self showPageInfo:sender];
- (BOOL)canGetInfo
{
return [self singleBookmarkIsSelected];
} }
- (BOOL)shouldShowBookmarkToolbar - (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 - (BookmarkToolbar*) bookmarkToolbar
{ {
return mPersonalToolbar; return mPersonalToolbar;
@ -3443,20 +3464,6 @@ enum BWCOpenDest {
return sBrokenIcon; 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 + (NSDictionary *)searchURLDictionary
{ {
static NSDictionary *searchURLDictionary = nil; static NSDictionary *searchURLDictionary = nil;
@ -3536,6 +3543,11 @@ enum BWCOpenDest {
return [self bookmarkViewControllerForCurrentTab]; return [self bookmarkViewControllerForCurrentTab];
} }
- (CHBrowserView*)activeBrowserView
{
return [mBrowserView getBrowserView];
}
- (id)windowWillReturnFieldEditor:(NSWindow *)aWindow toObject:(id)anObject - (id)windowWillReturnFieldEditor:(NSWindow *)aWindow toObject:(id)anObject
{ {
if ([anObject isEqual:mURLBar]) { if ([anObject isEqual:mURLBar]) {

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

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

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

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

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

@ -40,6 +40,9 @@
#import "ProgressView.h" #import "ProgressView.h"
NSString* const kDownloadInstanceSelectedNotificationName = @"DownloadInstanceSelected";
NSString* const kDownloadInstanceOpenedNotificationName = @"DownloadInstanceOpened";
@interface ProgressView(Private) @interface ProgressView(Private)
-(BOOL)isSelected; -(BOOL)isSelected;
@ -87,14 +90,14 @@
} }
} }
[self setSelected:shouldSelect]; [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, // 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 // 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 // processing the modifiers allows someone to shift-dblClick and open all selected items
// in the list in one action. // in the list in one action.
if ([theEvent type] == NSLeftMouseDown && [theEvent clickCount] == 2) if ([theEvent type] == NSLeftMouseDown && [theEvent clickCount] == 2)
[[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadInstanceOpened" object:self]; [[NSNotificationCenter defaultCenter] postNotificationName:kDownloadInstanceOpenedNotificationName object:self];
} }
-(int)lastModifier -(int)lastModifier
@ -130,7 +133,7 @@
mLastModifier = kNoKey; // control is only special because it means its contextual menu time mLastModifier = kNoKey; // control is only special because it means its contextual menu time
[self setSelected:YES]; [self setSelected:YES];
[self display]; // change selection immediately [self display]; // change selection immediately
[[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadInstanceSelected" object:self]; [[NSNotificationCenter defaultCenter] postNotificationName:kDownloadInstanceSelectedNotificationName object:self];
} }
return [[self getController] contextualMenu]; return [[self getController] contextualMenu];
} }

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

@ -50,14 +50,12 @@ class nsIDOMWindow;
class nsIWebBrowser; class nsIWebBrowser;
class nsIDOMNode; class nsIDOMNode;
class nsIDOMEvent; class nsIDOMEvent;
class nsIWebBrowserFind;
class nsIEventSink; class nsIEventSink;
class nsIDragHelperService; class nsIDragHelperService;
class nsIPrintSettings; class nsIPrintSettings;
class nsIURI; class nsIURI;
class nsISupports; class nsISupports;
// Protocol implemented by anyone interested in progress // Protocol implemented by anyone interested in progress
// related to a BrowserView. A listener should explicitly // related to a BrowserView. A listener should explicitly
// register itself with the view using the addListener // register itself with the view using the addListener
@ -176,8 +174,14 @@ enum {
- (void)goForward; - (void)goForward;
- (void)gotoIndex:(int)index; - (void)gotoIndex:(int)index;
- (void)stop:(unsigned int)flags; - (void)stop:(unsigned int)flags;
- (NSString*)getCurrentURI; - (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 // nsIWebBrowserSetup methods
- (void)setProperty:(unsigned int)property toValue:(unsigned int)value; - (void)setProperty:(unsigned int)property toValue:(unsigned int)value;

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

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved. * the Initial Developer. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
* Simon Fraser <smfr@smfr.org>
* *
* Alternatively, the contents of this file may be used under the terms of * 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 * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -37,6 +38,7 @@
#import "NSString+Utils.h" #import "NSString+Utils.h"
#import "NSPasteboard+Utils.h" #import "NSPasteboard+Utils.h"
#import "NSDate+Utils.h"
#import "CHClickListener.h" #import "CHClickListener.h"
@ -75,6 +77,7 @@
// Saving of links/images/docs // Saving of links/images/docs
#include "nsIWebBrowserFocus.h" #include "nsIWebBrowserFocus.h"
#include "nsIDOMNSDocument.h" #include "nsIDOMNSDocument.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMLocation.h" #include "nsIDOMLocation.h"
#include "nsIWebBrowserPersist.h" #include "nsIWebBrowserPersist.h"
#include "nsIProperties.h" #include "nsIProperties.h"
@ -131,9 +134,10 @@ const long NSFindPanelActionSetFindString = 7;
- (nsIContentViewer*)getContentViewer; // addrefs return value - (nsIContentViewer*)getContentViewer; // addrefs return value
- (float)getTextZoom; - (float)getTextZoom;
- (void)incrementTextZoom:(float)increment min:(float)min max:(float)max; - (void)incrementTextZoom:(float)increment min:(float)min max:(float)max;
- (nsIDocShell*)getDocShell; - (nsIDocShell*)getDocShell; // does NOT addref
- (NSString*)getSelection; - (NSString*)getSelection;
- (already_AddRefed<nsIDOMWindow>)focussedDOMWindow;
- (NSString*)locationFromDOMWindow:(nsIDOMWindow*)inDOMWindow;
- (void)ensurePrintSettings; - (void)ensurePrintSettings;
- (void)savePrintSettings; - (void)savePrintSettings;
@ -345,6 +349,7 @@ const long NSFindPanelActionSetFindString = 7;
_listener->SetContainer(container); _listener->SetContainer(container);
} }
// addrefs return value
- (nsIDOMWindow*)getContentWindow - (nsIDOMWindow*)getContentWindow
{ {
nsIDOMWindow* window = nsnull; nsIDOMWindow* window = nsnull;
@ -489,6 +494,7 @@ const long NSFindPanelActionSetFindString = 7;
browserSetup->SetProperty(property, value); browserSetup->SetProperty(property, value);
} }
// should we be using the window.location URL instead? see nsIDOMLocation.h
- (NSString*)getCurrentURI - (NSString*)getCurrentURI
{ {
nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser); nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
@ -505,6 +511,76 @@ const long NSFindPanelActionSetFindString = 7;
return [NSString stringWithUTF8String:spec.get()]; 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 - (CHBrowserListener*)getCocoaBrowserListener
{ {
return _listener; return _listener;
@ -766,32 +842,46 @@ const long NSFindPanelActionSetFindString = 7;
filterView: aFilterView]; 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 -(NSString*)getFocusedURLString
{ {
if (!_webBrowser) if (!_webBrowser)
return @""; 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; nsCOMPtr<nsIDOMWindow> focussedWindow = [self focussedDOMWindow];
domWindow->GetDocument(getter_AddRefs(domDocument)); NSString* locationString = [self locationFromDOMWindow:focussedWindow];
if (!domDocument) return locationString ? locationString : @"";
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];
} }
- (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView - (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView
@ -801,13 +891,9 @@ const long NSFindPanelActionSetFindString = 7;
nsCOMPtr<nsIDOMWindow> domWindow; nsCOMPtr<nsIDOMWindow> domWindow;
if (focusedFrame) if (focusedFrame)
{ domWindow = [self focussedDOMWindow];
nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
wbf->GetFocusedWindow(getter_AddRefs(domWindow));
}
else else
_webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (!domWindow) if (!domWindow)
return; return;
@ -815,26 +901,19 @@ const long NSFindPanelActionSetFindString = 7;
domWindow->GetDocument(getter_AddRefs(domDocument)); domWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument) if (!domDocument)
return; return;
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
if (!nsDoc) NSString* windowLocation = [self locationFromDOMWindow:domWindow];
return;
nsCOMPtr<nsIDOMLocation> location;
nsDoc->GetLocation(getter_AddRefs(location));
if (!location)
return;
nsAutoString urlStr;
location->GetHref(urlStr);
nsCOMPtr<nsIURI> url; 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)) if (NS_FAILED(rv))
return; return;
[self saveInternal: url.get() [self saveInternal:url.get()
withDocument: domDocument withDocument:domDocument
suggestedFilename: @"" suggestedFilename:@""
bypassCache: NO bypassCache:NO
filterView: aFilterView]; filterView:aFilterView];
} }
-(void)doCommand:(const char*)commandName -(void)doCommand:(const char*)commandName
@ -1011,38 +1090,6 @@ const long NSFindPanelActionSetFindString = 7;
[[self getBrowserContainer] didDismissPrompt]; [[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 - (void)setActive: (BOOL)aIsActive
{ {
nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser)); nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
@ -1095,7 +1142,7 @@ const long NSFindPanelActionSetFindString = 7;
} }
} }
// does NOT addref return value
- (nsIDocShell*)getDocShell - (nsIDocShell*)getDocShell
{ {
if (!_webBrowser) 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): * Contributor(s):
* Calum Robinson <calumr@mac.com> * Calum Robinson <calumr@mac.com>
* Simon Fraser <smfr@smfr.org>
* *
* Alternatively, the contents of this file may be used under the terms of * 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 * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -38,24 +39,98 @@
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
// views contained in the stack should send this notification when they change size // 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 // 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; IBOutlet id mDataSource;
BOOL mShowsSeparators;
// BOOL mIsResizingSubviews;
} }
- (void)setDataSource:(id)aDataSource; - (void)setDataSource:(id)aDataSource;
- (void)reloadSubviews;
// default is NO
- (BOOL)showsSeparators;
- (void)setShowsSeparators:(BOOL)inShowSeparators;
@end @end
@protocol CHStackViewDataSource @protocol CHStackViewDataSource
- (int)subviewsForStackView:(CHStackView *)stackView; - (NSArray*)subviewsForStackView:(CHStackView *)stackView;
- (NSView *)viewForStackView:(CHStackView *)stackView atIndex:(int)index;
@end @end

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

@ -22,6 +22,7 @@
* Contributor(s): * Contributor(s):
* Calum Robinson <calumr@mac.com> * Calum Robinson <calumr@mac.com>
* Josh Aas <josha@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 * 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 * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -37,34 +38,292 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** 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 "NSView+Utils.h"
#import "CHStackView.h" #import "CHStackView.h"
NSString* StackViewReloadNotificationName = @"ReloadStackView"; @interface NSObject(PrivateAPI)
NSString* StackViewResizedNotificationName = @"StackViewResized"; + (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 @implementation CHStackView
-(id)initWithFrame:(NSRect)frameRect -(id)initWithFrame:(NSRect)frameRect
{ {
if ((self = [super initWithFrame:frameRect])) { if ((self = [super initWithFrame:frameRect]))
// Register for notifications when one of the subviews changes size {
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadNotification:) selector:@selector(reloadNotification:)
name:StackViewReloadNotificationName name:kStackViewReloadNotificationName
object:nil]; object:nil];
} }
return self; 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 -(void)dealloc
{ {
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
@ -74,66 +333,144 @@ NSString* StackViewResizedNotificationName = @"StackViewResized";
-(void)setDataSource:(id)aDataSource -(void)setDataSource:(id)aDataSource
{ {
mDataSource = aDataSource; // should this retain? mDataSource = aDataSource; // should this retain?
[self reloadSubviews]; [self adaptToSubviews];
} }
-(void)reloadNotification:(NSNotification*)notification -(void)reloadNotification:(NSNotification*)notification
{ {
[self reloadSubviews]; [self adaptToSubviews];
} }
-(void)reloadSubviews - (void)didAddSubview:(NSView *)subview
{ {
NSRect newFrame = [self frame]; [super didAddSubview:subview];
NSSize oldSize = [self bounds].size; // [subview setAutoresizingMask:([subview autoresizingMask] | NSViewMinYMargin)];
int i, subviewCount = [mDataSource subviewsForStackView:self]; }
NSPoint nextOrigin = NSZeroPoint;
- (void)drawRect:(NSRect)inRect
// maintain the width of the stack view, assuming that it's scaled by its superview. {
newFrame.size.height = 0.0; if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] &&
[NSObject editingInInterfaceBuilder])
[self removeAllSubviews]; {
[[NSColor orangeColor] set];
for (i = 0; i < subviewCount; i++) { NSFrameRect([self bounds]);
NSView *subview = [mDataSource viewForStackView:self atIndex:i]; }
NSRect subviewFrame = [subview frame]; }
NSBox *separator;
-(void)adaptToSubviews
unsigned int autoResizeMask = [subview autoresizingMask]; {
if (autoResizeMask & NSViewWidthSizable) if (mSelfResizing) return; // avoid re-entry
subviewFrame.size.width = newFrame.size.width;
if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] &&
newFrame.size.height += NSHeight(subviewFrame); [NSObject editingInInterfaceBuilder])
{
subviewFrame.origin = nextOrigin; return;
[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];
} }
// NSLog(@"%@ frame %@", self, NSStringFromRect([self frame]));
const float kSeparatorHeight = 1.0f;
NSRect newBounds = newFrame; NSSize mySize = [self frame].size;
newBounds.origin = NSZeroPoint; 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]; [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 object:self
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithSize:oldSize], @"oldsize", nil]]; userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithSize:oldSize], @"oldsize", nil]];
} }
- (BOOL)showsSeparators
{
return mShowsSeparators;
}
- (void)setShowsSeparators:(BOOL)inShowSeparators
{
mShowsSeparators = inShowSeparators;
}
-(BOOL)isFlipped -(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 @end

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

@ -67,4 +67,12 @@ BOOL CHCloseSizes(NSSize aSize, NSSize bSize, float slop);
- (void)removeAllSubviews; - (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 @end

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

@ -191,4 +191,33 @@ static void RedistributeSpace(int resizeMask, float newWidth, /* in out */ float
[subviewsArray release]; [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 @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 ***** */ * ***** END LICENSE BLOCK ***** */
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#import "CHStackView.h"
@class CertificateItem; @class CertificateItem;
// this is a view that builds its contents dynamically from the cert. // 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 mDetailsExpanded;
BOOL mTrustExpanded; BOOL mTrustExpanded;

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

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