From 17ed09b145eb11bc9989cbda3ece8dfed271d76f Mon Sep 17 00:00:00 2001 From: "smfr%smfr.org" Date: Fri, 2 Dec 2005 05:20:36 +0000 Subject: [PATCH] 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. git-svn-id: svn://10.0.0.236/trunk@185563 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/camino/Camino.xcode/project.pbxproj | 153 +++++ mozilla/camino/Makefile.in | 4 + .../resources/application/ad_blocking.css | 3 + .../BrowserWindow.nib/classes.nib | 2 + .../English.lproj/BrowserWindow.nib/info.nib | 4 +- .../BrowserWindow.nib/keyedobjects.nib | Bin 31288 -> 31303 bytes .../CertificatesWindow.nib/info.nib | 2 +- .../English.lproj/Localizable.strings | Bin 28384 -> 30452 bytes .../English.lproj/MainMenu.nib/classes.nib | 6 +- .../English.lproj/MainMenu.nib/info.nib | 8 +- .../MainMenu.nib/keyedobjects.nib | Bin 32438 -> 32371 bytes .../English.lproj/PageInfo.nib/classes.nib | 45 ++ .../English.lproj/PageInfo.nib/info.nib | 12 + .../PageInfo.nib/keyedobjects.nib | Bin 0 -> 12627 bytes .../ProgressDialog.nib/classes.nib | 8 +- .../English.lproj/ProgressDialog.nib/info.nib | 6 +- .../ProgressDialog.nib/keyedobjects.nib | Bin 3600 -> 3860 bytes .../English.lproj/ProgressView.nib/info.nib | 15 +- .../ProgressView.nib/keyedobjects.nib | Bin 5369 -> 5369 bytes .../ViewCertificateDialog.nib/info.nib | 2 +- .../keyedobjects.nib | Bin 4555 -> 4555 bytes .../camino/src/application/MainController.h | 3 +- .../camino/src/application/MainController.mm | 37 +- .../src/browser/BrowserWindowController.h | 17 +- .../src/browser/BrowserWindowController.mm | 78 +-- mozilla/camino/src/browser/BrowserWrapper.mm | 15 +- .../src/browser/PageInfoWindowController.h | 73 +++ .../src/browser/PageInfoWindowController.mm | 287 +++++++++ .../src/download/ProgressDlgController.mm | 31 +- mozilla/camino/src/download/ProgressView.h | 3 + mozilla/camino/src/download/ProgressView.mm | 9 +- mozilla/camino/src/embedding/CHBrowserView.h | 8 +- mozilla/camino/src/embedding/CHBrowserView.mm | 199 ++++--- .../src/extensions/AutoSizingTextField.h | 55 ++ .../src/extensions/AutoSizingTextField.m | 114 ++++ mozilla/camino/src/extensions/CHStackView.h | 87 ++- mozilla/camino/src/extensions/CHStackView.m | 445 ++++++++++++-- mozilla/camino/src/extensions/NSView+Utils.h | 8 + mozilla/camino/src/extensions/NSView+Utils.m | 29 + .../src/extensions/TruncatingTextFieldCell.h | 61 ++ .../src/extensions/TruncatingTextFieldCell.mm | 122 ++++ mozilla/camino/src/security/CertificateView.h | 9 +- .../camino/src/security/CertificateView.mm | 550 ++++++++++-------- 43 files changed, 2026 insertions(+), 484 deletions(-) create mode 100644 mozilla/camino/resources/localized/English.lproj/PageInfo.nib/classes.nib create mode 100644 mozilla/camino/resources/localized/English.lproj/PageInfo.nib/info.nib create mode 100644 mozilla/camino/resources/localized/English.lproj/PageInfo.nib/keyedobjects.nib create mode 100644 mozilla/camino/src/browser/PageInfoWindowController.h create mode 100644 mozilla/camino/src/browser/PageInfoWindowController.mm create mode 100644 mozilla/camino/src/extensions/AutoSizingTextField.h create mode 100644 mozilla/camino/src/extensions/AutoSizingTextField.m create mode 100644 mozilla/camino/src/extensions/TruncatingTextFieldCell.h create mode 100644 mozilla/camino/src/extensions/TruncatingTextFieldCell.mm diff --git a/mozilla/camino/Camino.xcode/project.pbxproj b/mozilla/camino/Camino.xcode/project.pbxproj index 3536670f303..644cdcbe93a 100644 --- a/mozilla/camino/Camino.xcode/project.pbxproj +++ b/mozilla/camino/Camino.xcode/project.pbxproj @@ -1387,6 +1387,48 @@ isa = PBXCopyFilesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; + 0F7EAA9609326B770082C3EA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = AutoSizingTextField.m; + path = src/extensions/AutoSizingTextField.m; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 0F7EAA9709326B770082C3EA = { + fileRef = 0F7EAA9609326B770082C3EA; + isa = PBXBuildFile; + settings = { + }; + }; + 0F7EAA9809326B770082C3EA = { + fileRef = 0F7EAA9609326B770082C3EA; + isa = PBXBuildFile; + settings = { + }; + }; + 0F7EAA9909326B860082C3EA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = AutoSizingTextField.h; + path = src/extensions/AutoSizingTextField.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 0F7EAA9A09326B860082C3EA = { + fileRef = 0F7EAA9909326B860082C3EA; + isa = PBXBuildFile; + settings = { + }; + }; + 0F7EAA9B09326B860082C3EA = { + fileRef = 0F7EAA9909326B860082C3EA; + isa = PBXBuildFile; + settings = { + }; + }; 0F84BF1208862E3E00E23BC4 = { fileEncoding = 30; isa = PBXFileReference; @@ -1429,6 +1471,57 @@ settings = { }; }; + 0F8FC52C092ED71C0042429E = { + children = ( + 0F8FC52D092ED71C0042429E, + ); + isa = PBXVariantGroup; + name = PageInfo.nib; + path = ""; + refType = 4; + sourceTree = ""; + }; + 0F8FC52D092ED71C0042429E = { + isa = PBXFileReference; + lastKnownFileType = wrapper.nib; + name = English; + path = resources/localized/English.lproj/PageInfo.nib; + refType = 4; + sourceTree = ""; + }; + 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 = ""; + }; + 0F8FC583092ED8C70042429E = { + fileRef = 0F8FC582092ED8C70042429E; + isa = PBXBuildFile; + settings = { + }; + }; + 0F8FC584092ED8C70042429E = { + fileRef = 0F8FC582092ED8C70042429E; + isa = PBXBuildFile; + settings = { + }; + }; 0FA8EF970423B1A500A80166 = { isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; @@ -2232,6 +2325,48 @@ settings = { }; }; + 0FD75057093ABEBA00B6A3A4 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = TruncatingTextFieldCell.h; + path = src/extensions/TruncatingTextFieldCell.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 0FD75058093ABEBA00B6A3A4 = { + fileRef = 0FD75057093ABEBA00B6A3A4; + isa = PBXBuildFile; + settings = { + }; + }; + 0FD75059093ABEBA00B6A3A4 = { + fileRef = 0FD75057093ABEBA00B6A3A4; + isa = PBXBuildFile; + settings = { + }; + }; + 0FD7505A093ABEC600B6A3A4 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.objcpp; + name = TruncatingTextFieldCell.mm; + path = src/extensions/TruncatingTextFieldCell.mm; + refType = 4; + sourceTree = ""; + }; + 0FD7505B093ABEC600B6A3A4 = { + fileRef = 0FD7505A093ABEC600B6A3A4; + isa = PBXBuildFile; + settings = { + }; + }; + 0FD7505C093ABEC600B6A3A4 = { + fileRef = 0FD7505A093ABEC600B6A3A4; + isa = PBXBuildFile; + settings = { + }; + }; 0FD8181E08CB8E8900D8F88C = { children = ( 0FD8181F08CB8E8900D8F88C, @@ -3657,6 +3792,8 @@ 0F08FB1508D37DA90022DD45, 0F0F5E3D08FC660300B4EBCD, 0F07686B0927B0AA00E1BD6F, + 0F7EAA9B09326B860082C3EA, + 0FD75059093ABEBA00B6A3A4, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -4284,6 +4421,7 @@ 0FBB8CCA08D260D800D58D8D, 0F01117408F2FE7C00423C02, 0FEA7E650926BFC600B06154, + 0F8FC52F092ED71C0042429E, ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -4809,6 +4947,9 @@ 0F07686A0927B09E00E1BD6F, 0F07688F0927B0B300E1BD6F, 0F0768900927B0B600E1BD6F, + 0F8FC584092ED8C70042429E, + 0F7EAA9809326B770082C3EA, + 0FD7505C093ABEC600B6A3A4, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -7570,6 +7711,8 @@ 0F08FB1608D37DA90022DD45, 0F0F5E3E08FC660300B4EBCD, 0FEA7DDF0926BBEA00B06154, + 0F7EAA9A09326B860082C3EA, + 0FD75058093ABEBA00B6A3A4, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -8203,6 +8346,7 @@ 0FBB8CCF08D260D800D58D8D, 0F01117508F2FE7C00423C02, 0FEA7E660926BFC600B06154, + 0F8FC52E092ED71C0042429E, ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -8729,6 +8873,9 @@ 0F0F5E3B08FC65FB00B4EBCD, 0FEA7DE20926BBF500B06154, 0FEA7DE50926BC0C00B06154, + 0F8FC583092ED8C70042429E, + 0F7EAA9709326B770082C3EA, + 0FD7505B093ABEC600B6A3A4, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -14198,6 +14345,7 @@ F5DE10E90209DC0601A967DF, F528E21A020FD9620168DE43, F566BD1302EFA9AD01A967F3, + 0F8FC582092ED8C70042429E, ); isa = PBXGroup; name = Dialogs; @@ -16036,6 +16184,7 @@ children = ( F507A84103116E1D01026D5D, F507A84403116E5501026D5D, + 0F8FC52C092ED71C0042429E, 0FBC0EC90798F92600E8E0E2, 0FACBFEC07DC020D00DEE23A, F507A84A03116E6E01026D5D, @@ -16448,6 +16597,7 @@ F5B950BA030C833301A96654 = { children = ( 3489ADC90753B717005ADF6C, + 0F7EAA9909326B860082C3EA, F541495E02711B0001A80166, 0F0F5E3C08FC660300B4EBCD, F583E3C203B8228F01A80166, @@ -16475,6 +16625,7 @@ 3FF08F0606E7CF9C001C9B19, 3FF08F0706E7CF9C001C9B19, 3FF08F0806E7CF9C001C9B19, + 0FD75057093ABEBA00B6A3A4, ); isa = PBXGroup; name = Headers; @@ -16484,6 +16635,7 @@ F5B950BB030C833301A96654 = { children = ( 3489ADCA0753B717005ADF6C, + 0F7EAA9609326B770082C3EA, F541495F02711B0001A80166, 0F0F5E3908FC65FB00B4EBCD, F583E3BF03B8228701A80166, @@ -16512,6 +16664,7 @@ 3FF08EFD06E7CF86001C9B19, 3FF08EFE06E7CF86001C9B19, 3FF08EFF06E7CF86001C9B19, + 0FD7505A093ABEC600B6A3A4, ); isa = PBXGroup; name = Source; diff --git a/mozilla/camino/Makefile.in b/mozilla/camino/Makefile.in index d4a293d9a37..014ae119c72 100644 --- a/mozilla/camino/Makefile.in +++ b/mozilla/camino/Makefile.in @@ -42,6 +42,10 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk +DIRS = \ + IBPalette \ + $(NULL) + APP_NAME = Camino ifdef MOZ_DEBUG diff --git a/mozilla/camino/resources/application/ad_blocking.css b/mozilla/camino/resources/application/ad_blocking.css index b5372e1f11e..46aa8f89e99 100644 --- a/mozilla/camino/resources/application/ad_blocking.css +++ b/mozilla/camino/resources/application/ad_blocking.css @@ -83,6 +83,7 @@ embed[type="application/x-shockwave-flash"][src*=".tribalfusion.com/media/"], embed[type="application/x-shockwave-flash"][src*="/flash/promotions/"], embed[type="application/x-shockwave-flash"][src*=".adtrix.com"], embed[type="application/x-shockwave-flash"][src*=".netshelter.net"], +embed[type="application/x-shockwave-flash"][src*=".gms1.net"], img[src*="googlesyndication.com"], img[src*="mediaplex.com"], @@ -111,6 +112,7 @@ img[src*="kermit.macnn.com"], img[src*="media.adlegend.com"], img[src*=".adtrix.com"], img[src*=".netshelter.net"], +img[src*=".gms1.net"], iframe[src*="/ad."], iframe[src*="/ads."], @@ -156,6 +158,7 @@ iframe[src*=".yieldmanager.com"], iframe[src*=".mspaceads.com"], iframe[src*=".adtrix.com"], iframe[src*=".netshelter.net"], +iframe[src*=".gms1.net"], table#overtureLinksWrapper, table.adbritetable, diff --git a/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/classes.nib b/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/classes.nib index 650fdd481d1..01630bc653c 100644 --- a/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/classes.nib +++ b/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/classes.nib @@ -141,6 +141,8 @@ savePageAs = id; sendURL = id; sendURLFromLink = id; + showBookmarksInfo = id; + showPageInfo = id; smallerTextSize = id; stop = id; unblockAllSites = id; diff --git a/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/info.nib b/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/info.nib index fbad2dc92f3..5d58868e887 100644 --- a/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/info.nib +++ b/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/info.nib @@ -3,7 +3,7 @@ IBDocumentLocation - 3 3 530 384 0 0 1280 832 + 33 23 530 384 0 0 1600 1002 IBEditorPositions 1014 @@ -38,6 +38,6 @@ 889 IBSystem Version - 8C46 + 8F46 diff --git a/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/keyedobjects.nib b/mozilla/camino/resources/localized/English.lproj/BrowserWindow.nib/keyedobjects.nib index f6e05ef1c062ae7dae203563af9c6fdd2e585284..6687cac6db482f02b765277db6ba74f6c6093717 100644 GIT binary patch delta 9783 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 delta 9632 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 BsiOb@ diff --git a/mozilla/camino/resources/localized/English.lproj/CertificatesWindow.nib/info.nib b/mozilla/camino/resources/localized/English.lproj/CertificatesWindow.nib/info.nib index 7130de52dbd..dd655ea0cd0 100644 --- a/mozilla/camino/resources/localized/English.lproj/CertificatesWindow.nib/info.nib +++ b/mozilla/camino/resources/localized/English.lproj/CertificatesWindow.nib/info.nib @@ -14,6 +14,6 @@ IBFramework Version 437.0 IBSystem Version - 8C46 + 8F46 diff --git a/mozilla/camino/resources/localized/English.lproj/Localizable.strings b/mozilla/camino/resources/localized/English.lproj/Localizable.strings index bdf5fcb1ad4ace0f24c869510dd38cda06a7b738..4009c6c4f3a3f056a8de0a3c841c281aeb468867 100644 GIT binary patch delta 2399 zcmc&$!D)BgIN)Z{>1 zQSwB5X-WrIw`EN($&#eD)UpNNFy39bu8(2eG(Im8>qu2R332rTM-SIc9IiCrrQ`vQ zC9!@=g2Yqd+<=ddIL7wjbuHjms?U%H?iKra|4_m^SnGJTnAPr=6(`$N7SN3 z2qbwPf&)23aKqe%@sI5_ZRsMZkKpCw=Sm$ZdFJjJ&c`OgT1h2|8PQi1rHnv&<|#D* z(Kf|CMr0i#=t~zCD}qgJv{LktXc`hp^L=oE(X!93xce z!$skWGNmci0qf0XZ3$pQSWnWC#)nv|AtI2sSPPRnnUJMxL^fLoDC{7BkcV;)wNTa5 zsHnoHhX*myER=>SqqQO&RnD8hZ=k>(BzOR6+{HhWX3yn)tq7E?K!+7rmyL8BQ`%~h z@0f7(m~zfYSEkXJw#$gL2+5JuvzgH6qGDzyII(K-CWkAqDvSTuG&}{R(L70zI)|WT zZfd4b(R>JC>u`Q4GLGQ1s3rxoO#xf3Pv>ELxp_KpTPGKP1BSQ1U;qFB delta 362 zcmezJmhr(|#tpZlHh}6v$5jisS)# zdJIYo)(l*e<Ow2&($p*Qylb`2Ln!MYS&$|ey zDHo`@3}|o;(6DkKT?8~L6NuA+d@Tlj1}>nXL2z{-D;>2XPjfIS^A&%wPydwtw;kFY(EzQ%okOrV05cBiqGbPo9ZDT?!1gK&&)bAjf`l IVL>w+06 IBDocumentLocation - 24 23 409 367 0 0 1600 1002 + 134 210 409 367 0 0 1600 1002 IBEditorPositions 29 @@ -15,7 +15,11 @@ IBFramework Version 437.0 + IBOpenObjects + + 29 + IBSystem Version - 8C46 + 8F46 diff --git a/mozilla/camino/resources/localized/English.lproj/MainMenu.nib/keyedobjects.nib b/mozilla/camino/resources/localized/English.lproj/MainMenu.nib/keyedobjects.nib index bc09d0274be1d5cdd9b06b407e8b2d79be27d0ba..50692486af71ddede28a1a805482d93e9bc6631a 100644 GIT binary patch delta 18592 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 N@P2Fi@wfe#{|{2K*aiRq diff --git a/mozilla/camino/resources/localized/English.lproj/PageInfo.nib/classes.nib b/mozilla/camino/resources/localized/English.lproj/PageInfo.nib/classes.nib new file mode 100644 index 00000000000..ed35463171d --- /dev/null +++ b/mozilla/camino/resources/localized/English.lproj/PageInfo.nib/classes.nib @@ -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; +} \ No newline at end of file diff --git a/mozilla/camino/resources/localized/English.lproj/PageInfo.nib/info.nib b/mozilla/camino/resources/localized/English.lproj/PageInfo.nib/info.nib new file mode 100644 index 00000000000..a24ba7a9413 --- /dev/null +++ b/mozilla/camino/resources/localized/English.lproj/PageInfo.nib/info.nib @@ -0,0 +1,12 @@ + + + + + IBDocumentLocation + 18 49 367 240 0 0 1600 1002 + IBFramework Version + 437.0 + IBSystem Version + 8F46 + + diff --git a/mozilla/camino/resources/localized/English.lproj/PageInfo.nib/keyedobjects.nib b/mozilla/camino/resources/localized/English.lproj/PageInfo.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..55625288eb6d4233267831f31428f2b603076dbc GIT binary patch literal 12627 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%0DX`yq7T!>^l|zGIKvCz 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 literal 0 HcmV?d00001 diff --git a/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/classes.nib b/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/classes.nib index 41cdd20ab2e..78f330aab24 100644 --- a/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/classes.nib +++ b/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/classes.nib @@ -1,10 +1,16 @@ { IBClasses = ( + { + CLASS = CHFlippedShrinkWrapView; + LANGUAGE = ObjC; + SUPERCLASS = CHShrinkWrapView; + }, + {CLASS = CHShrinkWrapView; LANGUAGE = ObjC; SUPERCLASS = NSView; }, { CLASS = CHStackView; LANGUAGE = ObjC; OUTLETS = {mDataSource = id; }; - SUPERCLASS = NSView; + SUPERCLASS = CHShrinkWrapView; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, {CLASS = NSObject; LANGUAGE = ObjC; }, diff --git a/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/info.nib b/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/info.nib index b4d63f2bc65..60d93dcf6fb 100644 --- a/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/info.nib +++ b/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/info.nib @@ -5,11 +5,7 @@ IBDocumentLocation 24 42 592 284 0 0 1600 1002 IBFramework Version - 439.0 - IBOpenObjects - - 121 - + 437.0 IBSystem Version 8F46 diff --git a/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/keyedobjects.nib b/mozilla/camino/resources/localized/English.lproj/ProgressDialog.nib/keyedobjects.nib index 36f82d9f57c9584966e443e2c4804640a42e384d..edd8a773faad441afaef672061b44ef9bbec9a71 100644 GIT binary patch delta 2493 zcmY*a3s_Xg6+UO~y>suK@v%_F2WY5o5ph8f45%0sQNoh4h!Kgn!Yb$rWCam7WXCVD zB&Hg4)mW>>pqTh*)6^K7hf(9RiH(YnTBAW@VytaqtfnTKN9XQ}wL9Ov^El`H|3Bx< z+-;0n(X+7(3zn7l_pgGrunk^^o$xli4}0Js`~^OQzrx3G2L2A8z^8BtzJjmeI^2Yx zWdAb)DySkw9StOJd04l@l%`%IM4lKcGQ~(SM&yfef{Ka45Tit@a0*R87!D2u$T2NR zB#YsJnM#r}R3rvoR*nv_i*};D;9`h~7q;-K`2Zq8bSSoU_4yL*@v+fK!{X~>qkRd< ziLue~_JqJ1b!GZs5!V7EAp!(szXA(IxQP4&=0hDk3yWX@{2ChIId~oxOOF?zOtz)) zA~eD>SPlU>UK#LdlSbG?CoxD22*Yq&qv#_iu_4TtAbX>93P7V=>mvq;$a6vLbwTv? z@G@+GhCoLe(Qb;vndx=SaXZTwxC4D@Z+}mzBto`_Y-*SRqIU>zyCt$&E=QiZ57Z!~ z{ZX>~Nj@%kQ*@DBQS#{#3VF*4*(JJ)$kVVcxGyW<9cY%#1-nJJAWiqlzJy`+*yt2{ zeG4Q*iXZmEzGm15AHaS%0I5?lvYgeflGz32?%HCTP0q@^Ehcl<9+BMzd9_{tI>Lxjy!QSGPrAdho@xn)Nv>A?q z{~m9#txHB$rl-8B%3b>Zl!YO|vX1qq;20c-6LMQEa1u_z>0(>B!#TB>xFzGHvhr$oku=?36w!~wgG~{=THtRo-UVm#9nSG%g#VWz{pa9BlSEDp&CbJx zCb$5p5-JE0T5W}ko8V$7PleJV)mq6o8%*|Ra9JKBE9IZVLfO8Q&p+TA{1g6V`PO&~ zT%H>D;|^!O%RAFuEeE4Zs>>^5Dnz&l?=|vplvfV=h9QXlqF=GClP|PwyLFJ`lVswO z13&AX+kFE!n&Afg+fosTHX{AcLWucR@Bp{5-f2s;@7$b+&A=(ZS_}WU0ieM5u^}Xpl`v zf?~E9Q8U|aT$^2k{ToC1Dz-)Ve3BrvpJ5i4q>?~w7#=?;%>js3}<1BZ(-|7-Vz*!ixp^YT_fw2Q) zwo3KmC8;GWOG?`X<6wf6lq>~ANC`<&WLIH|;cf9#WDFMJ6F3!%aT>aCI+kE5xCZy|0$lf3#L*wcPbk*J) zTPa+Cz9#eqy72-2&KQX^a6YcU&G-iH#*gqzyhU`9~Ctr|n$hV5Bv{#~)fl8wM zV@X!hm2pbGQmB+D9;HI5QoMepTA8ObC@Yn9%4X#?WvjAX`GeA`+*CESquN6qq^782 z)m*hmouPWw8nsrfQ+;Z^>Q@)4&!~&k#p-X=rRo-Shx(p+P(7xeQqQQZ>J{}n4YhEs zhc-k@)`n}T+6ZlwmZfEDIa;pvl=hsqN^8=#X>V%&z1qjxajiu=rJd2vYUi{ITB~+R zyR3boeXV_~-PXR>?rJ~Mel&rm(MVQ zrz_|xx|+U1H_^@XHM*Pbq5J55dXOHYXX#~nT_?J!ch-CAef2~=&97(bxq6{qt^4&x zy;=Xg{*L~hzDM7u@7Is&C-js0dHs@pO~0<+Ho!2APDYZEZj3kbjC`ZOm|{F(6dTix zQe%cuZ!9(f#(HCmvBNlTTrsX1*Np4N4dbS9%lMD+opHyEFyqW*Gu_NFOU*fEwYkJx zZTfeb@0&*JG0W5~avN)E+GFcXzz#e4|Hkr+09#+Asn3p}x8rX8S zf~{h!*&4Q%t!J;Y?QAF8%RXQS*dca=eaMco)9h1rk$uKKXII!&c7xqvKd_%TaKcs2 zc~{<(_u+&6JdWG>aQ-k)<70UtFXB`AG(Me|@)^90&*C0l!K-*3U&)ZA MdimCaBmTpG0T0W<%K!iX delta 2224 zcmYjR3sh9c8UE+qJ9F>Ms=1;;anTagXb{5g@>->lAmJqf>MAPO-~yX~E(=*e#4Trs zwnoy22eVphjX^+aV>~g&K1`F;m>P+%plA+3<0~Yo)><1iYNL&vyQ`)hxDn^8G>Y$~6{pXTX&8c*W|dm4enR& zjx4XU+U2NP=?eT9FL-Ja*ZD|3VK@rYkMSt6oZJV~Mf7hVuS*21gSBEWicjF?Q?LS> z;AgN3UW8Yn9kxJgKquh=8yWA9+pE zpDl3YH`F`J+^%%5*V(k7z!97c!K7eXn@_-g_)u6q06p;0d_k2x!(gv**LWSZ&T?0l zHA)Q75g#YW{ldv1INS+`AytqCVIj?<@bOmoIApI_oVcrM4Rfc0xi|*LVI}khb8-Ss zLW>yv;y(bV;52*&XW*<6)8H*~x*J>z3mo&D-sfHQi$uOWhWQGyn(gwIyGlIu;xxUy z-pF7W4~tIYqHeGmuO2{g%YENozUR+vH<0$vmxZN)A zw2=lJ8LdW6px zC(1N7%6J9~H%Sz+Rmc`Utl{R6=+|&cHLTZ}-pyZqHCloe96I%v59p^?pwIi33mef=y(d>!M!fHhahl; zCi-QV3l`3}ja#@>)L7-IsA)V2`A{HkUI;CS2G7HIqH$hQ{k_lcLEY$)ASj$C8=&Iq zhs7Ig3^Wo&Y!#i^4Gw4#{TD9O!ni%?3;E5kuhS^f5Ok~o6)>&h14Dg4bA_RpoX~s*5UY^cYQHaM)19mIrZ3 z#@c_M#Ev3fgKXh4M@V$TOvn{NEu0E@tB?!lN#ffjg?t-C&j>uqL|G^s<)B+y~JHS;_yodiMTW zv^#R5vQAVMxNMr7K+z-OtLsLs=(ngF?LvFeX><|Ykt9i%#!0bKmNZvdA}y6(km{rc zsZnZ@e1U00%>GxU?a~hE4e5Z?D}5>rN*ASDGRPz3NO_VxS&oqtdPhtzU;Z!^wKaFSL z8tlWX@p{~Wx8vP-FFuNU@o{_te}en*0R9Z0#pm(o_zQdm-@rHVZTv01OD2+dGL>YI zOp;AI7tP0j#QFW#J`pV$a=DYY$Th=X7YRT2l5WtPmYpP~R*y;+d5tup~B}WwLCR%ko%0^Uq^Wwv;Vn)oeLy zWKHZRY(3k+HnL4@GizrZtc!KCZR|Dn7W IBDocumentLocation - 101 124 448 284 0 0 1280 832 + 35 161 448 284 0 0 1600 1002 IBEditorPositions 5 - 339 461 346 92 0 0 1024 746 + 606 622 346 92 0 0 1600 1002 71 - 339 462 346 92 0 0 1024 746 + 606 622 346 92 0 0 1600 1002 IBFramework Version - 439.0 + 437.0 IBLockedObjects 5 - IBOpenObjects - - 71 - 5 - IBSystem Version - 8C46 + 8F46 diff --git a/mozilla/camino/resources/localized/English.lproj/ProgressView.nib/keyedobjects.nib b/mozilla/camino/resources/localized/English.lproj/ProgressView.nib/keyedobjects.nib index def1ec11a57561a4d14f8da8450c918deae50a0f..a19da7f88aa9b24cd6401d7578996e539491bfe8 100644 GIT binary patch delta 312 zcmeyV`BQU)86*1%#>0#!8INqXWz6K&VDx85Vf1B4V{~9hV(@23Wk_c9YY1$RZE$Wd zY;bJgY2a$mX%KAioqUc@Dgvm;AA}hUpcu#lD&hiTCLj&MAYSYx20I2Z#x;zySAs2Y zU`T@+ZvZvk5okQba3-MP4*ZTfv3|iJsTCz|nW;G`hK6y@`MCu-sU@i?3SpV4@DSXP7zr`RDPk=3mRddvdtQ FA^^-=T1Nl? delta 313 zcmeyV`BQU)86*2)#uGqzalP@|dPhCA>(%Eb5uhon}NxMim1q!`9I=jRsWq?V+nD1>FEmQP;G zFD(#@tiUkPaPkR$Ra2mof#&-HUE0HWl>yKT$v{s8f=xFBdc?7TvmvU%0q8C! zpjQNeo>3C;6yG7RNnoeI76Eqweu4D@^8{E0b_r|{;NILMaE6()kAE)zYW^Mk$0mo1 GECK)%Mp|zG diff --git a/mozilla/camino/resources/localized/English.lproj/ViewCertificateDialog.nib/info.nib b/mozilla/camino/resources/localized/English.lproj/ViewCertificateDialog.nib/info.nib index 43806a4ab75..77930a26534 100644 --- a/mozilla/camino/resources/localized/English.lproj/ViewCertificateDialog.nib/info.nib +++ b/mozilla/camino/resources/localized/English.lproj/ViewCertificateDialog.nib/info.nib @@ -7,6 +7,6 @@ IBFramework Version 437.0 IBSystem Version - 8C46 + 8F46 diff --git a/mozilla/camino/resources/localized/English.lproj/ViewCertificateDialog.nib/keyedobjects.nib b/mozilla/camino/resources/localized/English.lproj/ViewCertificateDialog.nib/keyedobjects.nib index a685aefbd64b53a1a6c36ed06dd431a2119064f3..56171e3cbafc7225fcd7746d3f51ced10155170d 100644 GIT binary patch delta 196 zcmX@Dd|G(}BcmE)9m7F}qYSec>lvFETNx)aE@WK9P{X*G;V$D6#-)tQ7?(4yU|hLb zopCF-@HvJh4DT2M8Dbg~8YCN38n_y`C%@;B)iq!^#}LD?q=CDE2`Ix2l=Ha6V8Vguwu!3n&NHGue{YPuq*Z11Rpz;11Mx4rrz)P)%TiQ-cIhm1_eh&O{>OWk832fcHvj+t delta 196 zcmX@Dd|G(}BcmF_EXF#9qYMWb>lvFETNx)aE@WK9aF=m0;}XWDjLR68Gp=A<$xyRd zopCF-a3I4uhIb4x3`-ig8Wb8-8n_!IC%@;B)r|p)FJUkM^0|THk_}7^9+w#G7{nM0 z8B>=q1Tq)^b%FFS0rf~uw&eBGe#hX&;LhL;))&a&2{h9Ks9&YQse!Y>6>J7qg9Fes ji3X<0n|Q4SRRlx@)C5!oSOs_lL window = getter_AddRefs([mBrowserView getContentWindow]); - if (!window) - return @""; - - nsCOMPtr htmlDoc; - window->GetDocument(getter_AddRefs(htmlDoc)); - - nsCOMPtr htmlDocument(do_QueryInterface(htmlDoc)); - if (!htmlDocument) - return @""; - - nsAutoString titleString; - htmlDocument->GetTitle(titleString); - return [NSString stringWith_nsAString:titleString]; + return [mBrowserView pageTitle]; } - (NSImage*)siteIcon diff --git a/mozilla/camino/src/browser/PageInfoWindowController.h b/mozilla/camino/src/browser/PageInfoWindowController.h new file mode 100644 index 00000000000..0e85644fa40 --- /dev/null +++ b/mozilla/camino/src/browser/PageInfoWindowController.h @@ -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 + * + * 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 + +@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 diff --git a/mozilla/camino/src/browser/PageInfoWindowController.mm b/mozilla/camino/src/browser/PageInfoWindowController.mm new file mode 100644 index 00000000000..fdc3a480f44 --- /dev/null +++ b/mozilla/camino/src/browser/PageInfoWindowController.mm @@ -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 + * + * 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 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 secureBrowserUI = [inBrowserView getSecureBrowserUI]; + + nsCOMPtr statusProvider = do_QueryInterface(secureBrowserUI); + if (!statusProvider) return; + + nsCOMPtr serverCert; + PRUint32 sekritKeyLength = 0; + NSString* cipherNameString = @""; + + nsCOMPtr secStatus; + statusProvider->GetSSLStatus(getter_AddRefs(secStatus)); + nsCOMPtr 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 diff --git a/mozilla/camino/src/download/ProgressDlgController.mm b/mozilla/camino/src/download/ProgressDlgController.mm index 595731df88e..a74dfe7f747 100644 --- a/mozilla/camino/src/download/ProgressDlgController.mm +++ b/mozilla/camino/src/download/ProgressDlgController.mm @@ -68,6 +68,8 @@ static NSString* const kProgressWindowFrameSaveName = @"ProgressWindow"; @end +#pragma mark - + @implementation ProgressDlgController static id gSharedProgressController = nil; @@ -88,7 +90,8 @@ static id gSharedProgressController = nil; -(id)init { - if ((self == [super initWithWindowNibName:@"ProgressDialog"])) { + if ((self = [super initWithWindowNibName:@"ProgressDialog"])) + { mProgressViewControllers = [[NSMutableArray alloc] init]; mDefaultWindowSize = [[self window] frame].size; // it would be nice if we could get the frame from the name, and then @@ -101,12 +104,17 @@ static id gSharedProgressController = nil; mShouldCloseWindow = NO; // We provide the views for the stack view, from mProgressViewControllers + [mStackView setShowsSeparators:YES]; [mStackView setDataSource:self]; + mSelectionPivotIndex = -1; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(DLInstanceSelected:) - name:@"DownloadInstanceSelected" object:nil]; + name:kDownloadInstanceSelectedNotificationName + object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(DLInstanceOpened:) - name:@"DownloadInstanceOpened" object:nil]; + name:kDownloadInstanceOpenedNotificationName + object:nil]; } return self; @@ -592,7 +600,7 @@ static id gSharedProgressController = nil; -(void)rebuildViews { - [mStackView reloadSubviews]; + [mStackView adaptToSubviews]; } -(int)numDownloadsInProgress @@ -990,14 +998,15 @@ static id gSharedProgressController = nil; CHStackView datasource methods */ --(int)subviewsForStackView:(CHStackView *)stackView +- (NSArray*)subviewsForStackView:(CHStackView *)stackView { - return [mProgressViewControllers count]; -} - --(NSView *)viewForStackView:(CHStackView *)aResizingView atIndex:(int)index -{ - return [((ProgressViewController*)[mProgressViewControllers objectAtIndex:index]) view]; + NSMutableArray* viewsArray = [NSMutableArray arrayWithCapacity:[mProgressViewControllers count]]; + + unsigned int numViews = [mProgressViewControllers count]; + for (unsigned int i = 0; i < numViews; i ++) + [viewsArray addObject:[((ProgressViewController*)[mProgressViewControllers objectAtIndex:i]) view]]; + + return viewsArray; } #pragma mark - diff --git a/mozilla/camino/src/download/ProgressView.h b/mozilla/camino/src/download/ProgressView.h index 3cf57ceac12..7d7f2c9376d 100644 --- a/mozilla/camino/src/download/ProgressView.h +++ b/mozilla/camino/src/download/ProgressView.h @@ -40,6 +40,9 @@ #import #import "ProgressViewController.h" +extern NSString* const kDownloadInstanceSelectedNotificationName; +extern NSString* const kDownloadInstanceOpenedNotificationName; + // // interface ProgressView // diff --git a/mozilla/camino/src/download/ProgressView.mm b/mozilla/camino/src/download/ProgressView.mm index 03223fb8c0a..393d1bd9ec1 100644 --- a/mozilla/camino/src/download/ProgressView.mm +++ b/mozilla/camino/src/download/ProgressView.mm @@ -40,6 +40,9 @@ #import "ProgressView.h" +NSString* const kDownloadInstanceSelectedNotificationName = @"DownloadInstanceSelected"; +NSString* const kDownloadInstanceOpenedNotificationName = @"DownloadInstanceOpened"; + @interface ProgressView(Private) -(BOOL)isSelected; @@ -87,14 +90,14 @@ } } [self setSelected:shouldSelect]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadInstanceSelected" object:self]; + [[NSNotificationCenter defaultCenter] postNotificationName:kDownloadInstanceSelectedNotificationName object:self]; // after we've processed selection and modifiers, see if it's a double-click. If so, // send a notification off to the controller which will handle it accordingly. Doing it after // processing the modifiers allows someone to shift-dblClick and open all selected items // in the list in one action. if ([theEvent type] == NSLeftMouseDown && [theEvent clickCount] == 2) - [[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadInstanceOpened" object:self]; + [[NSNotificationCenter defaultCenter] postNotificationName:kDownloadInstanceOpenedNotificationName object:self]; } -(int)lastModifier @@ -130,7 +133,7 @@ mLastModifier = kNoKey; // control is only special because it means its contextual menu time [self setSelected:YES]; [self display]; // change selection immediately - [[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadInstanceSelected" object:self]; + [[NSNotificationCenter defaultCenter] postNotificationName:kDownloadInstanceSelectedNotificationName object:self]; } return [[self getController] contextualMenu]; } diff --git a/mozilla/camino/src/embedding/CHBrowserView.h b/mozilla/camino/src/embedding/CHBrowserView.h index 2b1f403a0fe..599703c9a55 100644 --- a/mozilla/camino/src/embedding/CHBrowserView.h +++ b/mozilla/camino/src/embedding/CHBrowserView.h @@ -50,14 +50,12 @@ class nsIDOMWindow; class nsIWebBrowser; class nsIDOMNode; class nsIDOMEvent; -class nsIWebBrowserFind; class nsIEventSink; class nsIDragHelperService; class nsIPrintSettings; class nsIURI; class nsISupports; - // Protocol implemented by anyone interested in progress // related to a BrowserView. A listener should explicitly // register itself with the view using the addListener @@ -176,8 +174,14 @@ enum { - (void)goForward; - (void)gotoIndex:(int)index; - (void)stop:(unsigned int)flags; + - (NSString*)getCurrentURI; +- (NSString*)pageLocation; // from window.location. can differ from the document's URI, and possibly from getCurrentURI +- (NSString*)pageLocationHost; +- (NSString*)pageTitle; +- (NSDate*)pageLastModifiedDate; + // nsIWebBrowserSetup methods - (void)setProperty:(unsigned int)property toValue:(unsigned int)value; diff --git a/mozilla/camino/src/embedding/CHBrowserView.mm b/mozilla/camino/src/embedding/CHBrowserView.mm index 4e1a1e3b852..f3495282608 100644 --- a/mozilla/camino/src/embedding/CHBrowserView.mm +++ b/mozilla/camino/src/embedding/CHBrowserView.mm @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Simon Fraser * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -37,6 +38,7 @@ #import "NSString+Utils.h" #import "NSPasteboard+Utils.h" +#import "NSDate+Utils.h" #import "CHClickListener.h" @@ -75,6 +77,7 @@ // Saving of links/images/docs #include "nsIWebBrowserFocus.h" #include "nsIDOMNSDocument.h" +#include "nsIDOMHTMLDocument.h" #include "nsIDOMLocation.h" #include "nsIWebBrowserPersist.h" #include "nsIProperties.h" @@ -131,9 +134,10 @@ const long NSFindPanelActionSetFindString = 7; - (nsIContentViewer*)getContentViewer; // addrefs return value - (float)getTextZoom; - (void)incrementTextZoom:(float)increment min:(float)min max:(float)max; -- (nsIDocShell*)getDocShell; +- (nsIDocShell*)getDocShell; // does NOT addref - (NSString*)getSelection; - +- (already_AddRefed)focussedDOMWindow; +- (NSString*)locationFromDOMWindow:(nsIDOMWindow*)inDOMWindow; - (void)ensurePrintSettings; - (void)savePrintSettings; @@ -345,6 +349,7 @@ const long NSFindPanelActionSetFindString = 7; _listener->SetContainer(container); } +// addrefs return value - (nsIDOMWindow*)getContentWindow { nsIDOMWindow* window = nsnull; @@ -489,6 +494,7 @@ const long NSFindPanelActionSetFindString = 7; browserSetup->SetProperty(property, value); } +// should we be using the window.location URL instead? see nsIDOMLocation.h - (NSString*)getCurrentURI { nsCOMPtr nav = do_QueryInterface(_webBrowser); @@ -505,6 +511,76 @@ const long NSFindPanelActionSetFindString = 7; return [NSString stringWithUTF8String:spec.get()]; } +- (NSString*)pageLocation +{ + nsCOMPtr contentWindow = getter_AddRefs([self getContentWindow]); + NSString* location = [self locationFromDOMWindow:contentWindow]; + return location ? location : @""; +} + +- (NSString*)pageLocationHost +{ + nsCOMPtr domWindow = getter_AddRefs([self getContentWindow]); + if (!domWindow) return @""; + nsCOMPtr domDocument; + domWindow->GetDocument(getter_AddRefs(domDocument)); + if (!domDocument) return @""; + nsCOMPtr nsDoc(do_QueryInterface(domDocument)); + if (!nsDoc) return @""; + + nsCOMPtr location; + nsDoc->GetLocation(getter_AddRefs(location)); + if (!location) return @""; + nsAutoString hostStr; + location->GetHost(hostStr); + + return [NSString stringWith_nsAString:hostStr]; +} + +- (NSString*)pageTitle +{ + nsCOMPtr window = getter_AddRefs([self getContentWindow]); + if (!window) + return @""; + + nsCOMPtr htmlDoc; + window->GetDocument(getter_AddRefs(htmlDoc)); + + nsCOMPtr htmlDocument(do_QueryInterface(htmlDoc)); + if (!htmlDocument) + return @""; + + nsAutoString titleString; + htmlDocument->GetTitle(titleString); + return [NSString stringWith_nsAString:titleString]; +} + +- (NSDate*)pageLastModifiedDate +{ + nsCOMPtr domWindow = getter_AddRefs([self getContentWindow]); + + nsCOMPtr domDocument; + domWindow->GetDocument(getter_AddRefs(domDocument)); + if (!domDocument) + return nil; + nsCOMPtr nsDoc(do_QueryInterface(domDocument)); + if (!nsDoc) + return nil; + + nsAutoString lastModifiedDate; + nsDoc->GetLastModified(lastModifiedDate); + + // sucks that we have to parse this back to a PRTime, thence back + // again to an NSDate. Why doesn't nsIDOMNSDocument have an accessor + // which can give me a date directly? + PRTime time; + PRStatus st = PR_ParseTimeString(NS_ConvertUCS2toUTF8(lastModifiedDate).get(), PR_FALSE /* local time */, &time); + if (st == PR_SUCCESS) + return [NSDate dateWithPRTime:time]; + + return nil; +} + - (CHBrowserListener*)getCocoaBrowserListener { return _listener; @@ -766,32 +842,46 @@ const long NSFindPanelActionSetFindString = 7; filterView: aFilterView]; } +- (already_AddRefed)focussedDOMWindow +{ + if (!_webBrowser) + return nsnull; + + nsCOMPtr 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 domDocument; + inDOMWindow->GetDocument(getter_AddRefs(domDocument)); + if (!domDocument) + return nil; + nsCOMPtr nsDoc(do_QueryInterface(domDocument)); + if (!nsDoc) + return nil; + nsCOMPtr location; + nsDoc->GetLocation(getter_AddRefs(location)); + if (!location) + return nil; + nsAutoString urlStr; + location->GetHref(urlStr); + return [NSString stringWith_nsAString:urlStr]; +} + -(NSString*)getFocusedURLString { if (!_webBrowser) return @""; - nsCOMPtr wbf(do_QueryInterface(_webBrowser)); - nsCOMPtr domWindow; - wbf->GetFocusedWindow(getter_AddRefs(domWindow)); - if (!domWindow) - _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); - if (!domWindow) - return @""; - nsCOMPtr domDocument; - domWindow->GetDocument(getter_AddRefs(domDocument)); - if (!domDocument) - return @""; - nsCOMPtr nsDoc(do_QueryInterface(domDocument)); - if (!nsDoc) - return @""; - nsCOMPtr location; - nsDoc->GetLocation(getter_AddRefs(location)); - if (!location) - return @""; - nsAutoString urlStr; - location->GetHref(urlStr); - return [NSString stringWith_nsAString: urlStr]; + nsCOMPtr focussedWindow = [self focussedDOMWindow]; + NSString* locationString = [self locationFromDOMWindow:focussedWindow]; + return locationString ? locationString : @""; } - (void)saveDocument:(BOOL)focusedFrame filterView:(NSView*)aFilterView @@ -801,13 +891,9 @@ const long NSFindPanelActionSetFindString = 7; nsCOMPtr domWindow; if (focusedFrame) - { - nsCOMPtr wbf(do_QueryInterface(_webBrowser)); - wbf->GetFocusedWindow(getter_AddRefs(domWindow)); - } + domWindow = [self focussedDOMWindow]; else _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); - if (!domWindow) return; @@ -815,26 +901,19 @@ const long NSFindPanelActionSetFindString = 7; domWindow->GetDocument(getter_AddRefs(domDocument)); if (!domDocument) return; - nsCOMPtr nsDoc(do_QueryInterface(domDocument)); - if (!nsDoc) - return; - nsCOMPtr location; - nsDoc->GetLocation(getter_AddRefs(location)); - if (!location) - return; - nsAutoString urlStr; - location->GetHref(urlStr); + + NSString* windowLocation = [self locationFromDOMWindow:domWindow]; nsCOMPtr url; - nsresult rv = NS_NewURI(getter_AddRefs(url), NS_ConvertUCS2toUTF8(urlStr).get()); + nsresult rv = NS_NewURI(getter_AddRefs(url), [windowLocation UTF8String]); if (NS_FAILED(rv)) return; - [self saveInternal: url.get() - withDocument: domDocument - suggestedFilename: @"" - bypassCache: NO - filterView: aFilterView]; + [self saveInternal:url.get() + withDocument:domDocument + suggestedFilename:@"" + bypassCache:NO + filterView:aFilterView]; } -(void)doCommand:(const char*)commandName @@ -1011,38 +1090,6 @@ const long NSFindPanelActionSetFindString = 7; [[self getBrowserContainer] didDismissPrompt]; } -#if 0 -// how does this differ from getCurrentURI? --(NSString*)getCurrentURLSpec -{ - NSString* empty = @""; - if (!_webBrowser) - return empty; - nsCOMPtr domWindow; - _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); - if (!domWindow) - return empty; - - nsCOMPtr domDocument; - domWindow->GetDocument(getter_AddRefs(domDocument)); - if (!domDocument) - return empty; - - nsCOMPtr nsDoc(do_QueryInterface(domDocument)); - if (!nsDoc) - return empty; - - nsCOMPtr location; - nsDoc->GetLocation(getter_AddRefs(location)); - if (!location) - return empty; - - nsAutoString urlStr; - location->GetHref(urlStr); - return [NSString stringWith_nsAString: urlStr]; -} -#endif - - (void)setActive: (BOOL)aIsActive { nsCOMPtr wbf(do_QueryInterface(_webBrowser)); @@ -1095,7 +1142,7 @@ const long NSFindPanelActionSetFindString = 7; } } - +// does NOT addref return value - (nsIDocShell*)getDocShell { if (!_webBrowser) diff --git a/mozilla/camino/src/extensions/AutoSizingTextField.h b/mozilla/camino/src/extensions/AutoSizingTextField.h new file mode 100644 index 00000000000..48095fc4a81 --- /dev/null +++ b/mozilla/camino/src/extensions/AutoSizingTextField.h @@ -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 + * + * 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 + +// +// 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 diff --git a/mozilla/camino/src/extensions/AutoSizingTextField.m b/mozilla/camino/src/extensions/AutoSizingTextField.m new file mode 100644 index 00000000000..a8375a86d03 --- /dev/null +++ b/mozilla/camino/src/extensions/AutoSizingTextField.m @@ -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 + * + * 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 diff --git a/mozilla/camino/src/extensions/CHStackView.h b/mozilla/camino/src/extensions/CHStackView.h index b9b338968a3..144405d5ece 100644 --- a/mozilla/camino/src/extensions/CHStackView.h +++ b/mozilla/camino/src/extensions/CHStackView.h @@ -20,6 +20,7 @@ * * Contributor(s): * Calum Robinson + * Simon Fraser * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -38,24 +39,98 @@ #import // views contained in the stack should send this notification when they change size -extern NSString* StackViewReloadNotificationName; +extern NSString* const kStackViewReloadNotificationName; // the stack view sends this notification after it has adjusted to subview sizes -extern NSString* StackViewResizedNotificationName; +extern NSString* const kStackViewResizedNotificationName; -@interface CHStackView : NSView + +// +// CHShrinkWrapView +// +// A view that resizes to contain its subviews. +// +// Early on, it will look at its subview positions, and calculate +// the "intrinsic padding" (i.e. the space around the subviews), +// and use this when sizing itself. It will then resize itself to +// contain its subviews, plus the padding, whenever one if its +// direct subviews resizes. +// +// Can be used in Interface Builder, if you have built and installed +// the CaminoView.palette IB Palette. +// + +@interface CHShrinkWrapView : NSView +{ + float mIntrinsicPadding[4]; // NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge + BOOL mFetchedIntrinsicPadding; + BOOL mPaddingSetManually; + BOOL mSelfResizing; +} + +// padding will normally be calculated automatically from the subview positions, +// but you can set it explicilty if you wish. +- (void)setIntrinsicPadding:(float)inPadding forEdge:(NSRectEdge)inEdge; +- (float)paddingForEdge:(NSRectEdge)inEdge; + +- (void)adaptToSubviews; + +@end + + + +// +// CHFlippedShrinkWrapView +// +// A subview of CHShrinkWrapView that is flipped. +// +// This is used when nesting a CHStackView inside an NSScrollView, +// because NSScrollView messes up is its containerView isn't flipped +// (really). +// +// If you have one of these in IB, editing contained views is broken +// (view outlines draw flipped, mouse interaction is busted). +// + +@interface CHFlippedShrinkWrapView : CHShrinkWrapView +{ +} + +@end + +// +// CHStackView +// +// A view that lays out its subviews top to bottom. +// +// It can either manage a static set of subviws as specified in +// the nib, or the subviews can be supplied by a "data source". +// If using a data source, the stack view can optionally insert +// a separator view after each supplied view. +// +// The data source, if used, must retain the views. +// +// Can be used in Interface Builder, if you have built and installed +// the CaminoView.palette IB Palette. +// + +@interface CHStackView : CHShrinkWrapView { IBOutlet id mDataSource; + BOOL mShowsSeparators; +// BOOL mIsResizingSubviews; } - (void)setDataSource:(id)aDataSource; -- (void)reloadSubviews; + +// default is NO +- (BOOL)showsSeparators; +- (void)setShowsSeparators:(BOOL)inShowSeparators; @end @protocol CHStackViewDataSource -- (int)subviewsForStackView:(CHStackView *)stackView; -- (NSView *)viewForStackView:(CHStackView *)stackView atIndex:(int)index; +- (NSArray*)subviewsForStackView:(CHStackView *)stackView; @end diff --git a/mozilla/camino/src/extensions/CHStackView.m b/mozilla/camino/src/extensions/CHStackView.m index 02018466783..c3e19331000 100644 --- a/mozilla/camino/src/extensions/CHStackView.m +++ b/mozilla/camino/src/extensions/CHStackView.m @@ -22,6 +22,7 @@ * Contributor(s): * Calum Robinson * Josh Aas + * Simon Fraser * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -37,34 +38,292 @@ * * ***** END LICENSE BLOCK ***** */ -/* - This class was inspired by the OAStack view from OmniGroup, but not copied directly. This - implementation is a little simpler, which is fine. - - It's like NSTableView, except the data source returns views instead of strings/images etc. - */ - #import "NSView+Utils.h" #import "CHStackView.h" -NSString* StackViewReloadNotificationName = @"ReloadStackView"; -NSString* StackViewResizedNotificationName = @"StackViewResized"; +@interface NSObject(PrivateAPI) ++ (BOOL)isInInterfaceBuilder; ++ (BOOL)editingInInterfaceBuilder; +@end + +@interface CHShrinkWrapView(Private) + ++ (BOOL)drawPlacementRect; + +- (void)setupNotifications; +- (void)viewBoundsChangedNotification:(NSNotification*)inNotification; +- (void)viewFrameChangedNotification:(NSNotification*)inNotification; +- (void)recalcPadding; + +@end + +#pragma mark - + +@implementation CHShrinkWrapView + +- (id)initWithFrame:(NSRect)inFrame +{ + if ((self = [super initWithFrame:inFrame])) + { + [self setupNotifications]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder +{ + if ((self = [super initWithCoder:decoder])) + { + [self setupNotifications]; + } + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder +{ + [super encodeWithCoder:coder]; +} + +- (void)awakeFromNib +{ +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + +- (void)drawRect:(NSRect)inRect +{ + if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] && + [NSObject editingInInterfaceBuilder]) + { + [[NSColor blueColor] set]; + NSFrameRect([self bounds]); + } +} + +- (void)setIntrinsicPadding:(float)inPadding forEdge:(NSRectEdge)inEdge +{ + if ((int)inEdge < 0 || (int)inEdge > 3) + return; + + mIntrinsicPadding[inEdge] = inPadding; + mPaddingSetManually = YES; +} + +- (float)paddingForEdge:(NSRectEdge)inEdge +{ + if ((int)inEdge < 0 || (int)inEdge > 3) + return 0.0f; + + return mIntrinsicPadding[inEdge]; +} + +- (void)didAddSubview:(NSView *)subview +{ + [subview setPostsBoundsChangedNotifications:YES]; + [subview setPostsFrameChangedNotifications:YES]; + + mFetchedIntrinsicPadding = NO; +} + +- (void)willRemoveSubview:(NSView *)subview +{ +} + +- (void)viewDidMoveToWindow +{ + if ([self window]) + { + [self adaptToSubviews]; + } +} + +- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize +{ + BOOL alreadyResizing = mSelfResizing; + + // avoid layout out our subviews once for every subview resize... + mSelfResizing = YES; + [super resizeSubviewsWithOldSize:oldBoundsSize]; + mSelfResizing = alreadyResizing; + + // ...by doing it just once here + if (!alreadyResizing) + [self adaptToSubviews]; +} + +- (void)recalcPadding +{ + if (mPaddingSetManually || mFetchedIntrinsicPadding) + return; + + NSRect subframeBounds = NSZeroRect; + NSEnumerator* subviewsEnum = [[self subviews] objectEnumerator]; + NSView* curSubView; + while ((curSubView = [subviewsEnum nextObject])) + { + NSRect subviewFrame = [curSubView frame]; + subframeBounds = NSUnionRect(subviewFrame, subframeBounds); + } + + NSRect myBounds = [self bounds]; + mIntrinsicPadding[NSMinXEdge] = NSMinX(subframeBounds); + mIntrinsicPadding[NSMinYEdge] = NSMinY(subframeBounds); + mIntrinsicPadding[NSMaxXEdge] = NSWidth(myBounds) - NSMaxX(subframeBounds); + mIntrinsicPadding[NSMaxYEdge] = NSHeight(myBounds) - NSMaxY(subframeBounds); + + mFetchedIntrinsicPadding = YES; +} + +- (void)adaptToSubviews +{ + // we can't rely on -awakeFromNib being called in any particular order, + // so we have to call -recalcPadding here, rather than from -awakeFromNib. + [self recalcPadding]; + + if (mSelfResizing) return; + + if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] && + [NSObject editingInInterfaceBuilder]) + { + return; + } + +#if 0 + NSLog(@"%@ padding: %f %f %f %f", self, mIntrinsicPadding[0], + mIntrinsicPadding[1], + mIntrinsicPadding[2], + mIntrinsicPadding[3]); +#endif + + + NSRect subframeBounds = NSZeroRect; + NSEnumerator* subviewsEnum = [[self subviews] objectEnumerator]; + NSView* curSubView; + while ((curSubView = [subviewsEnum nextObject])) + { + NSRect subviewFrame = [curSubView frame]; + subframeBounds = NSUnionRect(subviewFrame, subframeBounds); + } + + subframeBounds.origin.x = mIntrinsicPadding[NSMinXEdge]; + subframeBounds.origin.y = mIntrinsicPadding[NSMinYEdge]; + + subframeBounds.size.width += mIntrinsicPadding[NSMaxXEdge]; + subframeBounds.size.height += mIntrinsicPadding[NSMaxYEdge]; + + NSSize curSize = [self frame].size; + NSSize newSize = curSize; + if (!([self autoresizingMask] & NSViewWidthSizable)) + newSize.width = NSMaxX(subframeBounds); + + if (!([self autoresizingMask] & NSViewHeightSizable)) + newSize.height = NSMaxY(subframeBounds); + + if (!NSEqualSizes(curSize, newSize)) + { + // NSLog(@"resize %@ to %@", self, NSStringFromSize(newSize)); + mSelfResizing = YES; + [self setFrameSizeMaintainingTopLeftOrigin:newSize]; + mSelfResizing = NO; + + [super setNeedsDisplay:YES]; + } +} + +- (void)setupNotifications +{ + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(viewBoundsChangedNotification:) + name:NSViewBoundsDidChangeNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(viewFrameChangedNotification:) + name:NSViewFrameDidChangeNotification + object:nil]; +} + +- (void)viewBoundsChangedNotification:(NSNotification*)inNotification +{ + NSView* changedView = [inNotification object]; + if (changedView == self) + [self recalcPadding]; + else if ([self hasSubview:changedView]) + [self adaptToSubviews]; +} + +- (void)viewFrameChangedNotification:(NSNotification*)inNotification +{ + NSView* changedView = [inNotification object]; + if (changedView == self) + [self recalcPadding]; + else if ([self hasSubview:changedView]) + [self adaptToSubviews]; +} + +- (BOOL)isFlipped +{ + // not flipped because that IB freaks out when editing if it is + return NO; +} + +@end + + +#pragma mark - + +@implementation CHFlippedShrinkWrapView + +- (BOOL)isFlipped +{ + return YES; +} + +@end + +#pragma mark - + +NSString* const kStackViewReloadNotificationName = @"ReloadStackView"; +NSString* const kStackViewResizedNotificationName = @"StackViewResized"; + +@interface CHStackView(Private) + +- (NSArray*)managedSubviews; + +@end @implementation CHStackView -(id)initWithFrame:(NSRect)frameRect { - if ((self = [super initWithFrame:frameRect])) { - // Register for notifications when one of the subviews changes size + if ((self = [super initWithFrame:frameRect])) + { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadNotification:) - name:StackViewReloadNotificationName + name:kStackViewReloadNotificationName object:nil]; } return self; } +- (void)awakeFromNib +{ + // if we're thawed from a nib, and we don't have any subviews, then we seem + // to have subview resizing turned off, but we want it on. + [self setAutoresizesSubviews:YES]; + + if ([super respondsToSelector:@selector(awakeFromNib)]) + [super awakeFromNib]; + + [self adaptToSubviews]; +} + -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; @@ -74,66 +333,144 @@ NSString* StackViewResizedNotificationName = @"StackViewResized"; -(void)setDataSource:(id)aDataSource { mDataSource = aDataSource; // should this retain? - [self reloadSubviews]; + [self adaptToSubviews]; } -(void)reloadNotification:(NSNotification*)notification { - [self reloadSubviews]; + [self adaptToSubviews]; } --(void)reloadSubviews +- (void)didAddSubview:(NSView *)subview { - NSRect newFrame = [self frame]; - NSSize oldSize = [self bounds].size; - int i, subviewCount = [mDataSource subviewsForStackView:self]; - NSPoint nextOrigin = NSZeroPoint; - - // maintain the width of the stack view, assuming that it's scaled by its superview. - newFrame.size.height = 0.0; - - [self removeAllSubviews]; - - for (i = 0; i < subviewCount; i++) { - NSView *subview = [mDataSource viewForStackView:self atIndex:i]; - NSRect subviewFrame = [subview frame]; - NSBox *separator; - - unsigned int autoResizeMask = [subview autoresizingMask]; - if (autoResizeMask & NSViewWidthSizable) - subviewFrame.size.width = newFrame.size.width; - - newFrame.size.height += NSHeight(subviewFrame); - - subviewFrame.origin = nextOrigin; - [subview setFrame:subviewFrame]; - nextOrigin.y += NSHeight(subviewFrame); - - [self addSubview:subview]; - - // always add a separator - separator = [[NSBox alloc] initWithFrame: - NSMakeRect(nextOrigin.x, nextOrigin.y - 1.0, NSWidth([subview frame]), 1.0)]; - [separator setBoxType:NSBoxSeparator]; - [separator setAutoresizingMask:NSViewWidthSizable]; - [self addSubview:separator]; - [separator release]; + [super didAddSubview:subview]; + // [subview setAutoresizingMask:([subview autoresizingMask] | NSViewMinYMargin)]; +} + +- (void)drawRect:(NSRect)inRect +{ + if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] && + [NSObject editingInInterfaceBuilder]) + { + [[NSColor orangeColor] set]; + NSFrameRect([self bounds]); + } +} + +-(void)adaptToSubviews +{ + if (mSelfResizing) return; // avoid re-entry + + if ([NSObject respondsToSelector:@selector(editingInInterfaceBuilder)] && + [NSObject editingInInterfaceBuilder]) + { + return; } + + // NSLog(@"%@ frame %@", self, NSStringFromRect([self frame])); + const float kSeparatorHeight = 1.0f; - NSRect newBounds = newFrame; - newBounds.origin = NSZeroPoint; + NSSize mySize = [self frame].size; + NSSize oldSize = mySize; + + float totalHeightOfSubviews = 0.0f; + // we're not flipped because that freaks out editing in IB. So + // we have to do this in 2 passes; one to resize the subviews, and + // a second to place them (after sizing ourselves). + NSEnumerator* stackViewsEnum = [[self managedSubviews] objectEnumerator]; + NSView* curView; + while ((curView = [stackViewsEnum nextObject])) + { + NSSize subviewFrameSize = [curView frame].size; + + unsigned int autoResizeMask = [curView autoresizingMask]; + if ((autoResizeMask & NSViewWidthSizable) && (subviewFrameSize.width != mySize.width)) + { + subviewFrameSize.width = mySize.width; + mSelfResizing = YES; + [curView setFrameSize:subviewFrameSize]; + mSelfResizing = NO; + + // setting the width may have changed the height, so fetch it again + subviewFrameSize = [curView frame].size; + } + + totalHeightOfSubviews += subviewFrameSize.height; + + if (mShowsSeparators && mDataSource) + totalHeightOfSubviews += kSeparatorHeight; + } + + // resize self now + mySize.height = totalHeightOfSubviews; - [self setFrame:newFrame]; + mSelfResizing = YES; + [self setFrameSizeMaintainingTopLeftOrigin:mySize]; + mSelfResizing = NO; [self setNeedsDisplay:YES]; - [[NSNotificationCenter defaultCenter] postNotificationName:StackViewResizedNotificationName + // now place the subviews + if (mDataSource) + [self removeAllSubviews]; // should we keep a copy of the array to make sure they survive? + + float curMaxY = totalHeightOfSubviews; + + stackViewsEnum = [[self managedSubviews] objectEnumerator]; + while ((curView = [stackViewsEnum nextObject])) + { + NSRect subviewFrame = [curView frame]; + + curMaxY -= NSHeight(subviewFrame); + subviewFrame.origin.y = curMaxY; + + mSelfResizing = YES; + [curView setFrameOrigin:subviewFrame.origin]; + mSelfResizing = NO; + + if (mDataSource) + [self addSubview:curView]; + + if (mShowsSeparators && mDataSource) + { + curMaxY -= kSeparatorHeight; + + NSBox* separator = [[NSBox alloc] initWithFrame: + NSMakeRect(subviewFrame.origin.x, curMaxY, NSWidth(subviewFrame), kSeparatorHeight)]; + [separator setBoxType:NSBoxSeparator]; + [separator setAutoresizingMask:NSViewWidthSizable]; + [self addSubview:separator]; + [separator release]; + } + } + + [[NSNotificationCenter defaultCenter] postNotificationName:kStackViewResizedNotificationName object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithSize:oldSize], @"oldsize", nil]]; } +- (BOOL)showsSeparators +{ + return mShowsSeparators; +} + +- (void)setShowsSeparators:(BOOL)inShowSeparators +{ + mShowsSeparators = inShowSeparators; +} + -(BOOL)isFlipped { - return YES; + // not flipped because that IB freaks out when editing if it is + // (so the math is harder in -adaptToSubviews. oh well). + return NO; +} + +- (NSArray*)managedSubviews +{ + if (mDataSource) + return [mDataSource subviewsForStackView:self]; + + return [self subviews]; } @end diff --git a/mozilla/camino/src/extensions/NSView+Utils.h b/mozilla/camino/src/extensions/NSView+Utils.h index 9446d10d952..94088dd7190 100644 --- a/mozilla/camino/src/extensions/NSView+Utils.h +++ b/mozilla/camino/src/extensions/NSView+Utils.h @@ -67,4 +67,12 @@ BOOL CHCloseSizes(NSSize aSize, NSSize bSize, float slop); - (void)removeAllSubviews; +// is 'inView' an immediate subview of the receiver +- (BOOL)hasSubview:(NSView*)inView; + +- (void)setFrameSizeMaintainingTopLeftOrigin:(NSSize)inNewSize; + +// convert inRect to view coords depending on whether the view is flipped +- (NSRect)subviewRectFromTopRelativeRect:(NSRect)inRect; + @end diff --git a/mozilla/camino/src/extensions/NSView+Utils.m b/mozilla/camino/src/extensions/NSView+Utils.m index a93b8287ba3..eaeef06016f 100644 --- a/mozilla/camino/src/extensions/NSView+Utils.m +++ b/mozilla/camino/src/extensions/NSView+Utils.m @@ -191,4 +191,33 @@ static void RedistributeSpace(int resizeMask, float newWidth, /* in out */ float [subviewsArray release]; } +- (BOOL)hasSubview:(NSView*)inView +{ + return [[self subviews] containsObject:inView]; +} + +- (void)setFrameSizeMaintainingTopLeftOrigin:(NSSize)inNewSize +{ + if ([[self superview] isFlipped]) + [self setFrameSize:inNewSize]; + else + { + NSRect newFrame = [self frame]; + newFrame.origin.y -= (inNewSize.height - newFrame.size.height); + newFrame.size = inNewSize; + [self setFrame:newFrame]; + } +} + +- (NSRect)subviewRectFromTopRelativeRect:(NSRect)inRect +{ + if ([self isFlipped]) + return inRect; + + NSRect theRect = inRect; + theRect.origin.y = NSHeight([self bounds]) - NSMaxY(inRect); + return theRect; +} + + @end diff --git a/mozilla/camino/src/extensions/TruncatingTextFieldCell.h b/mozilla/camino/src/extensions/TruncatingTextFieldCell.h new file mode 100644 index 00000000000..0114f080b72 --- /dev/null +++ b/mozilla/camino/src/extensions/TruncatingTextFieldCell.h @@ -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 + * + * 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 + +#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 diff --git a/mozilla/camino/src/extensions/TruncatingTextFieldCell.mm b/mozilla/camino/src/extensions/TruncatingTextFieldCell.mm new file mode 100644 index 00000000000..61058ecf5f8 --- /dev/null +++ b/mozilla/camino/src/extensions/TruncatingTextFieldCell.mm @@ -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 + * + * 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 + diff --git a/mozilla/camino/src/security/CertificateView.h b/mozilla/camino/src/security/CertificateView.h index dd5b417d4bf..0dd64aa469b 100644 --- a/mozilla/camino/src/security/CertificateView.h +++ b/mozilla/camino/src/security/CertificateView.h @@ -37,13 +37,18 @@ * ***** END LICENSE BLOCK ***** */ #import +#import "CHStackView.h" @class CertificateItem; // this is a view that builds its contents dynamically from the cert. -@interface CertificateView : NSView +@interface CertificateView : CHShrinkWrapView { - NSView* mContentView; // created dynamically, retained + CHStackView* mContentView; // created dynamically, retained + + NSView* mTrustItemsView; // weak + NSView* mDetailsItemsView; // weak + BOOL mDetailsExpanded; BOOL mTrustExpanded; diff --git a/mozilla/camino/src/security/CertificateView.mm b/mozilla/camino/src/security/CertificateView.mm index bc48852cbb9..bbc2d608593 100644 --- a/mozilla/camino/src/security/CertificateView.mm +++ b/mozilla/camino/src/security/CertificateView.mm @@ -50,35 +50,20 @@ #import "nsServiceManagerUtils.h" +#import "AutoSizingTextField.h" + +#import "CHStackView.h" #import "CertificateItem.h" #import "CertificateView.h" -#pragma mark CertificateContentsView -#pragma mark - - -@interface CertificateContentsView : NSView -{ -} -@end - -@implementation CertificateContentsView - -- (BOOL)isFlipped -{ - return YES; -} - -@end - -#pragma mark - - const float kCertImageViewSize = 64.0f; const float kCertHeaderFieldVerticalGap = 4.0f; const float kCertHeaderFieldRightGap = 4.0f; const float kStatusImageSize = 12.0f; const float kGroupHeaderLeftOffset = 4.0f; +const float kGapAboveGroup = 2.0f; const float kGapUnderGroupHeader = 5.0f; const float kDisclosureLabelGap = 4.0f; @@ -87,12 +72,14 @@ const float kDisclosureButtonSize = 12.0f; const float kGeneralRightGap = 4.0f; const float kHeaderLeftOffset = 16.0f; -const float kGapUnderHeader = 5.0f; +const float kGapAboveHeader = 2.0f; +const float kGapUnderHeader = 3.0f; const float kGapUnderGroup = 5.0f; const float kLabelLeftOffset = 16.0f; const float kLabelGutterWidth = 10.0f; -const float kGapUnderLine = 5.0f; +const float kGapUnderLine = 5.0f; +const float kGapUnderCheckboxLine = 3.0f; #pragma mark - #pragma mark CertificateView @@ -102,20 +89,25 @@ const float kGapUnderLine = 5.0f; - (float)labelColumnWidth; -- (NSTextField*)textFieldWithInitialFrame:(NSRect)inFrame stringValue:(NSString*)inString small:(BOOL)useSmallFont bold:(BOOL)useBold; +- (CHShrinkWrapView*)containerViewWithTopPadding:(float)inTop bottomPadding:(float)inBottom; +- (NSTextField*)textFieldWithInitialFrame:(NSRect)inFrame stringValue:(NSString*)inString autoSizing:(BOOL)inAutosize small:(BOOL)useSmallFont bold:(BOOL)useBold; -- (void)addGroupingWithKey:(NSString*)inLabelKey expanded:(BOOL)inExpanded action:(SEL)inAction atOffset:(float*)ioOffset; -- (void)addHeaderWithKey:(NSString*)inLabelKey atOffset:(float*)ioOffset; -- (void)addLineWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData atOffset:(float*)ioOffset ignoreBlankLines:(BOOL)inIgnoreBlank; -- (void)addScrollingTextFieldWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData atOffset:(float*)ioOffset ignoreBlankLines:(BOOL)inIgnoreBlank; -- (NSButton*)addButtonLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction atOffset:(float*)ioOffset; -- (NSButton*)addCheckboxLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction atOffset:(float*)ioOffset; +- (CHStackView *)groupingWithKey:(NSString*)inLabelKey expanded:(BOOL)inExpanded action:(SEL)inAction; +- (NSView*)headerWithKey:(NSString*)inLabelKey; +- (NSTextField*)addLineLabelWithKey:(NSString*)inLabelKey toView:(NSView*)inLineContainerView; +- (NSView*)wholeLineLabelWithKey:(NSString*)inLabelKey; +- (NSView*)lineWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData ignoreBlankLines:(BOOL)inIgnoreBlank; +- (NSView*)scrollingTextFieldWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData ignoreBlankLines:(BOOL)inIgnoreBlank; +- (NSView*)buttonLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction button:(NSButton**)outButton; +- (NSView*)checkboxLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction button:(NSButton**)outButton; - (void)refreshView; -- (float)rebuildCertHeader; +- (void)rebuildCertHeader; - (void)rebuildCertContent; -- (float)rebuildDetails:(float)inOffset; -- (float)rebuildTrustSettings:(float)inOffset; + +- (void)rebuildDetails; +- (void)rebuildTrustSettings; + - (BOOL)showTrustSettings; - (IBAction)trustCheckboxClicked:(id)inSender; @@ -290,13 +282,83 @@ const float kGapUnderLine = 5.0f; - (float)labelColumnWidth { - // measure all the label strings? - return 120.0f; + static BOOL sGotWidth = NO; + static float sLongestLabelWidth = 0.0f; + + if (!sGotWidth) + { + NSArray* labelKeys = [NSArray arrayWithObjects: + @"IssuedTo", + @"OwnerCommonName", + @"OwnerEmailAddress", + @"OwnerOrganization", + @"OwnerOrgUnit", + @"Version", + @"SerialNumber", + @"IssuedBy", + @"IssuerCommonName", + @"IssuerOrganization", + @"IssuerOrgUnit", + @"ShowIssuerCertLabel", + @"Validity", + @"NotBeforeLocalTime", + @"NotAfterLocalTime", + @"SigAlgorithm", + @"Signature", + @"PublicKeyInfo", + @"PublicKeyAlgorithm", + @"PublicKey", + @"UsagesTitle", + @"Usages", + @"Fingerprints", + @"SHA1Fingerprint", + @"MD5Fingerprint", + nil]; + + float maxWidth = 0.0f; + NSDictionary* fontAttributes = [NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]] + forKey:NSFontAttributeName]; + NSEnumerator* keysEnum = [labelKeys objectEnumerator]; + NSString* curKey; + while ((curKey = [keysEnum nextObject])) + { + NSString* theLabel = NSLocalizedStringFromTable(curKey, @"CertificateDialogs", @""); + NSSize stringSize = [theLabel sizeWithAttributes:fontAttributes]; + if (stringSize.width > maxWidth) + maxWidth = stringSize.width; + } + + if (maxWidth < 120.0f) + maxWidth = 120.0f; + + sLongestLabelWidth = maxWidth; + sGotWidth = YES; + } + + return sLongestLabelWidth; } -- (NSTextField*)textFieldWithInitialFrame:(NSRect)inFrame stringValue:(NSString*)inString small:(BOOL)useSmallFont bold:(BOOL)useBold +- (CHShrinkWrapView*)containerViewWithTopPadding:(float)inTop bottomPadding:(float)inBottom { - NSTextField* theTextField = [[[NSTextField alloc] initWithFrame:inFrame] autorelease]; + // the origin of the rect doesn't matter, and we'll resize the height later + NSRect headerRect = NSMakeRect(0, 0, NSWidth([self frame]), NSHeight([self frame])); + CHShrinkWrapView* containerView = [[[CHShrinkWrapView alloc] initWithFrame:headerRect] autorelease]; + [containerView setIntrinsicPadding:kGroupHeaderLeftOffset forEdge:NSMinXEdge]; + [containerView setIntrinsicPadding:inBottom forEdge:NSMinYEdge]; + [containerView setIntrinsicPadding:kGroupHeaderLeftOffset forEdge:NSMaxXEdge]; + [containerView setIntrinsicPadding:inTop forEdge:NSMaxYEdge]; + [containerView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; + return containerView; +} + +- (NSTextField*)textFieldWithInitialFrame:(NSRect)inFrame stringValue:(NSString*)inString autoSizing:(BOOL)inAutosize small:(BOOL)useSmallFont bold:(BOOL)useBold +{ + NSTextField* theTextField; + if (inAutosize) + theTextField = [[[AutoSizingTextField alloc] initWithFrame:inFrame] autorelease]; + else + theTextField = [[[NSTextField alloc] initWithFrame:inFrame] autorelease]; + [theTextField setEditable:NO]; [theTextField setSelectable:YES]; NSFont* fieldFont; @@ -310,210 +372,241 @@ const float kGapUnderLine = 5.0f; [theTextField setDrawsBackground:NO]; [theTextField setBezeled:NO]; [theTextField setStringValue:inString ? inString : @""]; - [[theTextField cell] setWraps:NO]; + [[theTextField cell] setWraps:inAutosize]; + [theTextField setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; NSSize theCellSize = [[theTextField cell] cellSizeForBounds:inFrame]; theCellSize.width = NSWidth(inFrame); // keep the provided width - [theTextField setFrameSize:theCellSize]; - //[theTextField sizeToFit]; + [theTextField setFrameSizeMaintainingTopLeftOrigin:theCellSize]; return theTextField; } -- (void)addGroupingWithKey:(NSString*)inLabelKey expanded:(BOOL)inExpanded action:(SEL)inAction atOffset:(float*)ioOffset +- (CHStackView *)groupingWithKey:(NSString*)inLabelKey expanded:(BOOL)inExpanded action:(SEL)inAction { - NSRect lineRect = NSMakeRect(kGroupHeaderLeftOffset, *ioOffset + kGroupHeaderLeftOffset, NSWidth([self frame]) - 2 * kGroupHeaderLeftOffset, 100.0f); + NSRect stackFrame = [self bounds]; + + CHStackView* groupContainer = [[[CHStackView alloc] initWithFrame:stackFrame] autorelease]; + [groupContainer setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; + + NSView* lineContainer = [self containerViewWithTopPadding:kGapAboveGroup bottomPadding:kGapUnderGroupHeader]; - NSRect buttonRect; + NSRect lineRect = NSMakeRect(kGroupHeaderLeftOffset, 0.0f, NSWidth([self frame]) - 2 * kGroupHeaderLeftOffset, 100.0f); + + NSRect buttonRect = NSMakeRect(0, 0, kDisclosureButtonSize, kDisclosureButtonSize); buttonRect.origin = lineRect.origin; buttonRect.size = NSMakeSize(kDisclosureButtonSize, kDisclosureButtonSize); - NSButton* theButton = [[[NSButton alloc] initWithFrame:buttonRect] autorelease]; + NSButton* theButton = [[[NSButton alloc] initWithFrame:[groupContainer subviewRectFromTopRelativeRect:buttonRect]] autorelease]; [theButton setBordered:NO]; [theButton setImage: inExpanded ? [NSImage imageNamed:@"triangle_down_normal"] : [NSImage imageNamed:@"triangle_right_normal"]]; [theButton setAlternateImage:inExpanded ? [NSImage imageNamed:@"triangle_down_pressed"] : [NSImage imageNamed:@"triangle_right_pressed"]]; [theButton setButtonType:NSMomentaryChangeButton]; [theButton setAction:inAction]; [theButton setTarget:self]; - [mContentView addSubview:theButton]; + [theButton setAutoresizingMask:NSViewMinYMargin]; + [lineContainer addSubview:theButton]; lineRect.origin.x = NSMaxX(buttonRect) + kDisclosureLabelGap; NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @""); - NSTextField* headerField = [self textFieldWithInitialFrame:lineRect stringValue:theLabel small:YES bold:YES]; - [mContentView addSubview:headerField]; + NSTextField* headerField = [self textFieldWithInitialFrame:[groupContainer subviewRectFromTopRelativeRect:lineRect] stringValue:theLabel autoSizing:NO small:YES bold:YES]; + [lineContainer addSubview:headerField]; - float buttonBottom = NSMaxY([theButton frame]); - float labelBottom = NSMaxY([headerField frame]); - float maxYPos = (buttonBottom > labelBottom) ? buttonBottom : labelBottom; - - *ioOffset = maxYPos + kGapUnderGroupHeader; + [groupContainer addSubview:lineContainer]; + return groupContainer; } -- (void)addHeaderWithKey:(NSString*)inLabelKey atOffset:(float*)ioOffset +- (NSView*)headerWithKey:(NSString*)inLabelKey { + NSView* headerContainer = [self containerViewWithTopPadding:kGapAboveHeader bottomPadding:kGapUnderHeader]; + float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap; - NSRect headerRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f); + NSRect headerRect = NSMakeRect(labelOffset, 0.0f, [self labelColumnWidth], 100.0f); NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @""); - NSTextField* headerField = [self textFieldWithInitialFrame:headerRect stringValue:theLabel small:YES bold:YES]; - [mContentView addSubview:headerField]; + NSTextField* headerField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:headerRect] stringValue:theLabel autoSizing:NO small:YES bold:YES]; + [headerField setAlignment:NSRightTextAlignment]; + [headerField setTextColor:[NSColor lightGrayColor]]; + [headerField setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; + [headerContainer addSubview:headerField]; - *ioOffset = NSMaxY([headerField frame]) + kGapUnderHeader; + NSFont* labelFont = [[headerField cell] font]; + float baselineOffset = [labelFont ascender]; + + float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth; + NSRect boxFrame = NSMakeRect(xPos, baselineOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 2.0f); + + NSBox* lineBox = [[[NSBox alloc] initWithFrame:[headerContainer subviewRectFromTopRelativeRect:boxFrame]] autorelease]; + [lineBox setBoxType:NSBoxSeparator]; + [lineBox setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; + [headerContainer addSubview:lineBox]; + + return headerContainer; } -// returns current V offset -- (void)addLineWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData atOffset:(float*)ioOffset ignoreBlankLines:(BOOL)inIgnoreBlank +- (NSTextField*)addLineLabelWithKey:(NSString*)inLabelKey toView:(NSView*)inLineContainerView +{ + float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap; + NSRect labelRect = NSMakeRect(labelOffset, 0.0f, [self labelColumnWidth], 100.0f); + + NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @""); + NSTextField* labelField = [self textFieldWithInitialFrame:[inLineContainerView subviewRectFromTopRelativeRect:labelRect] stringValue:theLabel autoSizing:NO small:YES bold:NO]; + [labelField setAlignment:NSRightTextAlignment]; + [labelField setTextColor:[NSColor darkGrayColor]]; + [labelField setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; + [inLineContainerView addSubview:labelField]; + return labelField; +} + +- (NSView*)wholeLineLabelWithKey:(NSString*)inLabelKey +{ + NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderLine]; + + float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap; + NSRect labelRect = NSMakeRect(labelOffset, 0.0f, NSWidth([self frame]) - labelOffset, 100.0f); + + NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @""); + NSTextField* labelField = [self textFieldWithInitialFrame:[lineContainer subviewRectFromTopRelativeRect:labelRect] stringValue:theLabel autoSizing:YES small:YES bold:NO]; + [lineContainer addSubview:labelField]; + return lineContainer; +} + +- (NSView*)lineWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData ignoreBlankLines:(BOOL)inIgnoreBlank { if (inIgnoreBlank && [inData length] == 0) - return; - - float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap; - NSRect labelRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f); - - NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @""); - NSTextField* labelField = [self textFieldWithInitialFrame:labelRect stringValue:theLabel small:YES bold:NO]; - [mContentView addSubview:labelField]; + return nil; + + NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderLine]; + [self addLineLabelWithKey:inLabelKey toView:lineContainer]; float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth; - NSRect dataRect = NSMakeRect(xPos, *ioOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f); - NSTextField* dataField = [self textFieldWithInitialFrame:dataRect stringValue:inData small:YES bold:NO]; - [dataField setAutoresizingMask:NSViewWidthSizable | NSViewMaxYMargin]; - [mContentView addSubview:dataField]; - - float labelBottom = NSMaxY([labelField frame]); - float dataBottom = NSMaxY([dataField frame]); - float maxYPos = (dataBottom > labelBottom) ? dataBottom : labelBottom; - - *ioOffset = maxYPos + kGapUnderLine; + NSRect dataRect = NSMakeRect(xPos, 0.0f, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f); + NSTextField* dataField = [self textFieldWithInitialFrame:[lineContainer subviewRectFromTopRelativeRect:dataRect] stringValue:inData autoSizing:YES small:YES bold:NO]; + [lineContainer addSubview:dataField]; + return lineContainer; } -- (void)addScrollingTextFieldWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData atOffset:(float*)ioOffset ignoreBlankLines:(BOOL)inIgnoreBlank +- (NSView*)scrollingTextFieldWithLabelKey:(NSString*)inLabelKey data:(NSString*)inData ignoreBlankLines:(BOOL)inIgnoreBlank { if (inIgnoreBlank && [inData length] == 0) - return; + return nil; - float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap; - NSRect labelRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f); - - NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @""); - NSTextField* labelField = [self textFieldWithInitialFrame:labelRect stringValue:theLabel small:YES bold:NO]; - [mContentView addSubview:labelField]; + NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderLine]; + [self addLineLabelWithKey:inLabelKey toView:lineContainer]; float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth; - NSRect dataRect = NSMakeRect(xPos, *ioOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 56.0f); - + NSRect dataRect = NSMakeRect(xPos, 0.0f, NSWidth([self frame]) - xPos - kLabelLeftOffset, 56.0f); + dataRect = [lineContainer subviewRectFromTopRelativeRect:dataRect]; + NSScrollView* dataScrollView = [[[NSScrollView alloc] initWithFrame:dataRect] autorelease]; NSTextView* scrolledTextView = [[[NSTextView alloc] initWithFrame:dataRect] autorelease]; [dataScrollView setHasVerticalScroller:YES]; [dataScrollView setBorderType:NSBezelBorder]; - [dataScrollView setAutoresizingMask:NSViewWidthSizable | NSViewMaxYMargin]; + [dataScrollView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; [[dataScrollView verticalScroller] setControlSize:NSSmallControlSize]; if (inData) [[[scrolledTextView textStorage] mutableString] setString:[inData stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]]; [scrolledTextView setFont:[NSFont fontWithName:@"Monaco" size:10.0f]]; [scrolledTextView setEditable:NO]; - [dataScrollView setAutoresizingMask:NSViewWidthSizable]; [dataScrollView setDocumentView:scrolledTextView]; - [mContentView addSubview:dataScrollView]; - - float labelBottom = NSMaxY([labelField frame]); - float dataBottom = NSMaxY([dataScrollView frame]); - float maxYPos = (dataBottom > labelBottom) ? dataBottom : labelBottom; - - *ioOffset = maxYPos + kGapUnderLine; + [lineContainer addSubview:dataScrollView]; + return lineContainer; } -- (NSButton*)addButtonLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction atOffset:(float*)ioOffset +- (NSView*)buttonLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction button:(NSButton**)outButton { - float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap; - NSRect labelRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f); - - NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @""); - NSTextField* labelField = [self textFieldWithInitialFrame:labelRect stringValue:theLabel small:YES bold:NO]; - [mContentView addSubview:labelField]; + NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderLine]; + [self addLineLabelWithKey:inLabelKey toView:lineContainer]; float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth; - NSRect buttonRect = NSMakeRect(xPos, *ioOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f); - NSButton* theButton = [[[NSButton alloc] initWithFrame:buttonRect] autorelease]; + NSRect buttonRect = NSMakeRect(xPos, 0.0f, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f); + NSButton* theButton = [[[NSButton alloc] initWithFrame:[lineContainer subviewRectFromTopRelativeRect:buttonRect]] autorelease]; [theButton setTitle:NSLocalizedStringFromTable(buttonKey, @"CertificateDialogs", @"")]; [theButton setBezelStyle:NSRoundedBezelStyle]; [theButton setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; [[theButton cell] setControlSize:NSSmallControlSize]; - [theButton sizeToFit]; + //[theButton sizeToFit]; + NSSize theCellSize = [[theButton cell] cellSizeForBounds:[theButton frame]]; + [theButton setFrameSizeMaintainingTopLeftOrigin:theCellSize]; + + [theButton setAutoresizingMask:NSViewMinYMargin]; + [theButton setAction:inAction]; [theButton setTarget:self]; - [mContentView addSubview:theButton]; + [lineContainer addSubview:theButton]; - float labelBottom = NSMaxY([labelField frame]); - float buttonBottom = NSMaxY([theButton frame]); - float maxYPos = (buttonBottom > labelBottom) ? buttonBottom : labelBottom; - - *ioOffset = maxYPos + kGapUnderLine; - return theButton; + if (outButton) + *outButton = theButton; + + return lineContainer; } -- (NSButton*)addCheckboxLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction atOffset:(float*)ioOffset +- (NSView*)checkboxLineWithLabelKey:(NSString*)inLabelKey buttonLabelKey:(NSString*)buttonKey action:(SEL)inAction button:(NSButton**)outButton { - float labelOffset = kGroupHeaderLeftOffset + kDisclosureButtonSize + kDisclosureLabelGap; - NSRect labelRect = NSMakeRect(labelOffset, *ioOffset, NSWidth([self frame]) - labelOffset - kGeneralRightGap, 100.0f); - - NSString* theLabel = NSLocalizedStringFromTable(inLabelKey, @"CertificateDialogs", @""); - NSTextField* labelField = [self textFieldWithInitialFrame:labelRect stringValue:theLabel small:YES bold:NO]; - [mContentView addSubview:labelField]; + NSView* lineContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderCheckboxLine]; + + if ([inLabelKey length] > 0) + [self addLineLabelWithKey:inLabelKey toView:lineContainer]; float xPos = kLabelLeftOffset + [self labelColumnWidth] + kLabelGutterWidth; - NSRect buttonRect = NSMakeRect(xPos, *ioOffset, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f); - NSButton* theButton = [[[NSButton alloc] initWithFrame:buttonRect] autorelease]; + NSRect buttonRect = NSMakeRect(xPos, 0.0f, NSWidth([self frame]) - xPos - kLabelLeftOffset, 100.0f); + NSButton* theButton = [[[NSButton alloc] initWithFrame:[lineContainer subviewRectFromTopRelativeRect:buttonRect]] autorelease]; [theButton setTitle:NSLocalizedStringFromTable(buttonKey, @"CertificateDialogs", @"")]; [theButton setButtonType:NSSwitchButton]; [theButton setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; [[theButton cell] setControlSize:NSSmallControlSize]; - [theButton sizeToFit]; - [theButton setAutoresizingMask:NSViewWidthSizable | NSViewMaxYMargin]; + // resize maintaining the width + NSRect wideButtonRect = buttonRect; + wideButtonRect.size.width = 1000.0f; // if the width is narrow, -cellSizeForBounds: returns a greater height, which we don't want. + NSSize theCellSize = [[theButton cell] cellSizeForBounds:wideButtonRect]; + theCellSize.width = NSWidth(buttonRect); + [theButton setFrameSizeMaintainingTopLeftOrigin:theCellSize]; + + [theButton setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; [theButton setAction:inAction]; [theButton setTarget:self]; - [mContentView addSubview:theButton]; + [lineContainer addSubview:theButton]; - float labelBottom = NSMaxY([labelField frame]); - float buttonBottom = NSMaxY([theButton frame]); - float maxYPos = (buttonBottom > labelBottom) ? buttonBottom : labelBottom; - - *ioOffset = maxYPos + kGapUnderLine; - return theButton; + if (outButton) + *outButton = theButton; + + return lineContainer; } -- (float)rebuildDetails:(float)inOffset +- (void)rebuildDetails { - float curOffset = inOffset; - [self addGroupingWithKey:@"CertDetailsGroupHeader" expanded:mDetailsExpanded action:@selector(toggleDetails:) atOffset:&curOffset]; - curOffset += kGapUnderHeader; + mDetailsItemsView = [self groupingWithKey:@"CertDetailsGroupHeader" expanded:mDetailsExpanded action:@selector(toggleDetails:)]; + [mContentView addSubview:mDetailsItemsView]; if (!mDetailsExpanded) - return curOffset; - - [self addHeaderWithKey:@"IssuedTo" atOffset:&curOffset]; + return; + + // + // NOTE: add label string keys to the array in -labelColumnWidth if you add new ones. + // + [mDetailsItemsView addSubview:[self headerWithKey:@"IssuedTo"]]; // Owner stuff - [self addLineWithLabelKey:@"OwnerCommonName" data:[mCertItem commonName] atOffset:&curOffset ignoreBlankLines:YES]; - [self addLineWithLabelKey:@"OwnerEmailAddress" data:[mCertItem emailAddress] atOffset:&curOffset ignoreBlankLines:YES]; - [self addLineWithLabelKey:@"OwnerOrganization" data:[mCertItem organization] atOffset:&curOffset ignoreBlankLines:YES]; - [self addLineWithLabelKey:@"OwnerOrgUnit" data:[mCertItem organizationalUnit] atOffset:&curOffset ignoreBlankLines:YES]; - [self addLineWithLabelKey:@"Version" data:[mCertItem version] atOffset:&curOffset ignoreBlankLines:YES]; - [self addLineWithLabelKey:@"SerialNumber" data:[mCertItem serialNumber] atOffset:&curOffset ignoreBlankLines:YES]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"OwnerCommonName" data:[mCertItem commonName] ignoreBlankLines:YES]]; + + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"OwnerEmailAddress" data:[mCertItem emailAddress] ignoreBlankLines:YES]]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"OwnerOrganization" data:[mCertItem organization] ignoreBlankLines:YES]]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"OwnerOrgUnit" data:[mCertItem organizationalUnit] ignoreBlankLines:YES]]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"Version" data:[mCertItem version] ignoreBlankLines:YES]]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"SerialNumber" data:[mCertItem serialNumber] ignoreBlankLines:YES]]; // Issuer stuff - curOffset += kGapUnderGroup; - [self addHeaderWithKey:@"IssuedBy" atOffset:&curOffset]; + [mDetailsItemsView addSubview:[self headerWithKey:@"IssuedBy"]]; - [self addLineWithLabelKey:@"IssuerCommonName" data:[mCertItem issuerCommonName] atOffset:&curOffset ignoreBlankLines:YES]; - [self addLineWithLabelKey:@"IssuerOrganization" data:[mCertItem issuerOrganization] atOffset:&curOffset ignoreBlankLines:YES]; - [self addLineWithLabelKey:@"IssuerOrgUnit" data:[mCertItem issuerOrganizationalUnit] atOffset:&curOffset ignoreBlankLines:YES]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"IssuerCommonName" data:[mCertItem issuerCommonName] ignoreBlankLines:YES]]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"IssuerOrganization" data:[mCertItem issuerOrganization] ignoreBlankLines:YES]]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"IssuerOrgUnit" data:[mCertItem issuerOrganizationalUnit] ignoreBlankLines:YES]]; nsCOMPtr issuerCert; nsIX509Cert* thisCert = [mCertItem cert]; @@ -521,93 +614,83 @@ const float kGapUnderLine = 5.0f; thisCert->GetIssuer(getter_AddRefs(issuerCert)); if (issuerCert && ![mCertItem isSameCertAs:issuerCert]) { - [self addButtonLineWithLabelKey:@"ShowIssuerCertLabel" - buttonLabelKey:@"ShowIssuerCertButton" - action:@selector(showIssuerCert:) - atOffset:&curOffset]; + [mDetailsItemsView addSubview:[self buttonLineWithLabelKey:@"ShowIssuerCertLabel" + buttonLabelKey:@"ShowIssuerCertButton" + action:@selector(showIssuerCert:) + button:NULL]]; } // validity - curOffset += kGapUnderGroup; - [self addHeaderWithKey:@"Validity" atOffset:&curOffset]; + [mDetailsItemsView addSubview:[self headerWithKey:@"Validity"]]; - [self addLineWithLabelKey:@"NotBeforeLocalTime" data:[mCertItem longValidFromString] atOffset:&curOffset ignoreBlankLines:NO]; - [self addLineWithLabelKey:@"NotAfterLocalTime" data:[mCertItem longExpiresString] atOffset:&curOffset ignoreBlankLines:NO]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"NotBeforeLocalTime" data:[mCertItem longValidFromString] ignoreBlankLines:NO]]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"NotAfterLocalTime" data:[mCertItem longExpiresString] ignoreBlankLines:NO]]; // signature - [self addLineWithLabelKey:@"SigAlgorithm" data:[mCertItem signatureAlgorithm] atOffset:&curOffset ignoreBlankLines:NO]; - [self addScrollingTextFieldWithLabelKey:@"Signature" data:[mCertItem signatureValue] atOffset:&curOffset ignoreBlankLines:NO]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"SigAlgorithm" data:[mCertItem signatureAlgorithm] ignoreBlankLines:NO]]; + [mDetailsItemsView addSubview:[self scrollingTextFieldWithLabelKey:@"Signature" data:[mCertItem signatureValue] ignoreBlankLines:NO]]; // public key info - curOffset += kGapUnderGroup; - [self addHeaderWithKey:@"PublicKeyInfo" atOffset:&curOffset]; - [self addLineWithLabelKey:@"PublicKeyAlgorithm" data:[mCertItem publicKeyAlgorithm] atOffset:&curOffset ignoreBlankLines:NO]; - //[self addLineWithLabelKey:@"PublicKeySize" data:[mCertItem publicKeySizeBits] atOffset:&curOffset ignoreBlankLines:NO]; - [self addScrollingTextFieldWithLabelKey:@"PublicKey" data:[mCertItem publicKey] atOffset:&curOffset ignoreBlankLines:NO]; + [mDetailsItemsView addSubview:[self headerWithKey:@"PublicKeyInfo"]]; + + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"PublicKeyAlgorithm" data:[mCertItem publicKeyAlgorithm] ignoreBlankLines:NO]]; + //[self lineWithLabelKey:@"PublicKeySize" data:[mCertItem publicKeySizeBits] ignoreBlankLines:NO]; + [mDetailsItemsView addSubview:[self scrollingTextFieldWithLabelKey:@"PublicKey" data:[mCertItem publicKey] ignoreBlankLines:NO]]; // usages NSArray* certUsages = [mCertItem validUsages]; if ([certUsages count]) { - curOffset += kGapUnderGroup; - [self addHeaderWithKey:@"UsagesTitle" atOffset:&curOffset]; + [mDetailsItemsView addSubview:[self headerWithKey:@"UsagesTitle"]]; for (unsigned int i = 0; i < [certUsages count]; i ++) { NSString* labelKey = (i == 0) ? @"Usages" : @""; - [self addLineWithLabelKey:labelKey data:[certUsages objectAtIndex:i] atOffset:&curOffset ignoreBlankLines:NO]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:labelKey data:[certUsages objectAtIndex:i] ignoreBlankLines:NO]]; } } // fingerprints - curOffset += kGapUnderGroup; - [self addHeaderWithKey:@"Fingerprints" atOffset:&curOffset]; + [mDetailsItemsView addSubview:[self headerWithKey:@"Fingerprints"]]; - [self addLineWithLabelKey:@"SHA1Fingerprint" data:[mCertItem sha1Fingerprint] atOffset:&curOffset ignoreBlankLines:NO]; - [self addLineWithLabelKey:@"MD5Fingerprint" data:[mCertItem md5Fingerprint] atOffset:&curOffset ignoreBlankLines:NO]; - - curOffset += kGapUnderGroup; - return curOffset; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"SHA1Fingerprint" data:[mCertItem sha1Fingerprint] ignoreBlankLines:NO]]; + [mDetailsItemsView addSubview:[self lineWithLabelKey:@"MD5Fingerprint" data:[mCertItem md5Fingerprint] ignoreBlankLines:NO]]; } -- (float)rebuildTrustSettings:(float)inOffset +- (void)rebuildTrustSettings { - float curOffset = inOffset; - - [self addGroupingWithKey:@"CertTrustGroupHeader" expanded:mTrustExpanded action:@selector(toggleTrustSettings:) atOffset:&curOffset]; - curOffset += kGapUnderHeader; + mTrustItemsView = [self groupingWithKey:@"CertTrustGroupHeader" expanded:mTrustExpanded action:@selector(toggleTrustSettings:)]; + [mContentView addSubview:mTrustItemsView]; if (!mTrustExpanded) - return curOffset; + return; // XXX do we need a more comprehensive check than this? BOOL enableCheckboxes = YES; // [mCertItem isValid] || [mCertItem isUntrustedRootCACert]; // XXX only show relevant checkboxes? (see nsNSSCertificateDB::SetCertTrust) // XXX only show checkboxes for allowed usages? - [self addLineWithLabelKey:@"TrustSettingsLabel" data:@"" atOffset:&curOffset ignoreBlankLines:NO]; - mTrustForWebSitesCheckbox = [self addCheckboxLineWithLabelKey:@"" - buttonLabelKey:@"TrustWebSitesCheckboxLabel" - action:@selector(trustCheckboxClicked:) - atOffset:&curOffset]; + [mTrustItemsView addSubview:[self wholeLineLabelWithKey:@"TrustSettingsLabel"]]; + [mTrustItemsView addSubview:[self checkboxLineWithLabelKey:@"" + buttonLabelKey:@"TrustWebSitesCheckboxLabel" + action:@selector(trustCheckboxClicked:) + button:&mTrustForWebSitesCheckbox]]; + [mTrustForWebSitesCheckbox setState:mTrustedForWebSites]; [mTrustForWebSitesCheckbox setEnabled:enableCheckboxes]; - mTrustForEmailCheckbox = [self addCheckboxLineWithLabelKey:@"" + [mTrustItemsView addSubview:[self checkboxLineWithLabelKey:@"" buttonLabelKey:@"TrustEmailUsersCheckboxLabel" action:@selector(trustCheckboxClicked:) - atOffset:&curOffset]; + button:&mTrustForEmailCheckbox]]; [mTrustForEmailCheckbox setState:mTrustedForEmail]; [mTrustForEmailCheckbox setEnabled:enableCheckboxes]; - mTrustForObjSigningCheckbox = [self addCheckboxLineWithLabelKey:@"" - buttonLabelKey:@"TrustObjectSignersCheckboxLabel" - action:@selector(trustCheckboxClicked:) - atOffset:&curOffset]; + [mTrustItemsView addSubview:[self checkboxLineWithLabelKey:@"" + buttonLabelKey:@"TrustObjectSignersCheckboxLabel" + action:@selector(trustCheckboxClicked:) + button:&mTrustForObjSigningCheckbox]]; [mTrustForObjSigningCheckbox setState:mTrustedForObjectSigning]; [mTrustForObjSigningCheckbox setEnabled:enableCheckboxes]; - - curOffset += kGapUnderGroup; - return curOffset; } - (void)refreshView @@ -620,58 +703,63 @@ const float kGapUnderLine = 5.0f; mTrustForEmailCheckbox = nil; mTrustForObjSigningCheckbox = nil; - float headerHeight = [self rebuildCertHeader]; - - NSRect contentFrame = [self bounds]; - NSRect headerRect, contentsRect; - NSDivideRect(contentFrame, &headerRect, &contentsRect, headerHeight, NSMinYEdge); - - mContentView = [[CertificateContentsView alloc] initWithFrame:contentsRect]; + mContentView = [[CHStackView alloc] initWithFrame:[self bounds]]; [mContentView setAutoresizingMask:NSViewWidthSizable | NSViewMaxYMargin]; + + [self setIntrinsicPadding:0.0f forEdge:NSMinXEdge]; + [self setIntrinsicPadding:0.0f forEdge:NSMinYEdge]; + [self setIntrinsicPadding:0.0f forEdge:NSMaxXEdge]; + [self setIntrinsicPadding:0.0f forEdge:NSMaxYEdge]; + [self addSubview:mContentView]; + [self rebuildCertHeader]; [self rebuildCertContent]; } -- (float)rebuildCertHeader +- (void)rebuildCertHeader { // We do all this laborious manual view construction to avoid having to load a nib file each // time. This way, we can just have a single custom view in the nib, and do everything in code. - // cert image - NSRect certImageFrame = NSMakeRect(kGroupHeaderLeftOffset, kGroupHeaderLeftOffset, kCertImageViewSize, kCertImageViewSize); - NSImageView* certImageView = [[[NSImageView alloc] initWithFrame:certImageFrame] autorelease]; - [certImageView setImage:[NSImage imageNamed:@"certificate"]]; - [self addSubview:certImageView]; - - // description + // container for the header float headerFieldsLeftEdge = kGroupHeaderLeftOffset + kCertImageViewSize + kGroupHeaderLeftOffset; float headerFieldYOffset = kGroupHeaderLeftOffset; float headerFieldWith = NSWidth([self frame]) - headerFieldYOffset - kCertHeaderFieldRightGap; + NSView* headerContainer = [self containerViewWithTopPadding:0.0f bottomPadding:kGapUnderGroup]; + + // cert image + NSRect certImageFrame = NSMakeRect(0.0f, 0.0f, kCertImageViewSize, kCertImageViewSize); + NSImageView* certImageView = [[[NSImageView alloc] initWithFrame:[headerContainer subviewRectFromTopRelativeRect:certImageFrame]] autorelease]; + [certImageView setImage:[NSImage imageNamed:@"certificate"]]; + [certImageView setAutoresizingMask:NSViewMinYMargin]; + [headerContainer addSubview:certImageView]; + + // description NSRect decriptionRect = NSMakeRect(headerFieldsLeftEdge, headerFieldYOffset, headerFieldWith, 100.0f); - NSTextField* descField = [self textFieldWithInitialFrame:decriptionRect stringValue:[mCertItem displayName] small:NO bold:NO]; - [self addSubview:descField]; + NSTextField* descField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:decriptionRect] stringValue:[mCertItem displayName] autoSizing:NO small:NO bold:NO]; + [headerContainer addSubview:descField]; headerFieldYOffset += NSHeight([descField frame]) + kCertHeaderFieldVerticalGap; // issuer info NSRect issuerRect = NSMakeRect(headerFieldsLeftEdge, headerFieldYOffset, headerFieldWith, 100.0f); NSString* formatString = NSLocalizedStringFromTable(@"IssuedByHeaderFormat", @"CertificateDialogs", @""); NSString* issuerString = [NSString stringWithFormat:formatString, [mCertItem issuerCommonName]]; - NSTextField* issuerField = [self textFieldWithInitialFrame:issuerRect stringValue:issuerString small:YES bold:NO]; - [self addSubview:issuerField]; + NSTextField* issuerField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:issuerRect] stringValue:issuerString autoSizing:NO small:YES bold:NO]; + [headerContainer addSubview:issuerField]; headerFieldYOffset += NSHeight([issuerField frame]) + kCertHeaderFieldVerticalGap; // expiry info NSRect expiryRect = NSMakeRect(headerFieldsLeftEdge, headerFieldYOffset, headerFieldWith, 100.0f); formatString = NSLocalizedStringFromTable(@"ExpiresHeaderFormat", @"CertificateDialogs", @""); NSString* expiryString = [NSString stringWithFormat:formatString, [mCertItem longExpiresString]]; - NSTextField* expiryField = [self textFieldWithInitialFrame:expiryRect stringValue:expiryString small:YES bold:NO]; - [self addSubview:expiryField]; + NSTextField* expiryField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:expiryRect] stringValue:expiryString autoSizing:NO small:YES bold:NO]; + [headerContainer addSubview:expiryField]; headerFieldYOffset += NSHeight([expiryField frame]) + kCertHeaderFieldVerticalGap; NSRect statusImageRect = NSMakeRect(headerFieldsLeftEdge, headerFieldYOffset, kStatusImageSize, kStatusImageSize); - NSImageView* statusImageView = [[[NSImageView alloc] initWithFrame:statusImageRect] autorelease]; + NSImageView* statusImageView = [[[NSImageView alloc] initWithFrame:[headerContainer subviewRectFromTopRelativeRect:statusImageRect]] autorelease]; NSString* imageName = @""; if ([mCertItem isUntrustedRootCACert]) @@ -682,44 +770,34 @@ const float kGapUnderLine = 5.0f; imageName = @"mini_cert_invalid"; [statusImageView setImage:[NSImage imageNamed:imageName]]; - [self addSubview:statusImageView]; + [statusImageView setAutoresizingMask:NSViewMinYMargin]; + [headerContainer addSubview:statusImageView]; // status info float statusLeftEdge = headerFieldsLeftEdge + kStatusImageSize + kGroupHeaderLeftOffset; float statusFieldWith = NSWidth([self frame]) - statusLeftEdge - kCertHeaderFieldRightGap; NSRect statusRect = NSMakeRect(statusLeftEdge, headerFieldYOffset, statusFieldWith, 100.0f); - NSTextField* statusField = [self textFieldWithInitialFrame:statusRect stringValue:@"" small:YES bold:NO]; + NSTextField* statusField = [self textFieldWithInitialFrame:[headerContainer subviewRectFromTopRelativeRect:statusRect] stringValue:@"" autoSizing:NO small:YES bold:NO]; [statusField setAttributedStringValue:[mCertItem attributedLongValidityString]]; - [statusField sizeToFit]; - [self addSubview:statusField]; + [headerContainer addSubview:statusField]; - headerFieldYOffset += NSHeight([statusField frame]) + kCertHeaderFieldVerticalGap; - return headerFieldYOffset; + [mContentView addSubview:headerContainer]; } - (void)rebuildCertContent { // blow away the subviews of the content view - [mContentView removeAllSubviews]; + [mTrustItemsView removeFromSuperviewWithoutNeedingDisplay]; + mTrustItemsView = nil; + + [mDetailsItemsView removeFromSuperviewWithoutNeedingDisplay]; + mDetailsItemsView = nil; - float curHeight = 0.0f; if ([self showTrustSettings]) - curHeight = [self rebuildTrustSettings:curHeight]; + [self rebuildTrustSettings]; - curHeight = [self rebuildDetails:curHeight]; - - // make sure the details view is big enough to contain all its subviews - NSSize curSize = [mContentView frame].size; - curSize.height = curHeight; - [mContentView setFrameSize:curSize]; - - // and then resize us too - NSRect contentViewFrame = [mContentView frame]; - float myHeight = NSHeight(contentViewFrame) + NSMinY(contentViewFrame); - curSize = [self frame].size; - curSize.height = myHeight; - [self setFrameSize:curSize]; + [self rebuildDetails]; } - (void)certificateChanged:(NSNotification*)inNotification