From cc620cfe7257fdf0caf54c7addced8a136de4865 Mon Sep 17 00:00:00 2001 From: boisso Date: Sat, 8 Mar 2008 15:53:22 +0000 Subject: [PATCH] Bug 966: kmeleon.display.maximized ignored at startup Fix launching kmeleon a second time doesn't open a new window/tab --- CVSROOT/checkoutlist | 13 + CVSROOT/commitinfo | 15 + CVSROOT/config | 11 + CVSROOT/cvswrappers | 23 + CVSROOT/editinfo | 21 + CVSROOT/loginfo | 26 + CVSROOT/modules | 26 + CVSROOT/notify | 12 + CVSROOT/rcsinfo | 13 + CVSROOT/taginfo | 20 + CVSROOT/verifymsg | 21 + k-meleon/About.cpp | 80 + k-meleon/About.h | 40 + k-meleon/AccelParser.cpp | 484 +++ k-meleon/AccelParser.h | 62 + k-meleon/BrowserFrameGlue.cpp | 956 +++++ k-meleon/BrowserFrm.cpp | 1613 ++++++++ k-meleon/BrowserFrm.h | 358 ++ k-meleon/BrowserFrmTab.cpp | 876 +++++ k-meleon/BrowserFrmTab.h | 173 + k-meleon/BrowserGlue.cpp | 434 +++ k-meleon/BrowserImpl.cpp | 847 ++++ k-meleon/BrowserImpl.h | 125 + k-meleon/BrowserImplCtxMenuLstnr.cpp | 88 + k-meleon/BrowserImplWebPrgrsLstnr.cpp | 189 + k-meleon/BrowserView.cpp | 1022 +++++ k-meleon/BrowserView.h | 323 ++ k-meleon/BrowserViewFind.cpp | 220 ++ k-meleon/BrowserViewPanning.cpp | 216 + k-meleon/BrowserViewUtils.cpp | 535 +++ k-meleon/BrowserWindow.cpp | 1797 +++++++++ k-meleon/BrowserWindow.h | 327 ++ k-meleon/CmdLine.cpp | 187 + k-meleon/CmdLine.h | 12 + k-meleon/Components.cpp | 174 + k-meleon/CookiePromptService.cpp | 149 + k-meleon/CookiePromptService.h | 81 + k-meleon/Cookies.h | 88 + k-meleon/CookiesViewerDlg.cpp | 249 ++ k-meleon/CookiesViewerDlg.h | 63 + k-meleon/DialogEx.h | 126 + k-meleon/DialogUtils.cpp | 186 + k-meleon/DialogUtils.h | 39 + k-meleon/Dialogs.cpp | 526 +++ k-meleon/Dialogs.h | 183 + k-meleon/FavIconList.cpp | 835 ++++ k-meleon/FavIconList.h | 85 + k-meleon/FontPackageHandler.cpp | 212 + k-meleon/FontPackageHandler.h | 88 + k-meleon/GenKeyPairDialogs.cpp | 112 + k-meleon/GenKeyPairDialogs.h | 75 + k-meleon/GenericDlg.cpp | 443 +++ k-meleon/GenericDlg.h | 140 + k-meleon/HiddenWnd.cpp | 347 ++ k-meleon/HiddenWnd.h | 83 + k-meleon/IBrowserFrameGlue.h | 192 + k-meleon/Install/GNUlicense.txt | 340 ++ k-meleon/Install/K-Meleon.bmp | Bin 0 -> 154542 bytes k-meleon/Install/K-MeleonUNINST.ini | 1 + k-meleon/Install/License.txt | 916 +++++ k-meleon/Install/SetDefault.nsi | 981 +++++ k-meleon/Install/english.nlf | 50 + k-meleon/Install/install.ico | Bin 0 -> 4710 bytes k-meleon/Install/k-meleon.ico | Bin 0 -> 4710 bytes k-meleon/Install/k-meleon.nsi | 728 ++++ k-meleon/Install/makensis.exe | Bin 0 -> 195584 bytes k-meleon/Install/readme.txt | 118 + k-meleon/Install/uninstall.ico | Bin 0 -> 4710 bytes k-meleon/JSBridge/JSBridge.sln | 21 + k-meleon/JSBridge/JSBridge.vcproj | 188 + k-meleon/JSBridge/genidl.cmd | 2 + k-meleon/JSBridge/jscomp.cpp | 71 + k-meleon/JSBridge/jscomp.h | 21 + k-meleon/JSBridge/jsplugin.cpp | 107 + k-meleon/JSBridge/nsGenericFactory.cpp | 214 + k-meleon/JSBridge/nsIJSBridge.idl | 24 + k-meleon/KMeleon.dsp | 540 +++ k-meleon/KMeleon.dsw | 185 + k-meleon/KMeleon.sln | 293 ++ k-meleon/KMeleon.vcproj | 1037 +++++ k-meleon/KMeleonConst.h | 90 + k-meleon/KmMenu.cpp | 375 ++ k-meleon/KmMenu.h | 227 ++ k-meleon/LangParser.cpp | 192 + k-meleon/LangParser.h | 57 + k-meleon/LocalesUtils.h | 400 ++ k-meleon/Log.h | 223 ++ k-meleon/MenuParser.cpp | 219 ++ k-meleon/MenuParser.h | 45 + k-meleon/MfcEmbed.cpp | 1636 ++++++++ k-meleon/MfcEmbed.h | 199 + k-meleon/MfcEmbed.rc | 1774 +++++++++ k-meleon/MostRecentUrls.cpp | 112 + k-meleon/MostRecentUrls.h | 40 + k-meleon/MozUtils.cpp | 445 +++ k-meleon/MozUtils.h | 35 + k-meleon/NSSDialogs.cpp | 923 +++++ k-meleon/NSSDialogs.h | 296 ++ k-meleon/Parser.cpp | 192 + k-meleon/Parser.h | 21 + k-meleon/PasswordViewerDlg.cpp | 286 ++ k-meleon/PasswordViewerDlg.h | 102 + k-meleon/Permissions.cpp | 291 ++ k-meleon/Permissions.h | 165 + k-meleon/Plugins.cpp | 1620 ++++++++ k-meleon/Plugins.h | 61 + k-meleon/Preferences.cpp | 484 +++ k-meleon/Preferences.h | 442 +++ k-meleon/PreferencesDlg.cpp | 779 ++++ k-meleon/PrintProgressDialog.cpp | 251 ++ k-meleon/PrintProgressDialog.h | 68 + k-meleon/PrintSetupDialog.cpp | 434 +++ k-meleon/PrintSetupDialog.h | 78 + k-meleon/ProfileMgr.cpp | 676 ++++ k-meleon/ProfileMgr.h | 93 + k-meleon/ProfilesDlg.cpp | 288 ++ k-meleon/ProfilesDlg.h | 156 + k-meleon/PromptService.cpp | 475 +++ k-meleon/PromptService.h | 66 + k-meleon/README.TXT | 132 + k-meleon/ReBarEx.cpp | 462 +++ k-meleon/ReBarEx.h | 64 + k-meleon/SaveAsHandler.cpp | 425 ++ k-meleon/SaveAsHandler.h | 38 + k-meleon/SideBar.cpp | 455 +++ k-meleon/SideBar.h | 100 + k-meleon/StdAfx.cpp | 31 + k-meleon/StdAfx.h | 211 + k-meleon/TabReBar.cpp | 800 ++++ k-meleon/TabReBar.h | 143 + k-meleon/ToolBarEx.cpp | 238 ++ k-meleon/ToolBarEx.h | 48 + k-meleon/Tooltips.cpp | 124 + k-meleon/Tooltips.h | 42 + k-meleon/TooltipsProvider.cpp | 227 ++ k-meleon/TooltipsProvider.h | 52 + k-meleon/UnknownContentTypeHandler.cpp | 1280 ++++++ k-meleon/UnknownContentTypeHandler.h | 160 + k-meleon/Utils.cpp | 250 ++ k-meleon/Utils.h | 30 + k-meleon/bmp_menu/StdAfx.cpp | 8 + k-meleon/bmp_menu/StdAfx.h | 30 + k-meleon/bmp_menu/bmp_menu.cpp | 801 ++++ k-meleon/bmp_menu/bmp_menu.dsp | 121 + k-meleon/bmp_menu/bmp_menu.vcproj | 221 ++ .../communicator/permissions/cookieP3P.xul | 188 + .../chrome/embed/content/global/about.xhtml | 162 + .../chrome/embed/content/global/config.xul | 95 + .../chrome/embed/content/global/console.xul | 86 + k-meleon/chrome/embed/content/global/logo.gif | Bin 0 -> 12685 bytes .../embed/content/global/netError.xhtml | 142 + .../content/global/platformHTMLBindings.xml | 173 + .../embed/content/navigator/viewSource.xul | 51 + .../embed/content/navigator/viewsource.js | 388 ++ .../embed/content/pippki/certManager.xul | 38 + .../embed/content/pippki/changepassword.xul | 48 + .../embed/content/pippki/choosetoken.xul | 23 + .../embed/content/pippki/clientauthask.xul | 32 + .../embed/content/pippki/createCertInfo.xul | 19 + .../embed/content/pippki/crlManager.xul | 60 + .../embed/content/pippki/deletecert.xul | 19 + .../embed/content/pippki/device_manager.xul | 76 + .../embed/content/pippki/editcacert.xul | 25 + .../embed/content/pippki/editemailcert.xul | 30 + .../embed/content/pippki/editsslcert.xul | 30 + .../embed/content/pippki/escrowWarn.xul | 25 + .../embed/content/pippki/pref-crlupdate.xul | 49 + .../embed/content/pippki/pref-masterpass.js | 75 + .../embed/content/pippki/pref-masterpass.xul | 73 + .../embed/content/pippki/resetpassword.js | 43 + .../embed/content/pippki/resetpassword.xul | 26 + .../embed/locale/en-US/branding/brand.dtd | 5 + .../locale/en-US/branding/brand.properties | 4 + .../embed/skin/classic/global/netError.css | 151 + .../embed/skin/classic/global/toolbar.css | 70 + k-meleon/chrome/kmprefs/content/contents.rdf | 17 + .../kmprefs/content/firefox/actionsshared.js | 28 + .../kmprefs/content/firefox/changeaction.js | 219 ++ .../kmprefs/content/firefox/changeaction.xul | 91 + .../content/firefox/downloadactions.js | 826 ++++ .../content/firefox/downloadactions.xul | 102 + .../kmprefs/content/firefox/license.txt | 33 + .../kmprefs/content/firefox/preferences.css | 4 + .../kmprefs/content/firefox/preferences.xml | 80 + .../kmprefs/content/kmprefs/dlg-gestures.xul | 54 + .../kmprefs/content/kmprefs/dlg-webfind.xul | 54 + .../kmprefs/content/kmprefs/homepage.js | 40 + .../kmprefs/content/kmprefs/ovrl-history.xul | 103 + .../content/kmprefs/ovrl-javascript.xul | 22 + .../kmprefs/content/kmprefs/ovrl-popups.xul | 55 + .../kmprefs/content/kmprefs/ovrl-referrer.xul | 45 + .../kmprefs/content/kmprefs/ovrl-tabbar.xul | 134 + .../kmprefs/content/kmprefs/ovrl-urlbar.xul | 49 + .../chrome/kmprefs/content/kmprefs/xml.js | 99 + .../content/kplugins/booklistmanager.xul | 123 + .../kmprefs/content/kplugins/bookmarksbar.xul | 105 + .../kmprefs/content/kplugins/favoritesbar.xul | 220 ++ .../kmprefs/content/kplugins/fullscreen.xul | 75 + .../kmprefs/content/kplugins/gestures.xml | 78 + .../kmprefs/content/kplugins/hotlistbar.xul | 87 + .../kmprefs/content/kplugins/jsbridge.js | 46 + .../kmprefs/content/kplugins/layers.xul | 135 + .../kmprefs/content/kplugins/layersbar.xul | 145 + .../kmprefs/content/pref-appearance.xul | 519 +++ .../chrome/kmprefs/content/pref-browsing.xul | 239 ++ .../chrome/kmprefs/content/pref-display.xul | 189 + .../kmprefs/content/pref-encryption.xul | 201 + .../chrome/kmprefs/content/pref-filetypes.xul | 122 + .../chrome/kmprefs/content/pref-filters.xul | 63 + .../chrome/kmprefs/content/pref-history.xul | 18 + .../chrome/kmprefs/content/pref-hotlinks.xul | 103 + .../kmprefs/content/pref-javascript.xul | 65 + .../kmprefs/content/pref-kbookmarks.xul | 283 ++ .../kmprefs/content/pref-kfavorites.xul | 278 ++ .../kmprefs/content/pref-kfullscreen.xul | 17 + .../chrome/kmprefs/content/pref-kgestures.xul | 375 ++ .../chrome/kmprefs/content/pref-khotlist.xul | 347 ++ .../chrome/kmprefs/content/pref-klayers.xul | 35 + .../chrome/kmprefs/content/pref-kmacros.xul | 142 + .../chrome/kmprefs/content/pref-kplugins.xul | 148 + .../chrome/kmprefs/content/pref-privacy.xul | 237 ++ k-meleon/chrome/kmprefs/content/pref-tabs.xul | 114 + .../chrome/kmprefs/content/pref-toolbars.xul | 124 + .../chrome/kmprefs/content/pref-webfind.xul | 439 +++ k-meleon/chrome/kmprefs/content/pref.js | 392 ++ k-meleon/chrome/kmprefs/content/pref.xul | 294 ++ k-meleon/chrome/kmprefs/license.txt | 37 + .../chrome/kmprefs/locale/en-US/contents.rdf | 17 + .../locale/en-US/firefox/changeaction.dtd | 24 + .../locale/en-US/firefox/downloadactions.dtd | 28 + .../kmprefs/locale/en-US/firefox/license.txt | 33 + .../en-US/firefox/preferences.properties | 22 + .../locale/en-US/kmprefs/ovrl-history.dtd | 15 + .../locale/en-US/kmprefs/ovrl-javascript.dtd | 11 + .../locale/en-US/kmprefs/ovrl-popups.dtd | 20 + .../locale/en-US/kmprefs/ovrl-referrer.dtd | 7 + .../locale/en-US/kmprefs/ovrl-tabbar.dtd | 12 + .../locale/en-US/kmprefs/ovrl-urlbar.dtd | 3 + .../locale/en-US/kmprefs/xml.properties | 2 + .../locale/en-US/kplugins/bookmarksbar.dtd | 7 + .../locale/en-US/kplugins/favoritesbar.dtd | 10 + .../locale/en-US/kplugins/fullscreen.dtd | 6 + .../en-US/kplugins/fullscreen.properties | 3 + .../locale/en-US/kplugins/gestures.dtd | 64 + .../locale/en-US/kplugins/gestures.properties | 3 + .../locale/en-US/kplugins/hotlistbar.dtd | 5 + .../locale/en-US/kplugins/kplugins.dtd | 18 + .../locale/en-US/kplugins/kplugins.properties | 21 + .../kmprefs/locale/en-US/kplugins/layers.dtd | 14 + .../locale/en-US/kplugins/layersbar.dtd | 9 + .../locale/en-US/kplugins/macros.properties | 25 + .../kmprefs/locale/en-US/pref-appearance.dtd | 15 + .../kmprefs/locale/en-US/pref-browsing.dtd | 23 + .../locale/en-US/pref-browsing.properties | 6 + .../kmprefs/locale/en-US/pref-display.dtd | 30 + .../locale/en-US/pref-display.properties | 3 + .../kmprefs/locale/en-US/pref-encryption.dtd | 26 + .../kmprefs/locale/en-US/pref-filetypes.dtd | 15 + .../kmprefs/locale/en-US/pref-filters.dtd | 14 + .../kmprefs/locale/en-US/pref-history.dtd | 1 + .../kmprefs/locale/en-US/pref-hotlinks.dtd | 14 + .../kmprefs/locale/en-US/pref-javascript.dtd | 3 + .../kmprefs/locale/en-US/pref-kbookmarks.dtd | 10 + .../kmprefs/locale/en-US/pref-kfavorites.dtd | 7 + .../kmprefs/locale/en-US/pref-kfullscreen.dtd | 1 + .../kmprefs/locale/en-US/pref-kgestures.dtd | 15 + .../kmprefs/locale/en-US/pref-khotlist.dtd | 11 + .../kmprefs/locale/en-US/pref-klayers.dtd | 2 + .../kmprefs/locale/en-US/pref-kmacros.dtd | 7 + .../kmprefs/locale/en-US/pref-kplugins.dtd | 18 + .../locale/en-US/pref-kplugins.properties | 21 + .../kmprefs/locale/en-US/pref-privacy.dtd | 23 + .../chrome/kmprefs/locale/en-US/pref-tabs.dtd | 14 + .../kmprefs/locale/en-US/pref-toolbars.dtd | 7 + .../kmprefs/locale/en-US/pref-webfind.dtd | 32 + k-meleon/chrome/kmprefs/locale/en-US/pref.dtd | 71 + .../kmprefs/locale/en-US/pref.properties | 23 + k-meleon/chrome/kmprefs/skin/contents.rdf | 17 + .../kmprefs/skin/firefox/preferences.css | 145 + k-meleon/chrome/kmprefs/skin/gestures/LR.gif | Bin 0 -> 157 bytes k-meleon/chrome/kmprefs/skin/gestures/RL.gif | Bin 0 -> 158 bytes .../chrome/kmprefs/skin/gestures/down.gif | Bin 0 -> 138 bytes .../chrome/kmprefs/skin/gestures/downleft.gif | Bin 0 -> 140 bytes .../kmprefs/skin/gestures/downright.gif | Bin 0 -> 143 bytes .../chrome/kmprefs/skin/gestures/left.gif | Bin 0 -> 138 bytes .../chrome/kmprefs/skin/gestures/right.gif | Bin 0 -> 138 bytes k-meleon/chrome/kmprefs/skin/gestures/up.gif | Bin 0 -> 137 bytes .../chrome/kmprefs/skin/gestures/upleft.gif | Bin 0 -> 138 bytes .../chrome/kmprefs/skin/gestures/upright.gif | Bin 0 -> 138 bytes k-meleon/chrome/kmprefs/skin/kmprefs.css | 2 + k-meleon/components/Dialogs.cpp | 422 ++ k-meleon/components/Dialogs.h | 182 + k-meleon/components/Dialogs.rc | 136 + k-meleon/components/PromptService.cpp | 449 +++ k-meleon/components/PromptService.h | 43 + k-meleon/components/components.dsp | 137 + k-meleon/components/resource.h | 43 + k-meleon/components/stdafx.h | 76 + k-meleon/crash/crash.cpp | 579 +++ k-meleon/default/pref/I10n.js | 89 + k-meleon/default/pref/kmeleon.js | 230 ++ k-meleon/default/pref/kmprefs.js | 91 + k-meleon/default/pref/skin.js | 42 + k-meleon/default/profile/accel.cfg | 20 + k-meleon/default/profile/bookmarks.html | 43 + k-meleon/default/profile/chrome/adblock.css | 263 ++ .../default/profile/chrome/userContent.css | 46 + k-meleon/default/profile/localstore.rdf | 19 + k-meleon/default/profile/menus.cfg | 19 + k-meleon/default/profile/mimeTypes.rdf | 13 + k-meleon/default/profile/prefs.js | 9 + k-meleon/default/profile/search.rdf | 72 + k-meleon/default/profile/user.js | 1 + k-meleon/default/settings/accel.cfg | 121 + k-meleon/default/settings/gestures.xml | 77 + k-meleon/default/settings/menus.cfg | 557 +++ k-meleon/default/skins/Klassic/back.bmp | Bin 0 -> 39798 bytes .../default/skins/Klassic/bookmarks-edit.ico | Bin 0 -> 1078 bytes k-meleon/default/skins/Klassic/bookmarks.bmp | Bin 0 -> 4662 bytes k-meleon/default/skins/Klassic/favorites.bmp | Bin 0 -> 4374 bytes .../default/skins/Klassic/history-view.ico | Bin 0 -> 3262 bytes k-meleon/default/skins/Klassic/history.bmp | Bin 0 -> 4374 bytes .../default/skins/Klassic/hotlist-edit.ico | Bin 0 -> 766 bytes k-meleon/default/skins/Klassic/hotlist.bmp | Bin 0 -> 838 bytes k-meleon/default/skins/Klassic/layers.bmp | Bin 0 -> 822 bytes .../default/skins/Klassic/layerwindowcold.bmp | Bin 0 -> 3126 bytes .../default/skins/Klassic/layerwindowhot.bmp | Bin 0 -> 3126 bytes k-meleon/default/skins/Klassic/main.ico | Bin 0 -> 4710 bytes k-meleon/default/skins/Klassic/menu.bmp | Bin 0 -> 30006 bytes k-meleon/default/skins/Klassic/menuicons.cfg | 89 + k-meleon/default/skins/Klassic/onelook.bmp | Bin 0 -> 822 bytes .../default/skins/Klassic/privbar_green.bmp | Bin 0 -> 25974 bytes .../default/skins/Klassic/privbar_red.bmp | Bin 0 -> 25974 bytes k-meleon/default/skins/Klassic/rsscold.bmp | Bin 0 -> 822 bytes k-meleon/default/skins/Klassic/rsshot.bmp | Bin 0 -> 822 bytes k-meleon/default/skins/Klassic/throbber.avi | Bin 0 -> 26624 bytes k-meleon/default/skins/Klassic/toolbars.cfg | 466 +++ k-meleon/default/skins/Klassic/toolcold.bmp | Bin 0 -> 14646 bytes k-meleon/default/skins/Klassic/tooldead.bmp | Bin 0 -> 14646 bytes k-meleon/default/skins/Klassic/toolhot.bmp | Bin 0 -> 14646 bytes k-meleon/default/skins/Klassic/zoomcold.bmp | Bin 0 -> 1590 bytes k-meleon/default/skins/Klassic/zoomhot.bmp | Bin 0 -> 1590 bytes .../skins/Phoenity(Large)/mailnewscold.bmp | Bin 0 -> 5238 bytes .../skins/Phoenity(Large)/mailnewshot.bmp | Bin 0 -> 5238 bytes .../skins/Phoenity(Large)/mainbarcold.bmp | Bin 0 -> 19062 bytes .../skins/Phoenity(Large)/mainbardead.bmp | Bin 0 -> 5238 bytes .../skins/Phoenity(Large)/mainbarhot.bmp | Bin 0 -> 19062 bytes .../skins/Phoenity(Large)/searchlargecold.bmp | Bin 0 -> 1782 bytes .../skins/Phoenity(Large)/searchlargehot.bmp | Bin 0 -> 1782 bytes .../skins/Phoenity(Large)/toolbars.cfg | 496 +++ .../skins/Phoenity(Large)/zoomcold.bmp | Bin 0 -> 3510 bytes .../default/skins/Phoenity(Large)/zoomhot.bmp | Bin 0 -> 3510 bytes k-meleon/default/skins/Phoenity/back.bmp | Bin 0 -> 12054 bytes .../default/skins/Phoenity/bookmarks-edit.ico | Bin 0 -> 9062 bytes k-meleon/default/skins/Phoenity/bookmarks.bmp | Bin 0 -> 4662 bytes k-meleon/default/skins/Phoenity/favorites.bmp | Bin 0 -> 4662 bytes k-meleon/default/skins/Phoenity/findcold.bmp | Bin 0 -> 3830 bytes k-meleon/default/skins/Phoenity/findhot.bmp | Bin 0 -> 3830 bytes k-meleon/default/skins/Phoenity/gocold.bmp | Bin 0 -> 1590 bytes k-meleon/default/skins/Phoenity/gohot.bmp | Bin 0 -> 1590 bytes .../default/skins/Phoenity/history-view.ico | Bin 0 -> 9062 bytes k-meleon/default/skins/Phoenity/history.bmp | Bin 0 -> 4662 bytes .../default/skins/Phoenity/hotlist-edit.ico | Bin 0 -> 9062 bytes k-meleon/default/skins/Phoenity/hotlist.bmp | Bin 0 -> 4662 bytes k-meleon/default/skins/Phoenity/layers.bmp | Bin 0 -> 390 bytes .../skins/Phoenity/layerwindowcold.bmp | Bin 0 -> 3126 bytes .../default/skins/Phoenity/layerwindowhot.bmp | Bin 0 -> 3126 bytes .../default/skins/Phoenity/mailnewscold.bmp | Bin 0 -> 2358 bytes .../default/skins/Phoenity/mailnewshot.bmp | Bin 0 -> 2358 bytes k-meleon/default/skins/Phoenity/main.ico | Bin 0 -> 9062 bytes .../default/skins/Phoenity/mainbarcold.bmp | Bin 0 -> 8502 bytes .../default/skins/Phoenity/mainbardead.bmp | Bin 0 -> 2358 bytes .../default/skins/Phoenity/mainbarhot.bmp | Bin 0 -> 8502 bytes k-meleon/default/skins/Phoenity/menu.bmp | Bin 0 -> 28470 bytes k-meleon/default/skins/Phoenity/menuicons.cfg | 86 + k-meleon/default/skins/Phoenity/privcold.bmp | Bin 0 -> 42486 bytes k-meleon/default/skins/Phoenity/privhot.bmp | Bin 0 -> 42486 bytes .../default/skins/Phoenity/searchcold.bmp | Bin 0 -> 6966 bytes k-meleon/default/skins/Phoenity/searchhot.bmp | Bin 0 -> 6966 bytes k-meleon/default/skins/Phoenity/skin.js | 42 + k-meleon/default/skins/Phoenity/throbber.avi | Bin 0 -> 10240 bytes k-meleon/default/skins/Phoenity/toolbars.cfg | 496 +++ k-meleon/default/skins/Phoenity/zoomcold.bmp | Bin 0 -> 1590 bytes k-meleon/default/skins/Phoenity/zoomhot.bmp | Bin 0 -> 1590 bytes k-meleon/default/skins/commands.txt | 256 ++ k-meleon/defineMap.cpp | 85 + k-meleon/external/external.cpp | 346 ++ k-meleon/external/external.dsp | 125 + k-meleon/external/external.vcproj | 206 + k-meleon/findskin.cpp | 111 + k-meleon/fullscreen/fullscreen.cpp | 413 ++ k-meleon/fullscreen/fullscreen.dsp | 118 + k-meleon/fullscreen/fullscreen.h | 48 + k-meleon/fullscreen/fullscreen.rc | 107 + k-meleon/fullscreen/fullscreen.vcproj | 215 + k-meleon/fullscreen/resource.h | 25 + k-meleon/gestures/gestures.cpp | 434 +++ k-meleon/gestures/gestures.vcproj | 138 + k-meleon/history/AutoComplete.h | 146 + k-meleon/history/HistoryNode.h | 363 ++ k-meleon/history/bitmap1.bmp | Bin 0 -> 4374 bytes k-meleon/history/hist_view.cpp | 1429 +++++++ k-meleon/history/history.cpp | 556 +++ k-meleon/history/history.dsp | 132 + k-meleon/history/history.h | 82 + k-meleon/history/history.rc | 185 + k-meleon/history/history.vcproj | 210 + k-meleon/history/icon1.ico | Bin 0 -> 3262 bytes k-meleon/history/resource.h | 75 + k-meleon/ie_favorites/BookmarkNode.h | 344 ++ k-meleon/ie_favorites/StdAfx.cpp | 8 + k-meleon/ie_favorites/StdAfx.h | 29 + k-meleon/ie_favorites/bitmap1.bmp | Bin 0 -> 4374 bytes k-meleon/ie_favorites/favorites2.vcproj | 168 + k-meleon/ie_favorites/ie_favorites.cpp | 812 ++++ k-meleon/ie_favorites/ie_favorites.dsp | 152 + k-meleon/ie_favorites/ie_favorites.h | 174 + k-meleon/ie_favorites/ie_favorites.rc | 134 + k-meleon/ie_favorites/ie_favorites.vcproj | 264 ++ k-meleon/ie_favorites/ie_file.cpp | 272 ++ k-meleon/ie_favorites/ie_plugin.cpp | 567 +++ k-meleon/ie_favorites/ie_utils.cpp | 575 +++ k-meleon/ie_favorites/resource.h | 52 + k-meleon/kmeleon_plugin.h | 351 ++ k-meleon/kmeleon_winamp/StdAfx.cpp | 8 + k-meleon/kmeleon_winamp/StdAfx.h | 25 + k-meleon/kmeleon_winamp/bmp00001.bmp | Bin 0 -> 502 bytes k-meleon/kmeleon_winamp/frontend.h | 441 +++ k-meleon/kmeleon_winamp/kmeleon_winamp.cpp | 251 ++ k-meleon/kmeleon_winamp/kmeleon_winamp.dsp | 146 + k-meleon/kmeleon_winamp/kmeleon_winamp.rc | 161 + k-meleon/kmeleon_winamp/kmeleon_winamp.rc2 | 2 + k-meleon/kmeleon_winamp/kmeleon_winamp.vcproj | 227 ++ k-meleon/kmeleon_winamp/resource.h | 24 + k-meleon/layers/Layers.vcproj | 205 + k-meleon/layers/layers.cpp | 2021 ++++++++++ k-meleon/layers/layers.dsp | 117 + k-meleon/layers/layers.h | 3 + k-meleon/layers/layers.rc | 106 + k-meleon/loader/KMeleon.ico | Bin 0 -> 4710 bytes k-meleon/loader/config.cpp | 146 + k-meleon/loader/config.h | 33 + k-meleon/loader/loader.cpp | 317 ++ k-meleon/loader/loader.dsp | 142 + k-meleon/loader/loader.h | 41 + k-meleon/loader/loader.rc | 110 + k-meleon/loader/loader.vcproj | 233 ++ k-meleon/loader/resource.h | 26 + k-meleon/loader/tray.cpp | 63 + k-meleon/loader/tray.h | 23 + k-meleon/macros/macros.cpp | 3462 +++++++++++++++++ k-meleon/macros/macros.dsp | 125 + k-meleon/macros/macros.h | 5 + k-meleon/macros/macros.rc | 101 + k-meleon/macros/macros.vcproj | 214 + k-meleon/macros/macros/accel.kmm | 122 + k-meleon/macros/macros/cfg.kmm | 76 + k-meleon/macros/macros/compat.kmm | 37 + k-meleon/macros/macros/console2.kmm | 25 + k-meleon/macros/macros/docinfo.kmm | 91 + k-meleon/macros/macros/docinfo/docinfo.css | 19 + k-meleon/macros/macros/domcomplete.kmm | 28 + k-meleon/macros/macros/encoding.kmm | 198 + k-meleon/macros/macros/groups.kmm | 292 ++ k-meleon/macros/macros/hotlink.kmm | 30 + k-meleon/macros/macros/ie.kmm | 61 + k-meleon/macros/macros/kmprefs.kmm | 66 + k-meleon/macros/macros/lang.kmm | 48 + k-meleon/macros/macros/mail.kmm | 97 + k-meleon/macros/macros/main.kmm | 722 ++++ k-meleon/macros/macros/mru.kmm | 85 + k-meleon/macros/macros/mtypes.kmm | 24 + k-meleon/macros/macros/newsfox.kmm | 26 + k-meleon/macros/macros/proxy.kmm | 96 + k-meleon/macros/macros/reload.kmm | 53 + k-meleon/macros/macros/search.kmm | 148 + k-meleon/macros/macros/sendto.kmm | 29 + k-meleon/macros/macros/translate.kmm | 70 + k-meleon/macros/macros/useragent.kmm | 71 + k-meleon/macros/macros/zoom.kmm | 133 + k-meleon/macros2/functions.h | 1365 +++++++ k-meleon/macros2/macros.cpp | 884 +++++ k-meleon/macros2/macros.rc | 119 + k-meleon/macros2/macros/accel.kmm | 143 + k-meleon/macros2/macros/cfg.kmm | 96 + k-meleon/macros2/macros/compat.kmm | 37 + k-meleon/macros2/macros/console2.kmm | 25 + k-meleon/macros2/macros/docinfo.kmm | 91 + k-meleon/macros2/macros/docinfo/docinfo.css | 19 + k-meleon/macros2/macros/domcomplete.kmm | 28 + k-meleon/macros2/macros/encoding.kmm | 198 + k-meleon/macros2/macros/hotlink.kmm | 33 + k-meleon/macros2/macros/ie.kmm | 63 + k-meleon/macros2/macros/mail.kmm | 97 + k-meleon/macros2/macros/main.kmm | 786 ++++ k-meleon/macros2/macros/mtypes.kmm | 24 + k-meleon/macros2/macros/newsfox.kmm | 26 + k-meleon/macros2/macros/proxy.kmm | 96 + k-meleon/macros2/macros/reload.kmm | 53 + k-meleon/macros2/macros/search.kmm | 149 + k-meleon/macros2/macros/sendto.kmm | 29 + k-meleon/macros2/macros/translate.kmm | 70 + k-meleon/macros2/macros/useragent.kmm | 74 + k-meleon/macros2/macros/zoom.kmm | 133 + k-meleon/macros2/macros2.vcproj | 206 + k-meleon/macros2/object.h | 536 +++ k-meleon/macros2/parser.h | 1067 +++++ k-meleon/macros2/resrc1.h | 21 + k-meleon/nsGenericFactory.cpp | 224 ++ k-meleon/nsPrintSettingsImpl.cpp | 946 +++++ k-meleon/nsPrintSettingsImpl.h | 122 + k-meleon/ns_bookmarks/BookmarkNode.h | 459 +++ k-meleon/ns_bookmarks/StdAfx.cpp | 8 + k-meleon/ns_bookmarks/StdAfx.h | 38 + k-meleon/ns_bookmarks/bitmap1.bmp | Bin 0 -> 832 bytes k-meleon/ns_bookmarks/cursor1.cur | Bin 0 -> 326 bytes k-meleon/ns_bookmarks/defines.h | 66 + k-meleon/ns_bookmarks/icon1.ico | Bin 0 -> 1078 bytes k-meleon/ns_bookmarks/ns_bookmarks.cpp | 467 +++ k-meleon/ns_bookmarks/ns_bookmarks.dsp | 176 + k-meleon/ns_bookmarks/ns_bookmarks.rc | 256 ++ k-meleon/ns_bookmarks/ns_bookmarks.rc2 | 2 + k-meleon/ns_bookmarks/ns_bookmarks.vcproj | 591 +++ k-meleon/ns_bookmarks/ns_bookmarks_edit.cpp | 2058 ++++++++++ .../ns_bookmarks/ns_bookmarks_functions.h | 95 + k-meleon/ns_bookmarks/ns_bookmarks_utils.cpp | 1586 ++++++++ k-meleon/ns_bookmarks/resource.h | 90 + k-meleon/op_hotlist/BookmarkNode.h | 472 +++ k-meleon/op_hotlist/bitmap1.bmp | Bin 0 -> 838 bytes k-meleon/op_hotlist/cursor1.cur | Bin 0 -> 326 bytes k-meleon/op_hotlist/icon1.ico | Bin 0 -> 766 bytes k-meleon/op_hotlist/op_edit.cpp | 1769 +++++++++ k-meleon/op_hotlist/op_file.cpp | 695 ++++ k-meleon/op_hotlist/op_hotlist.dsp | 139 + k-meleon/op_hotlist/op_hotlist.h | 177 + k-meleon/op_hotlist/op_hotlist.rc | 233 ++ k-meleon/op_hotlist/op_hotlist.vcproj | 293 ++ k-meleon/op_hotlist/op_plugin.cpp | 739 ++++ k-meleon/op_hotlist/op_utils.cpp | 653 ++++ k-meleon/op_hotlist/resource.h | 84 + k-meleon/privacy/build.txt | 21 + k-meleon/privacy/copying.txt | 340 ++ k-meleon/privacy/privacy.cpp | 623 +++ k-meleon/privacy/privacy.dev | 89 + k-meleon/privacy/privacy.vcproj | 153 + k-meleon/privacy/privacy_private.h | 23 + k-meleon/privacy/privacy_private.rc | 158 + k-meleon/privacy/privacy_readme.txt | 104 + k-meleon/privacy/privacy_res.h | 17 + k-meleon/privacy/privacy_res.rc | 36 + k-meleon/qsort.cpp | 99 + k-meleon/rebar_menu/StdAfx.cpp | 8 + k-meleon/rebar_menu/StdAfx.h | 26 + k-meleon/rebar_menu/hot_tracking.cpp | 114 + k-meleon/rebar_menu/hot_tracking.h | 24 + k-meleon/rebar_menu/rebar_menu.cpp | 456 +++ k-meleon/rebar_menu/rebar_menu.dsp | 129 + k-meleon/rebar_menu/rebar_menu.vcproj | 236 ++ k-meleon/res/Cursor_10.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_11.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_12.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_13.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_14.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_15.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_16.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_17.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_25.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_26.cur | Bin 0 -> 326 bytes k-meleon/res/Cursor_27.cur | Bin 0 -> 326 bytes k-meleon/res/ICO1.ICO | Bin 0 -> 318 bytes k-meleon/res/ICO2.ICO | Bin 0 -> 318 bytes k-meleon/res/KMeleon.rc2 | 13 + k-meleon/res/KmeleonDocument.ico | Bin 0 -> 4710 bytes k-meleon/res/MozillaBrowser.ico | Bin 0 -> 4710 bytes k-meleon/res/broken.ico | Bin 0 -> 2126 bytes k-meleon/res/cursor1.cur | Bin 0 -> 2558 bytes k-meleon/res/kmeleon.ico | Bin 0 -> 1078 bytes k-meleon/res/mfcembed.ico | Bin 0 -> 1078 bytes k-meleon/res/mfcembed.rc2 | 13 + k-meleon/res/off.ico | Bin 0 -> 318 bytes k-meleon/res/offcheck.ico | Bin 0 -> 318 bytes k-meleon/res/on.ico | Bin 0 -> 318 bytes k-meleon/res/oncheck.ico | Bin 0 -> 318 bytes k-meleon/res/popupblock.ico | Bin 0 -> 3838 bytes k-meleon/res/sinsecur.ico | Bin 0 -> 2126 bytes k-meleon/res/ssecur.ico | Bin 0 -> 1366 bytes k-meleon/res/toolbar1.bmp | Bin 0 -> 190 bytes k-meleon/resource.h | 605 +++ k-meleon/sessions/resource.h | 33 + k-meleon/sessions/sessions.cpp | 755 ++++ k-meleon/sessions/sessions.h | 659 ++++ k-meleon/sessions/sessions.rc | 193 + k-meleon/sessions/sessions.vcproj | 307 ++ k-meleon/sessions/stdafx.cpp | 8 + k-meleon/sessions/stdafx.h | 13 + k-meleon/strconv.h | 197 + k-meleon/stristr.cpp | 69 + k-meleon/toolbars/toolbars.cpp | 1527 ++++++++ k-meleon/toolbars/toolbars.dsp | 125 + k-meleon/toolbars/toolbars.vcproj | 206 + k-meleon/urlbar.cpp | 700 ++++ k-meleon/urlbar.h | 263 ++ k-meleon/utf.h | 329 ++ k-meleon/utils/SetDefault.nsi | 257 ++ k-meleon/utils/km-remote.cpp | 77 + k-meleon/version.h | 8 + k-meleon/weasel/StdAfx.cpp | 7 + k-meleon/weasel/StdAfx.h | 35 + k-meleon/weasel/bitmap1.bmp | Bin 0 -> 934 bytes k-meleon/weasel/pop.cpp | 201 + k-meleon/weasel/pop.h | 26 + k-meleon/weasel/resource.h | 24 + k-meleon/weasel/weasel.cpp | 437 +++ k-meleon/weasel/weasel.dsp | 145 + k-meleon/weasel/weasel.dsw | 29 + k-meleon/weasel/weasel.rc | 119 + k-meleon/weasel/weasel.vcproj | 228 ++ k-meleon/winEmbedFileLocProvider.cpp | 465 +++ k-meleon/winEmbedFileLocProvider.h | 69 + 619 files changed, 109588 insertions(+) create mode 100644 CVSROOT/checkoutlist create mode 100644 CVSROOT/commitinfo create mode 100644 CVSROOT/config create mode 100644 CVSROOT/cvswrappers create mode 100644 CVSROOT/editinfo create mode 100644 CVSROOT/loginfo create mode 100644 CVSROOT/modules create mode 100644 CVSROOT/notify create mode 100644 CVSROOT/rcsinfo create mode 100644 CVSROOT/taginfo create mode 100644 CVSROOT/verifymsg create mode 100644 k-meleon/About.cpp create mode 100644 k-meleon/About.h create mode 100644 k-meleon/AccelParser.cpp create mode 100644 k-meleon/AccelParser.h create mode 100644 k-meleon/BrowserFrameGlue.cpp create mode 100644 k-meleon/BrowserFrm.cpp create mode 100644 k-meleon/BrowserFrm.h create mode 100644 k-meleon/BrowserFrmTab.cpp create mode 100644 k-meleon/BrowserFrmTab.h create mode 100644 k-meleon/BrowserGlue.cpp create mode 100644 k-meleon/BrowserImpl.cpp create mode 100644 k-meleon/BrowserImpl.h create mode 100644 k-meleon/BrowserImplCtxMenuLstnr.cpp create mode 100644 k-meleon/BrowserImplWebPrgrsLstnr.cpp create mode 100644 k-meleon/BrowserView.cpp create mode 100644 k-meleon/BrowserView.h create mode 100644 k-meleon/BrowserViewFind.cpp create mode 100644 k-meleon/BrowserViewPanning.cpp create mode 100644 k-meleon/BrowserViewUtils.cpp create mode 100644 k-meleon/BrowserWindow.cpp create mode 100644 k-meleon/BrowserWindow.h create mode 100644 k-meleon/CmdLine.cpp create mode 100644 k-meleon/CmdLine.h create mode 100644 k-meleon/Components.cpp create mode 100644 k-meleon/CookiePromptService.cpp create mode 100644 k-meleon/CookiePromptService.h create mode 100644 k-meleon/Cookies.h create mode 100644 k-meleon/CookiesViewerDlg.cpp create mode 100644 k-meleon/CookiesViewerDlg.h create mode 100644 k-meleon/DialogEx.h create mode 100644 k-meleon/DialogUtils.cpp create mode 100644 k-meleon/DialogUtils.h create mode 100644 k-meleon/Dialogs.cpp create mode 100644 k-meleon/Dialogs.h create mode 100644 k-meleon/FavIconList.cpp create mode 100644 k-meleon/FavIconList.h create mode 100644 k-meleon/FontPackageHandler.cpp create mode 100644 k-meleon/FontPackageHandler.h create mode 100644 k-meleon/GenKeyPairDialogs.cpp create mode 100644 k-meleon/GenKeyPairDialogs.h create mode 100644 k-meleon/GenericDlg.cpp create mode 100644 k-meleon/GenericDlg.h create mode 100644 k-meleon/HiddenWnd.cpp create mode 100644 k-meleon/HiddenWnd.h create mode 100644 k-meleon/IBrowserFrameGlue.h create mode 100644 k-meleon/Install/GNUlicense.txt create mode 100644 k-meleon/Install/K-Meleon.bmp create mode 100644 k-meleon/Install/K-MeleonUNINST.ini create mode 100644 k-meleon/Install/License.txt create mode 100644 k-meleon/Install/SetDefault.nsi create mode 100644 k-meleon/Install/english.nlf create mode 100644 k-meleon/Install/install.ico create mode 100644 k-meleon/Install/k-meleon.ico create mode 100644 k-meleon/Install/k-meleon.nsi create mode 100644 k-meleon/Install/makensis.exe create mode 100644 k-meleon/Install/readme.txt create mode 100644 k-meleon/Install/uninstall.ico create mode 100644 k-meleon/JSBridge/JSBridge.sln create mode 100644 k-meleon/JSBridge/JSBridge.vcproj create mode 100644 k-meleon/JSBridge/genidl.cmd create mode 100644 k-meleon/JSBridge/jscomp.cpp create mode 100644 k-meleon/JSBridge/jscomp.h create mode 100644 k-meleon/JSBridge/jsplugin.cpp create mode 100644 k-meleon/JSBridge/nsGenericFactory.cpp create mode 100644 k-meleon/JSBridge/nsIJSBridge.idl create mode 100644 k-meleon/KMeleon.dsp create mode 100644 k-meleon/KMeleon.dsw create mode 100644 k-meleon/KMeleon.sln create mode 100644 k-meleon/KMeleon.vcproj create mode 100644 k-meleon/KMeleonConst.h create mode 100644 k-meleon/KmMenu.cpp create mode 100644 k-meleon/KmMenu.h create mode 100644 k-meleon/LangParser.cpp create mode 100644 k-meleon/LangParser.h create mode 100644 k-meleon/LocalesUtils.h create mode 100644 k-meleon/Log.h create mode 100644 k-meleon/MenuParser.cpp create mode 100644 k-meleon/MenuParser.h create mode 100644 k-meleon/MfcEmbed.cpp create mode 100644 k-meleon/MfcEmbed.h create mode 100644 k-meleon/MfcEmbed.rc create mode 100644 k-meleon/MostRecentUrls.cpp create mode 100644 k-meleon/MostRecentUrls.h create mode 100644 k-meleon/MozUtils.cpp create mode 100644 k-meleon/MozUtils.h create mode 100644 k-meleon/NSSDialogs.cpp create mode 100644 k-meleon/NSSDialogs.h create mode 100644 k-meleon/Parser.cpp create mode 100644 k-meleon/Parser.h create mode 100644 k-meleon/PasswordViewerDlg.cpp create mode 100644 k-meleon/PasswordViewerDlg.h create mode 100644 k-meleon/Permissions.cpp create mode 100644 k-meleon/Permissions.h create mode 100644 k-meleon/Plugins.cpp create mode 100644 k-meleon/Plugins.h create mode 100644 k-meleon/Preferences.cpp create mode 100644 k-meleon/Preferences.h create mode 100644 k-meleon/PreferencesDlg.cpp create mode 100644 k-meleon/PrintProgressDialog.cpp create mode 100644 k-meleon/PrintProgressDialog.h create mode 100644 k-meleon/PrintSetupDialog.cpp create mode 100644 k-meleon/PrintSetupDialog.h create mode 100644 k-meleon/ProfileMgr.cpp create mode 100644 k-meleon/ProfileMgr.h create mode 100644 k-meleon/ProfilesDlg.cpp create mode 100644 k-meleon/ProfilesDlg.h create mode 100644 k-meleon/PromptService.cpp create mode 100644 k-meleon/PromptService.h create mode 100644 k-meleon/README.TXT create mode 100644 k-meleon/ReBarEx.cpp create mode 100644 k-meleon/ReBarEx.h create mode 100644 k-meleon/SaveAsHandler.cpp create mode 100644 k-meleon/SaveAsHandler.h create mode 100644 k-meleon/SideBar.cpp create mode 100644 k-meleon/SideBar.h create mode 100644 k-meleon/StdAfx.cpp create mode 100644 k-meleon/StdAfx.h create mode 100644 k-meleon/TabReBar.cpp create mode 100644 k-meleon/TabReBar.h create mode 100644 k-meleon/ToolBarEx.cpp create mode 100644 k-meleon/ToolBarEx.h create mode 100644 k-meleon/Tooltips.cpp create mode 100644 k-meleon/Tooltips.h create mode 100644 k-meleon/TooltipsProvider.cpp create mode 100644 k-meleon/TooltipsProvider.h create mode 100644 k-meleon/UnknownContentTypeHandler.cpp create mode 100644 k-meleon/UnknownContentTypeHandler.h create mode 100644 k-meleon/Utils.cpp create mode 100644 k-meleon/Utils.h create mode 100644 k-meleon/bmp_menu/StdAfx.cpp create mode 100644 k-meleon/bmp_menu/StdAfx.h create mode 100644 k-meleon/bmp_menu/bmp_menu.cpp create mode 100644 k-meleon/bmp_menu/bmp_menu.dsp create mode 100644 k-meleon/bmp_menu/bmp_menu.vcproj create mode 100644 k-meleon/chrome/embed/content/communicator/permissions/cookieP3P.xul create mode 100644 k-meleon/chrome/embed/content/global/about.xhtml create mode 100644 k-meleon/chrome/embed/content/global/config.xul create mode 100644 k-meleon/chrome/embed/content/global/console.xul create mode 100644 k-meleon/chrome/embed/content/global/logo.gif create mode 100644 k-meleon/chrome/embed/content/global/netError.xhtml create mode 100644 k-meleon/chrome/embed/content/global/platformHTMLBindings.xml create mode 100644 k-meleon/chrome/embed/content/navigator/viewSource.xul create mode 100644 k-meleon/chrome/embed/content/navigator/viewsource.js create mode 100644 k-meleon/chrome/embed/content/pippki/certManager.xul create mode 100644 k-meleon/chrome/embed/content/pippki/changepassword.xul create mode 100644 k-meleon/chrome/embed/content/pippki/choosetoken.xul create mode 100644 k-meleon/chrome/embed/content/pippki/clientauthask.xul create mode 100644 k-meleon/chrome/embed/content/pippki/createCertInfo.xul create mode 100644 k-meleon/chrome/embed/content/pippki/crlManager.xul create mode 100644 k-meleon/chrome/embed/content/pippki/deletecert.xul create mode 100644 k-meleon/chrome/embed/content/pippki/device_manager.xul create mode 100644 k-meleon/chrome/embed/content/pippki/editcacert.xul create mode 100644 k-meleon/chrome/embed/content/pippki/editemailcert.xul create mode 100644 k-meleon/chrome/embed/content/pippki/editsslcert.xul create mode 100644 k-meleon/chrome/embed/content/pippki/escrowWarn.xul create mode 100644 k-meleon/chrome/embed/content/pippki/pref-crlupdate.xul create mode 100644 k-meleon/chrome/embed/content/pippki/pref-masterpass.js create mode 100644 k-meleon/chrome/embed/content/pippki/pref-masterpass.xul create mode 100644 k-meleon/chrome/embed/content/pippki/resetpassword.js create mode 100644 k-meleon/chrome/embed/content/pippki/resetpassword.xul create mode 100644 k-meleon/chrome/embed/locale/en-US/branding/brand.dtd create mode 100644 k-meleon/chrome/embed/locale/en-US/branding/brand.properties create mode 100644 k-meleon/chrome/embed/skin/classic/global/netError.css create mode 100644 k-meleon/chrome/embed/skin/classic/global/toolbar.css create mode 100644 k-meleon/chrome/kmprefs/content/contents.rdf create mode 100644 k-meleon/chrome/kmprefs/content/firefox/actionsshared.js create mode 100644 k-meleon/chrome/kmprefs/content/firefox/changeaction.js create mode 100644 k-meleon/chrome/kmprefs/content/firefox/changeaction.xul create mode 100644 k-meleon/chrome/kmprefs/content/firefox/downloadactions.js create mode 100644 k-meleon/chrome/kmprefs/content/firefox/downloadactions.xul create mode 100644 k-meleon/chrome/kmprefs/content/firefox/license.txt create mode 100644 k-meleon/chrome/kmprefs/content/firefox/preferences.css create mode 100644 k-meleon/chrome/kmprefs/content/firefox/preferences.xml create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/dlg-gestures.xul create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/dlg-webfind.xul create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/homepage.js create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/ovrl-history.xul create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/ovrl-javascript.xul create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/ovrl-popups.xul create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/ovrl-referrer.xul create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/ovrl-tabbar.xul create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/ovrl-urlbar.xul create mode 100644 k-meleon/chrome/kmprefs/content/kmprefs/xml.js create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/booklistmanager.xul create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/bookmarksbar.xul create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/favoritesbar.xul create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/fullscreen.xul create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/gestures.xml create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/hotlistbar.xul create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/jsbridge.js create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/layers.xul create mode 100644 k-meleon/chrome/kmprefs/content/kplugins/layersbar.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-appearance.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-browsing.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-display.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-encryption.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-filetypes.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-filters.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-history.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-hotlinks.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-javascript.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-kbookmarks.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-kfavorites.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-kfullscreen.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-kgestures.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-khotlist.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-klayers.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-kmacros.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-kplugins.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-privacy.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-tabs.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-toolbars.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref-webfind.xul create mode 100644 k-meleon/chrome/kmprefs/content/pref.js create mode 100644 k-meleon/chrome/kmprefs/content/pref.xul create mode 100644 k-meleon/chrome/kmprefs/license.txt create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/contents.rdf create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/firefox/changeaction.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/firefox/downloadactions.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/firefox/license.txt create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/firefox/preferences.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kmprefs/ovrl-history.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kmprefs/ovrl-javascript.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kmprefs/ovrl-popups.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kmprefs/ovrl-referrer.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kmprefs/ovrl-tabbar.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kmprefs/ovrl-urlbar.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kmprefs/xml.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/bookmarksbar.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/favoritesbar.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/fullscreen.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/fullscreen.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/gestures.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/gestures.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/hotlistbar.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/kplugins.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/kplugins.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/layers.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/layersbar.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/kplugins/macros.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-appearance.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-browsing.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-browsing.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-display.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-display.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-encryption.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-filetypes.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-filters.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-history.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-hotlinks.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-javascript.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-kbookmarks.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-kfavorites.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-kfullscreen.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-kgestures.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-khotlist.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-klayers.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-kmacros.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-kplugins.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-kplugins.properties create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-privacy.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-tabs.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-toolbars.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref-webfind.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref.dtd create mode 100644 k-meleon/chrome/kmprefs/locale/en-US/pref.properties create mode 100644 k-meleon/chrome/kmprefs/skin/contents.rdf create mode 100644 k-meleon/chrome/kmprefs/skin/firefox/preferences.css create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/LR.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/RL.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/down.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/downleft.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/downright.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/left.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/right.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/up.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/upleft.gif create mode 100644 k-meleon/chrome/kmprefs/skin/gestures/upright.gif create mode 100644 k-meleon/chrome/kmprefs/skin/kmprefs.css create mode 100644 k-meleon/components/Dialogs.cpp create mode 100644 k-meleon/components/Dialogs.h create mode 100644 k-meleon/components/Dialogs.rc create mode 100644 k-meleon/components/PromptService.cpp create mode 100644 k-meleon/components/PromptService.h create mode 100644 k-meleon/components/components.dsp create mode 100644 k-meleon/components/resource.h create mode 100644 k-meleon/components/stdafx.h create mode 100644 k-meleon/crash/crash.cpp create mode 100644 k-meleon/default/pref/I10n.js create mode 100644 k-meleon/default/pref/kmeleon.js create mode 100644 k-meleon/default/pref/kmprefs.js create mode 100644 k-meleon/default/pref/skin.js create mode 100644 k-meleon/default/profile/accel.cfg create mode 100644 k-meleon/default/profile/bookmarks.html create mode 100644 k-meleon/default/profile/chrome/adblock.css create mode 100644 k-meleon/default/profile/chrome/userContent.css create mode 100644 k-meleon/default/profile/localstore.rdf create mode 100644 k-meleon/default/profile/menus.cfg create mode 100644 k-meleon/default/profile/mimeTypes.rdf create mode 100644 k-meleon/default/profile/prefs.js create mode 100644 k-meleon/default/profile/search.rdf create mode 100644 k-meleon/default/profile/user.js create mode 100644 k-meleon/default/settings/accel.cfg create mode 100644 k-meleon/default/settings/gestures.xml create mode 100644 k-meleon/default/settings/menus.cfg create mode 100644 k-meleon/default/skins/Klassic/back.bmp create mode 100644 k-meleon/default/skins/Klassic/bookmarks-edit.ico create mode 100644 k-meleon/default/skins/Klassic/bookmarks.bmp create mode 100644 k-meleon/default/skins/Klassic/favorites.bmp create mode 100644 k-meleon/default/skins/Klassic/history-view.ico create mode 100644 k-meleon/default/skins/Klassic/history.bmp create mode 100644 k-meleon/default/skins/Klassic/hotlist-edit.ico create mode 100644 k-meleon/default/skins/Klassic/hotlist.bmp create mode 100644 k-meleon/default/skins/Klassic/layers.bmp create mode 100644 k-meleon/default/skins/Klassic/layerwindowcold.bmp create mode 100644 k-meleon/default/skins/Klassic/layerwindowhot.bmp create mode 100644 k-meleon/default/skins/Klassic/main.ico create mode 100644 k-meleon/default/skins/Klassic/menu.bmp create mode 100644 k-meleon/default/skins/Klassic/menuicons.cfg create mode 100644 k-meleon/default/skins/Klassic/onelook.bmp create mode 100644 k-meleon/default/skins/Klassic/privbar_green.bmp create mode 100644 k-meleon/default/skins/Klassic/privbar_red.bmp create mode 100644 k-meleon/default/skins/Klassic/rsscold.bmp create mode 100644 k-meleon/default/skins/Klassic/rsshot.bmp create mode 100644 k-meleon/default/skins/Klassic/throbber.avi create mode 100644 k-meleon/default/skins/Klassic/toolbars.cfg create mode 100644 k-meleon/default/skins/Klassic/toolcold.bmp create mode 100644 k-meleon/default/skins/Klassic/tooldead.bmp create mode 100644 k-meleon/default/skins/Klassic/toolhot.bmp create mode 100644 k-meleon/default/skins/Klassic/zoomcold.bmp create mode 100644 k-meleon/default/skins/Klassic/zoomhot.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/mailnewscold.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/mailnewshot.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/mainbarcold.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/mainbardead.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/mainbarhot.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/searchlargecold.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/searchlargehot.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/toolbars.cfg create mode 100644 k-meleon/default/skins/Phoenity(Large)/zoomcold.bmp create mode 100644 k-meleon/default/skins/Phoenity(Large)/zoomhot.bmp create mode 100644 k-meleon/default/skins/Phoenity/back.bmp create mode 100644 k-meleon/default/skins/Phoenity/bookmarks-edit.ico create mode 100644 k-meleon/default/skins/Phoenity/bookmarks.bmp create mode 100644 k-meleon/default/skins/Phoenity/favorites.bmp create mode 100644 k-meleon/default/skins/Phoenity/findcold.bmp create mode 100644 k-meleon/default/skins/Phoenity/findhot.bmp create mode 100644 k-meleon/default/skins/Phoenity/gocold.bmp create mode 100644 k-meleon/default/skins/Phoenity/gohot.bmp create mode 100644 k-meleon/default/skins/Phoenity/history-view.ico create mode 100644 k-meleon/default/skins/Phoenity/history.bmp create mode 100644 k-meleon/default/skins/Phoenity/hotlist-edit.ico create mode 100644 k-meleon/default/skins/Phoenity/hotlist.bmp create mode 100644 k-meleon/default/skins/Phoenity/layers.bmp create mode 100644 k-meleon/default/skins/Phoenity/layerwindowcold.bmp create mode 100644 k-meleon/default/skins/Phoenity/layerwindowhot.bmp create mode 100644 k-meleon/default/skins/Phoenity/mailnewscold.bmp create mode 100644 k-meleon/default/skins/Phoenity/mailnewshot.bmp create mode 100644 k-meleon/default/skins/Phoenity/main.ico create mode 100644 k-meleon/default/skins/Phoenity/mainbarcold.bmp create mode 100644 k-meleon/default/skins/Phoenity/mainbardead.bmp create mode 100644 k-meleon/default/skins/Phoenity/mainbarhot.bmp create mode 100644 k-meleon/default/skins/Phoenity/menu.bmp create mode 100644 k-meleon/default/skins/Phoenity/menuicons.cfg create mode 100644 k-meleon/default/skins/Phoenity/privcold.bmp create mode 100644 k-meleon/default/skins/Phoenity/privhot.bmp create mode 100644 k-meleon/default/skins/Phoenity/searchcold.bmp create mode 100644 k-meleon/default/skins/Phoenity/searchhot.bmp create mode 100644 k-meleon/default/skins/Phoenity/skin.js create mode 100644 k-meleon/default/skins/Phoenity/throbber.avi create mode 100644 k-meleon/default/skins/Phoenity/toolbars.cfg create mode 100644 k-meleon/default/skins/Phoenity/zoomcold.bmp create mode 100644 k-meleon/default/skins/Phoenity/zoomhot.bmp create mode 100644 k-meleon/default/skins/commands.txt create mode 100644 k-meleon/defineMap.cpp create mode 100644 k-meleon/external/external.cpp create mode 100644 k-meleon/external/external.dsp create mode 100644 k-meleon/external/external.vcproj create mode 100644 k-meleon/findskin.cpp create mode 100644 k-meleon/fullscreen/fullscreen.cpp create mode 100644 k-meleon/fullscreen/fullscreen.dsp create mode 100644 k-meleon/fullscreen/fullscreen.h create mode 100644 k-meleon/fullscreen/fullscreen.rc create mode 100644 k-meleon/fullscreen/fullscreen.vcproj create mode 100644 k-meleon/fullscreen/resource.h create mode 100644 k-meleon/gestures/gestures.cpp create mode 100644 k-meleon/gestures/gestures.vcproj create mode 100644 k-meleon/history/AutoComplete.h create mode 100644 k-meleon/history/HistoryNode.h create mode 100644 k-meleon/history/bitmap1.bmp create mode 100644 k-meleon/history/hist_view.cpp create mode 100644 k-meleon/history/history.cpp create mode 100644 k-meleon/history/history.dsp create mode 100644 k-meleon/history/history.h create mode 100644 k-meleon/history/history.rc create mode 100644 k-meleon/history/history.vcproj create mode 100644 k-meleon/history/icon1.ico create mode 100644 k-meleon/history/resource.h create mode 100644 k-meleon/ie_favorites/BookmarkNode.h create mode 100644 k-meleon/ie_favorites/StdAfx.cpp create mode 100644 k-meleon/ie_favorites/StdAfx.h create mode 100644 k-meleon/ie_favorites/bitmap1.bmp create mode 100644 k-meleon/ie_favorites/favorites2.vcproj create mode 100644 k-meleon/ie_favorites/ie_favorites.cpp create mode 100644 k-meleon/ie_favorites/ie_favorites.dsp create mode 100644 k-meleon/ie_favorites/ie_favorites.h create mode 100644 k-meleon/ie_favorites/ie_favorites.rc create mode 100644 k-meleon/ie_favorites/ie_favorites.vcproj create mode 100644 k-meleon/ie_favorites/ie_file.cpp create mode 100644 k-meleon/ie_favorites/ie_plugin.cpp create mode 100644 k-meleon/ie_favorites/ie_utils.cpp create mode 100644 k-meleon/ie_favorites/resource.h create mode 100644 k-meleon/kmeleon_plugin.h create mode 100644 k-meleon/kmeleon_winamp/StdAfx.cpp create mode 100644 k-meleon/kmeleon_winamp/StdAfx.h create mode 100644 k-meleon/kmeleon_winamp/bmp00001.bmp create mode 100644 k-meleon/kmeleon_winamp/frontend.h create mode 100644 k-meleon/kmeleon_winamp/kmeleon_winamp.cpp create mode 100644 k-meleon/kmeleon_winamp/kmeleon_winamp.dsp create mode 100644 k-meleon/kmeleon_winamp/kmeleon_winamp.rc create mode 100644 k-meleon/kmeleon_winamp/kmeleon_winamp.rc2 create mode 100644 k-meleon/kmeleon_winamp/kmeleon_winamp.vcproj create mode 100644 k-meleon/kmeleon_winamp/resource.h create mode 100644 k-meleon/layers/Layers.vcproj create mode 100644 k-meleon/layers/layers.cpp create mode 100644 k-meleon/layers/layers.dsp create mode 100644 k-meleon/layers/layers.h create mode 100644 k-meleon/layers/layers.rc create mode 100644 k-meleon/loader/KMeleon.ico create mode 100644 k-meleon/loader/config.cpp create mode 100644 k-meleon/loader/config.h create mode 100644 k-meleon/loader/loader.cpp create mode 100644 k-meleon/loader/loader.dsp create mode 100644 k-meleon/loader/loader.h create mode 100644 k-meleon/loader/loader.rc create mode 100644 k-meleon/loader/loader.vcproj create mode 100644 k-meleon/loader/resource.h create mode 100644 k-meleon/loader/tray.cpp create mode 100644 k-meleon/loader/tray.h create mode 100644 k-meleon/macros/macros.cpp create mode 100644 k-meleon/macros/macros.dsp create mode 100644 k-meleon/macros/macros.h create mode 100644 k-meleon/macros/macros.rc create mode 100644 k-meleon/macros/macros.vcproj create mode 100644 k-meleon/macros/macros/accel.kmm create mode 100644 k-meleon/macros/macros/cfg.kmm create mode 100644 k-meleon/macros/macros/compat.kmm create mode 100644 k-meleon/macros/macros/console2.kmm create mode 100644 k-meleon/macros/macros/docinfo.kmm create mode 100644 k-meleon/macros/macros/docinfo/docinfo.css create mode 100644 k-meleon/macros/macros/domcomplete.kmm create mode 100644 k-meleon/macros/macros/encoding.kmm create mode 100644 k-meleon/macros/macros/groups.kmm create mode 100644 k-meleon/macros/macros/hotlink.kmm create mode 100644 k-meleon/macros/macros/ie.kmm create mode 100644 k-meleon/macros/macros/kmprefs.kmm create mode 100644 k-meleon/macros/macros/lang.kmm create mode 100644 k-meleon/macros/macros/mail.kmm create mode 100644 k-meleon/macros/macros/main.kmm create mode 100644 k-meleon/macros/macros/mru.kmm create mode 100644 k-meleon/macros/macros/mtypes.kmm create mode 100644 k-meleon/macros/macros/newsfox.kmm create mode 100644 k-meleon/macros/macros/proxy.kmm create mode 100644 k-meleon/macros/macros/reload.kmm create mode 100644 k-meleon/macros/macros/search.kmm create mode 100644 k-meleon/macros/macros/sendto.kmm create mode 100644 k-meleon/macros/macros/translate.kmm create mode 100644 k-meleon/macros/macros/useragent.kmm create mode 100644 k-meleon/macros/macros/zoom.kmm create mode 100644 k-meleon/macros2/functions.h create mode 100644 k-meleon/macros2/macros.cpp create mode 100644 k-meleon/macros2/macros.rc create mode 100644 k-meleon/macros2/macros/accel.kmm create mode 100644 k-meleon/macros2/macros/cfg.kmm create mode 100644 k-meleon/macros2/macros/compat.kmm create mode 100644 k-meleon/macros2/macros/console2.kmm create mode 100644 k-meleon/macros2/macros/docinfo.kmm create mode 100644 k-meleon/macros2/macros/docinfo/docinfo.css create mode 100644 k-meleon/macros2/macros/domcomplete.kmm create mode 100644 k-meleon/macros2/macros/encoding.kmm create mode 100644 k-meleon/macros2/macros/hotlink.kmm create mode 100644 k-meleon/macros2/macros/ie.kmm create mode 100644 k-meleon/macros2/macros/mail.kmm create mode 100644 k-meleon/macros2/macros/main.kmm create mode 100644 k-meleon/macros2/macros/mtypes.kmm create mode 100644 k-meleon/macros2/macros/newsfox.kmm create mode 100644 k-meleon/macros2/macros/proxy.kmm create mode 100644 k-meleon/macros2/macros/reload.kmm create mode 100644 k-meleon/macros2/macros/search.kmm create mode 100644 k-meleon/macros2/macros/sendto.kmm create mode 100644 k-meleon/macros2/macros/translate.kmm create mode 100644 k-meleon/macros2/macros/useragent.kmm create mode 100644 k-meleon/macros2/macros/zoom.kmm create mode 100644 k-meleon/macros2/macros2.vcproj create mode 100644 k-meleon/macros2/object.h create mode 100644 k-meleon/macros2/parser.h create mode 100644 k-meleon/macros2/resrc1.h create mode 100644 k-meleon/nsGenericFactory.cpp create mode 100644 k-meleon/nsPrintSettingsImpl.cpp create mode 100644 k-meleon/nsPrintSettingsImpl.h create mode 100644 k-meleon/ns_bookmarks/BookmarkNode.h create mode 100644 k-meleon/ns_bookmarks/StdAfx.cpp create mode 100644 k-meleon/ns_bookmarks/StdAfx.h create mode 100644 k-meleon/ns_bookmarks/bitmap1.bmp create mode 100644 k-meleon/ns_bookmarks/cursor1.cur create mode 100644 k-meleon/ns_bookmarks/defines.h create mode 100644 k-meleon/ns_bookmarks/icon1.ico create mode 100644 k-meleon/ns_bookmarks/ns_bookmarks.cpp create mode 100644 k-meleon/ns_bookmarks/ns_bookmarks.dsp create mode 100644 k-meleon/ns_bookmarks/ns_bookmarks.rc create mode 100644 k-meleon/ns_bookmarks/ns_bookmarks.rc2 create mode 100644 k-meleon/ns_bookmarks/ns_bookmarks.vcproj create mode 100644 k-meleon/ns_bookmarks/ns_bookmarks_edit.cpp create mode 100644 k-meleon/ns_bookmarks/ns_bookmarks_functions.h create mode 100644 k-meleon/ns_bookmarks/ns_bookmarks_utils.cpp create mode 100644 k-meleon/ns_bookmarks/resource.h create mode 100644 k-meleon/op_hotlist/BookmarkNode.h create mode 100644 k-meleon/op_hotlist/bitmap1.bmp create mode 100644 k-meleon/op_hotlist/cursor1.cur create mode 100644 k-meleon/op_hotlist/icon1.ico create mode 100644 k-meleon/op_hotlist/op_edit.cpp create mode 100644 k-meleon/op_hotlist/op_file.cpp create mode 100644 k-meleon/op_hotlist/op_hotlist.dsp create mode 100644 k-meleon/op_hotlist/op_hotlist.h create mode 100644 k-meleon/op_hotlist/op_hotlist.rc create mode 100644 k-meleon/op_hotlist/op_hotlist.vcproj create mode 100644 k-meleon/op_hotlist/op_plugin.cpp create mode 100644 k-meleon/op_hotlist/op_utils.cpp create mode 100644 k-meleon/op_hotlist/resource.h create mode 100644 k-meleon/privacy/build.txt create mode 100644 k-meleon/privacy/copying.txt create mode 100644 k-meleon/privacy/privacy.cpp create mode 100644 k-meleon/privacy/privacy.dev create mode 100644 k-meleon/privacy/privacy.vcproj create mode 100644 k-meleon/privacy/privacy_private.h create mode 100644 k-meleon/privacy/privacy_private.rc create mode 100644 k-meleon/privacy/privacy_readme.txt create mode 100644 k-meleon/privacy/privacy_res.h create mode 100644 k-meleon/privacy/privacy_res.rc create mode 100644 k-meleon/qsort.cpp create mode 100644 k-meleon/rebar_menu/StdAfx.cpp create mode 100644 k-meleon/rebar_menu/StdAfx.h create mode 100644 k-meleon/rebar_menu/hot_tracking.cpp create mode 100644 k-meleon/rebar_menu/hot_tracking.h create mode 100644 k-meleon/rebar_menu/rebar_menu.cpp create mode 100644 k-meleon/rebar_menu/rebar_menu.dsp create mode 100644 k-meleon/rebar_menu/rebar_menu.vcproj create mode 100644 k-meleon/res/Cursor_10.cur create mode 100644 k-meleon/res/Cursor_11.cur create mode 100644 k-meleon/res/Cursor_12.cur create mode 100644 k-meleon/res/Cursor_13.cur create mode 100644 k-meleon/res/Cursor_14.cur create mode 100644 k-meleon/res/Cursor_15.cur create mode 100644 k-meleon/res/Cursor_16.cur create mode 100644 k-meleon/res/Cursor_17.cur create mode 100644 k-meleon/res/Cursor_25.cur create mode 100644 k-meleon/res/Cursor_26.cur create mode 100644 k-meleon/res/Cursor_27.cur create mode 100644 k-meleon/res/ICO1.ICO create mode 100644 k-meleon/res/ICO2.ICO create mode 100644 k-meleon/res/KMeleon.rc2 create mode 100644 k-meleon/res/KmeleonDocument.ico create mode 100644 k-meleon/res/MozillaBrowser.ico create mode 100644 k-meleon/res/broken.ico create mode 100644 k-meleon/res/cursor1.cur create mode 100644 k-meleon/res/kmeleon.ico create mode 100644 k-meleon/res/mfcembed.ico create mode 100644 k-meleon/res/mfcembed.rc2 create mode 100644 k-meleon/res/off.ico create mode 100644 k-meleon/res/offcheck.ico create mode 100644 k-meleon/res/on.ico create mode 100644 k-meleon/res/oncheck.ico create mode 100644 k-meleon/res/popupblock.ico create mode 100644 k-meleon/res/sinsecur.ico create mode 100644 k-meleon/res/ssecur.ico create mode 100644 k-meleon/res/toolbar1.bmp create mode 100644 k-meleon/resource.h create mode 100644 k-meleon/sessions/resource.h create mode 100644 k-meleon/sessions/sessions.cpp create mode 100644 k-meleon/sessions/sessions.h create mode 100644 k-meleon/sessions/sessions.rc create mode 100644 k-meleon/sessions/sessions.vcproj create mode 100644 k-meleon/sessions/stdafx.cpp create mode 100644 k-meleon/sessions/stdafx.h create mode 100644 k-meleon/strconv.h create mode 100644 k-meleon/stristr.cpp create mode 100644 k-meleon/toolbars/toolbars.cpp create mode 100644 k-meleon/toolbars/toolbars.dsp create mode 100644 k-meleon/toolbars/toolbars.vcproj create mode 100644 k-meleon/urlbar.cpp create mode 100644 k-meleon/urlbar.h create mode 100644 k-meleon/utf.h create mode 100644 k-meleon/utils/SetDefault.nsi create mode 100644 k-meleon/utils/km-remote.cpp create mode 100644 k-meleon/version.h create mode 100644 k-meleon/weasel/StdAfx.cpp create mode 100644 k-meleon/weasel/StdAfx.h create mode 100644 k-meleon/weasel/bitmap1.bmp create mode 100644 k-meleon/weasel/pop.cpp create mode 100644 k-meleon/weasel/pop.h create mode 100644 k-meleon/weasel/resource.h create mode 100644 k-meleon/weasel/weasel.cpp create mode 100644 k-meleon/weasel/weasel.dsp create mode 100644 k-meleon/weasel/weasel.dsw create mode 100644 k-meleon/weasel/weasel.rc create mode 100644 k-meleon/weasel/weasel.vcproj create mode 100644 k-meleon/winEmbedFileLocProvider.cpp create mode 100644 k-meleon/winEmbedFileLocProvider.h diff --git a/CVSROOT/checkoutlist b/CVSROOT/checkoutlist new file mode 100644 index 00000000..b04b3501 --- /dev/null +++ b/CVSROOT/checkoutlist @@ -0,0 +1,13 @@ +# The "checkoutlist" file is used to support additional version controlled +# administrative files in $CVSROOT/CVSROOT, such as template files. +# +# The first entry on a line is a filename which will be checked out from +# the corresponding RCS file in the $CVSROOT/CVSROOT directory. +# The remainder of the line is an error message to use if the file cannot +# be checked out. +# +# File format: +# +# [] +# +# comment lines begin with '#' diff --git a/CVSROOT/commitinfo b/CVSROOT/commitinfo new file mode 100644 index 00000000..b19e7b7a --- /dev/null +++ b/CVSROOT/commitinfo @@ -0,0 +1,15 @@ +# The "commitinfo" file is used to control pre-commit checks. +# The filter on the right is invoked with the repository and a list +# of files to check. A non-zero exit of the filter program will +# cause the commit to be aborted. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being committed to, relative +# to the $CVSROOT. For the first match that is found, then the remainder +# of the line is the name of the filter to run. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/config b/CVSROOT/config new file mode 100644 index 00000000..8069cad5 --- /dev/null +++ b/CVSROOT/config @@ -0,0 +1,11 @@ +# Set this to "no" if pserver shouldn't check system users/passwords +#SystemAuth=no + +# Set `PreservePermissions' to `yes' to save file status information +# in the repository. +#PreservePermissions=no + +# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top +# level of the new working directory when using the `cvs checkout' +# command. +#TopLevelAdmin=no diff --git a/CVSROOT/cvswrappers b/CVSROOT/cvswrappers new file mode 100644 index 00000000..0accaf1b --- /dev/null +++ b/CVSROOT/cvswrappers @@ -0,0 +1,23 @@ +# This file affects handling of files based on their names. +# +# The -t/-f options allow one to treat directories of files +# as a single file, or to transform a file in other ways on +# its way in and out of CVS. +# +# The -m option specifies whether CVS attempts to merge files. +# +# The -k option specifies keyword expansion (e.g. -kb for binary). +# +# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) +# +# wildcard [option value][option value]... +# +# where option is one of +# -f from cvs filter value: path to filter +# -t to cvs filter value: path to filter +# -m update methodology value: MERGE or COPY +# -k expansion mode value: b, o, kkv, &c +# +# and value is a single-quote delimited value. +# For example: +#*.gif -k 'b' diff --git a/CVSROOT/editinfo b/CVSROOT/editinfo new file mode 100644 index 00000000..d78886c1 --- /dev/null +++ b/CVSROOT/editinfo @@ -0,0 +1,21 @@ +# The "editinfo" file is used to allow verification of logging +# information. It works best when a template (as specified in the +# rcsinfo file) is provided for the logging procedure. Given a +# template with locations for, a bug-id number, a list of people who +# reviewed the code before it can be checked in, and an external +# process to catalog the differences that were code reviewed, the +# following test can be applied to the code: +# +# Making sure that the entered bug-id number is correct. +# Validating that the code that was reviewed is indeed the code being +# checked in (using the bug-id number or a seperate review +# number to identify this particular code set.). +# +# If any of the above test failed, then the commit would be aborted. +# +# Actions such as mailing a copy of the report to each reviewer are +# better handled by an entry in the loginfo file. +# +# One thing that should be noted is the the ALL keyword is not +# supported. There can be only one entry that matches a given +# repository. diff --git a/CVSROOT/loginfo b/CVSROOT/loginfo new file mode 100644 index 00000000..5a59f0a5 --- /dev/null +++ b/CVSROOT/loginfo @@ -0,0 +1,26 @@ +# The "loginfo" file controls where "cvs commit" log information +# is sent. The first entry on a line is a regular expression which must match +# the directory that the change is being made to, relative to the +# $CVSROOT. If a match is found, then the remainder of the line is a filter +# program that should expect log information on its standard input. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name ALL appears as a regular expression it is always used +# in addition to the first matching regex or DEFAULT. +# +# You may specify a format string as part of the +# filter. The string is composed of a `%' followed +# by a single format character, or followed by a set of format +# characters surrounded by `{' and `}' as separators. The format +# characters are: +# +# s = file name +# V = old version number (pre-checkin) +# v = new version number (post-checkin) +# +# For example: +#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog +# or +#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog diff --git a/CVSROOT/modules b/CVSROOT/modules new file mode 100644 index 00000000..cb9e9efc --- /dev/null +++ b/CVSROOT/modules @@ -0,0 +1,26 @@ +# Three different line formats are valid: +# key -a aliases... +# key [options] directory +# key [options] directory files... +# +# Where "options" are composed of: +# -i prog Run "prog" on "cvs commit" from top-level of module. +# -o prog Run "prog" on "cvs checkout" of module. +# -e prog Run "prog" on "cvs export" of module. +# -t prog Run "prog" on "cvs rtag" of module. +# -u prog Run "prog" on "cvs update" of module. +# -d dir Place module in directory "dir" instead of module name. +# -l Top-level directory only -- do not recurse. +# +# NOTE: If you change any of the "Run" options above, you'll have to +# release and re-checkout any working directories of these modules. +# +# And "directory" is a path to a directory relative to $CVSROOT. +# +# The "-a" option specifies an alias. An alias is interpreted as if +# everything on the right of the "-a" had been typed on the command line. +# +# You can encode a module within a module by using the special '&' +# character to interpose another module into the current module. This +# can be useful for creating a module that consists of many directories +# spread out over the entire source repository. diff --git a/CVSROOT/notify b/CVSROOT/notify new file mode 100644 index 00000000..34f0bc28 --- /dev/null +++ b/CVSROOT/notify @@ -0,0 +1,12 @@ +# The "notify" file controls where notifications from watches set by +# "cvs watch add" or "cvs edit" are sent. The first entry on a line is +# a regular expression which is tested against the directory that the +# change is being made to, relative to the $CVSROOT. If it matches, +# then the remainder of the line is a filter program that should contain +# one occurrence of %s for the user to notify, and information on its +# standard input. +# +# "ALL" or "DEFAULT" can be used in place of the regular expression. +# +# For example: +#ALL mail %s -s "CVS notification" diff --git a/CVSROOT/rcsinfo b/CVSROOT/rcsinfo new file mode 100644 index 00000000..49e59f4d --- /dev/null +++ b/CVSROOT/rcsinfo @@ -0,0 +1,13 @@ +# The "rcsinfo" file is used to control templates with which the editor +# is invoked on commit and import. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being made to, relative to the +# $CVSROOT. For the first match that is found, then the remainder of the +# line is the name of the file that contains the template. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/taginfo b/CVSROOT/taginfo new file mode 100644 index 00000000..274a46dd --- /dev/null +++ b/CVSROOT/taginfo @@ -0,0 +1,20 @@ +# The "taginfo" file is used to control pre-tag checks. +# The filter on the right is invoked with the following arguments: +# +# $1 -- tagname +# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d +# $3 -- repository +# $4-> file revision [file revision ...] +# +# A non-zero exit of the filter program will cause the tag to be aborted. +# +# The first entry on a line is a regular expression which is tested +# against the directory that the change is being committed to, relative +# to the $CVSROOT. For the first match that is found, then the remainder +# of the line is the name of the filter to run. +# +# If the repository name does not match any of the regular expressions in this +# file, the "DEFAULT" line is used, if it is specified. +# +# If the name "ALL" appears as a regular expression it is always used +# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/verifymsg b/CVSROOT/verifymsg new file mode 100644 index 00000000..86f747ce --- /dev/null +++ b/CVSROOT/verifymsg @@ -0,0 +1,21 @@ +# The "verifymsg" file is used to allow verification of logging +# information. It works best when a template (as specified in the +# rcsinfo file) is provided for the logging procedure. Given a +# template with locations for, a bug-id number, a list of people who +# reviewed the code before it can be checked in, and an external +# process to catalog the differences that were code reviewed, the +# following test can be applied to the code: +# +# Making sure that the entered bug-id number is correct. +# Validating that the code that was reviewed is indeed the code being +# checked in (using the bug-id number or a seperate review +# number to identify this particular code set.). +# +# If any of the above test failed, then the commit would be aborted. +# +# Actions such as mailing a copy of the report to each reviewer are +# better handled by an entry in the loginfo file. +# +# One thing that should be noted is the the ALL keyword is not +# supported. There can be only one entry that matches a given +# repository. diff --git a/k-meleon/About.cpp b/k-meleon/About.cpp new file mode 100644 index 00000000..6ec73043 --- /dev/null +++ b/k-meleon/About.cpp @@ -0,0 +1,80 @@ +/* +* Copyright (C) 2001 Jeff Doozan +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "StdAfx.h" +#include "version.h" +#include "About.h" +#include "BrowserFrm.h" +#include "MfcEmbed.h" +extern CMfcEmbedApp theApp; + +#define _QUOTE(blah) #blah + +CAboutDlg::CAboutDlg(CWnd *wndParent) : CDialog(CAboutDlg::IDD, wndParent) +{ + m_credits = _QUOTE( + \r\n + K-Meleon - Copyright 2000-2003\r\n + \r\n + Uses the Gecko rendering engine by the Mozilla Group\r\n + Based on MfcEmbed\r\n + \r\n + Core Developers:\r\n + Jeff Doozan \r\n + Brian Harris \r\n + Mark Liffiton \r\n + \r\n + Plugin Developers:\r\n + Ulf Erikson \r\n + Rob Johnson \r\n + \r\n + Project Documentation:\r\n + Andrew Mutch \r\n + \r\n + Past Contributors:\r\n + Sebastian Spaeth \r\n + Christophe Thibault \r\n + Chak Nanga \r\n + ); + m_version.Format("Version %s Build %d Compiled %s", VERSION, BUILD_NUMBER, BUILD_TIME); +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX){ + DDX_Text(pDX, IDC_CREDITS, m_credits); + DDX_Text(pDX, IDC_VERSION, m_version); + CDialog::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CMfcEmbedApp) + ON_COMMAND(IDC_KMELEON_HOME, OnHome) + ON_COMMAND(IDC_KMELEON_FORUM, OnForum) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +void CAboutDlg::OnHome() { + if (theApp.m_pMostRecentBrowserFrame) + theApp.m_pMostRecentBrowserFrame->PostMessage(WM_COMMAND, ID_LINK_KMELEON_HOME); +} + + +void CAboutDlg::OnForum() { + if (theApp.m_pMostRecentBrowserFrame) + theApp.m_pMostRecentBrowserFrame->PostMessage(WM_COMMAND, ID_LINK_KMELEON_FORUM); +} diff --git a/k-meleon/About.h b/k-meleon/About.h new file mode 100644 index 00000000..5ba8d826 --- /dev/null +++ b/k-meleon/About.h @@ -0,0 +1,40 @@ +/* +* Copyright (C) 2001 Jeff Doozan +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "resource.h" +#include "BrowserView.h" +#include "DialogEx.h" + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(CWnd *wndParent); + enum { IDD = IDD_ABOUTBOX }; + +protected: + CString m_credits; + CString m_version; + + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + +protected: + afx_msg void OnHome(); + afx_msg void OnForum(); + + DECLARE_MESSAGE_MAP() +}; diff --git a/k-meleon/AccelParser.cpp b/k-meleon/AccelParser.cpp new file mode 100644 index 00000000..bc586290 --- /dev/null +++ b/k-meleon/AccelParser.cpp @@ -0,0 +1,484 @@ +/* +* Copyright (C) 2000 Brian Harris +* Copyright (C) 2006 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "StdAfx.h" + +#include "MfcEmbed.h" + +#include "AccelParser.h" +#include "Utils.h" +#include "resource.h" +#include "Plugins.h" + + +#define BEGIN_VK_TEST if (0){} +#define VK_TEST(KEY) else if (stricmp(p, #KEY) == 0){ key = VK_##KEY; } + +// a few that winuser.h doesn't have for some reason (snagged from msdn) +#define VK_OEM_PLUS 0xBB +#define VK_OEM_COMMA 0xBC +#define VK_OEM_MINUS 0xBD +#define VK_OEM_PERIOD 0xBE +// and some more friendly definitions... +#define VK_PLUS VK_OEM_PLUS +#define VK_EQUALS VK_OEM_PLUS +#define VK_MINUS VK_OEM_MINUS +#define VK_COMMA VK_OEM_COMMA +#define VK_PERIOD VK_OEM_PERIOD +#define VK_PERIOD VK_OEM_PERIOD +#define VK_PAGE_UP VK_PRIOR +#define VK_PAGE_DOWN VK_NEXT + +//Standard accel to show in menu + +static const ACCEL stdAccels[] = { + {FCONTROL, 'C', ID_EDIT_COPY}, + {FCONTROL, 'V', ID_EDIT_PASTE}, + {FCONTROL, 'X', ID_EDIT_CUT}, + {FVIRTKEY|FALT, VK_F4, ID_FILE_CLOSE} +}; + +extern BOOL ParsePluginCommand(char *pszCommand, char** plugin, char **parameter); + +CAccelParser::CAccelParser() +{ + accelTable = NULL; + numAccelerators = 0; + memset(accelerators, 0, sizeof(ACCEL) * MAX_ACCEL); + numMKeys = 0; + memset(mouse, 0, sizeof(ACCEL) * MAX_MOUSE); +} + +CAccelParser::CAccelParser(LPCTSTR filename) +{ + accelTable = NULL; + numAccelerators = 0; + memset(accelerators, 0, sizeof(ACCEL) * MAX_ACCEL); + + Load(filename); +} + +CAccelParser::~CAccelParser() +{ + if (accelTable){ + DestroyAcceleratorTable(accelTable); + } +} + +int CAccelParser::Load(LPCTSTR filename) +{ + SETUP_LOG("Accel"); + + if (accelTable){ + DestroyAcceleratorTable(accelTable); + accelTable = NULL; + numAccelerators = 0; + } + + int retVal = CParser::Load(filename); + + END_LOG(); + + return retVal; +} + +int CAccelParser::Parse(char *p) +{ + // = + char *e = strchr(p, '='); + if (e){ + *e = 0; + e++; + e = SkipWhiteSpace(e); + TrimWhiteSpace(e); + TrimWhiteSpace(p); + return SetAccel(p, e); + } + return 0; +} + +int CAccelParser::SetAccel(const char* pKey, char* pCommand) +{ + int command = 0; + const char *alt, *ctrl, *shift; + const char* p; + BYTE virt; + int key; + + char *plugin, *parameter; + if (ParsePluginCommand(pCommand, &plugin, ¶meter)) + { + if (theApp.plugins.SendMessage(plugin, "* AccelParser", "DoAccel", (long)parameter, (long)&command)) { + LOG_2("Called plugin %s with parameter %s", plugin, parameter); + } + else { + LOG_ERROR_2( "Plugin %s has no accelerator %s", plugin, parameter); + return 0; + } + } + else { + command = theApp.GetID(pCommand); + if (!command) + command = atoi(pCommand); + } + + virt = 0; + p = pKey; + alt = strstr(pKey, "ALT"); + if (alt){ + virt |= FALT; + p = alt + 3; + } + ctrl = strstr(pKey, "CTRL"); + if (ctrl){ + virt |= FCONTROL; + if (ctrl > alt){ + p = ctrl + 4; + } + } + shift = strstr(pKey, "SHIFT"); + if (shift){ + virt |= FSHIFT; + if ((shift > alt) && (shift > ctrl)){ + p = shift + 5; + } + } + + // by now, p should be past the modifiers and point to " " + p = SkipWhiteSpace((char*)p); + + if (strncmp(p, "VK_", 3) == 0){ + p+=3; + key = 0; + + // these should be in order of frequency of use to speed up parsing + BEGIN_VK_TEST + + VK_TEST(ESCAPE) + VK_TEST(LEFT) + VK_TEST(RIGHT) + + VK_TEST(F1) + VK_TEST(F2) + VK_TEST(F3) + VK_TEST(F4) + VK_TEST(F5) + VK_TEST(F6) + VK_TEST(F7) + VK_TEST(F8) + VK_TEST(F9) + VK_TEST(F10) + VK_TEST(F11) + VK_TEST(F12) + + VK_TEST(HOME) + VK_TEST(END) + + VK_TEST(PRIOR) // page up + VK_TEST(NEXT) // page down + VK_TEST(PAGE_UP) + VK_TEST(PAGE_DOWN) + VK_TEST(UP) + VK_TEST(DOWN) + VK_TEST(INSERT) + VK_TEST(DELETE) + VK_TEST(SPACE) + VK_TEST(HELP) + VK_TEST(EXECUTE) + VK_TEST(SELECT) + VK_TEST(PRINT) + VK_TEST(SNAPSHOT) // print screen? + + VK_TEST(PLUS) + VK_TEST(MINUS) + VK_TEST(COMMA) + VK_TEST(PERIOD) + VK_TEST(EQUALS) + + VK_TEST(BACK) + VK_TEST(TAB) + VK_TEST(CLEAR) + + VK_TEST(RETURN) + + VK_TEST(MULTIPLY) + VK_TEST(ADD) + VK_TEST(SUBTRACT) + VK_TEST(DECIMAL) + VK_TEST(DIVIDE) + VK_TEST(SEPARATOR) + + VK_TEST(PAUSE) + VK_TEST(CAPITAL) + VK_TEST(MENU) + + /* + VK_TEST(KANA) + VK_TEST(JUNJA) + VK_TEST(FINAL) + VK_TEST(HANJA) + VK_TEST(KANJI) + + VK_TEST(CONVERT) + VK_TEST(NONCONVERT) + VK_TEST(ACCEPT) + VK_TEST(MODECHANGE) + */ + + VK_TEST(LWIN) + VK_TEST(RWIN) + VK_TEST(APPS) + + VK_TEST(NUMPAD0) + VK_TEST(NUMPAD1) + VK_TEST(NUMPAD2) + VK_TEST(NUMPAD3) + VK_TEST(NUMPAD4) + VK_TEST(NUMPAD5) + VK_TEST(NUMPAD6) + VK_TEST(NUMPAD7) + VK_TEST(NUMPAD8) + VK_TEST(NUMPAD9) + + /* + VK_TEST(F13) + VK_TEST(F14) + VK_TEST(F15) + VK_TEST(F16) + VK_TEST(F17) + VK_TEST(F18) + VK_TEST(F19) + VK_TEST(F20) + VK_TEST(F21) + VK_TEST(F22) + VK_TEST(F23) + VK_TEST(F24) + */ + + VK_TEST(NUMLOCK) + VK_TEST(SCROLL) + } + else if (stricmp(p, "LButton") == 0){ + SetMAccel(command, virt, WM_LBUTTONDOWN); + return true; + } + else if (stricmp(p, "MButton") == 0){ + SetMAccel(command, virt, WM_MBUTTONDOWN); + return true; + } + else if (stricmp(p, "RButton") == 0){ + SetMAccel(command, virt, WM_RBUTTONDOWN); + return true; + } + else { + // regular key, convert it to virtual-key code to + // get the associated key on the keyboard. + key = VkKeyScanA(*p) & 0xff; + } + + virt |= FVIRTKEY; + SetAccel(command, virt, key); + + return true; +} + +void CAccelParser::SetAccel(WORD command, BYTE virt, WORD key) +{ + int oldAccel = FindAccel(virt, key); + if (command != 0 && oldAccel == -1) { + accelerators[numAccelerators].cmd = command; + accelerators[numAccelerators].fVirt = virt; + accelerators[numAccelerators].key = key; + numAccelerators++; + } + else { + if (command != 0) + accelerators[oldAccel].cmd = command; + else if (oldAccel>=0) + DeleteAccel(oldAccel); + } + if (accelTable) { + DestroyAcceleratorTable(accelTable); + accelTable = NULL; + } +} + +void CAccelParser::SetMAccel(WORD command, BYTE virt, WORD button) +{ + int oldAccel = FindMAccel(virt, button); + if (command == 0) { + if(oldAccel != -1) + DeleteMAccel(oldAccel); + return; + } + + if (oldAccel != -1) { + mouse[oldAccel].cmd = command; + return; + } + + mouse[numMKeys].cmd = command; + mouse[numMKeys].fVirt = virt; + mouse[numMKeys].key = button; + numMKeys++; +} + +void CAccelParser::DeleteMAccel(int idx) +{ + ASSERT(idx>=0&&idx<=MAX_MOUSE); + int i; + --numMKeys; + for (i=idx;i=0&&idx<=MAX_ACCEL); + int i; + --numAccelerators; + for (i=idx;ifVirt & FCONTROL) { + GetKeyNameText(MapVirtualKey(VK_CONTROL, 0)<<16, buf, sizeof(buf)); + if (*buf) { + CharLowerBuff(buf+1, _tcslen(buf)-1); + str = str + buf + _T("+"); + } + } + if(accel->fVirt & FSHIFT) { + GetKeyNameText(MapVirtualKey(VK_SHIFT, 0)<<16, buf, sizeof(buf)); + if (*buf) { + CharLowerBuff(buf+1, _tcslen(buf)-1); + str = str + buf + _T("+"); + } + } + if(accel->fVirt & FALT) { + GetKeyNameText(MapVirtualKey(VK_MENU, 0)<<16, buf, sizeof(buf)); + if (*buf) { + CharLowerBuff(buf+1, _tcslen(buf)-1); + str = str + buf + _T("+"); + } + } + if(accel->fVirt & FVIRTKEY) { + WORD key = accel->key; + UINT scan = MapVirtualKey(key, 0); + if ((key >= VK_PRIOR) && (key<=VK_DELETE)) + scan |= 0x100; // should remove the numpad text + + if (GetKeyNameText(scan<<16 , buf, sizeof(buf)) == 0) + return _T(""); + + // Since I can't find a way to remove the numpad indication + // for /,* or . I'm removing it the hard way. + TCHAR* parenthesis = _tcschr(buf, '('); + if (parenthesis && parenthesis>buf) + *parenthesis = 0; + + if (*buf) { + CharLowerBuff(buf+1, _tcslen(buf)-1); + str += buf; + } + } + else { + char c[2] = { accel->key & 0xff, '\0' }; + USES_CONVERSION; + str += A2CT(c); + } + return str; + } + + return _T(""); +} + +int CAccelParser::CheckMouse(UINT message){ + + int i, virt = 0; + virt = message >> 8; + switch (message & 0xff) { + case MK_LBUTTON: message = WM_LBUTTONDOWN; break; + case MK_RBUTTON: message = WM_RBUTTONDOWN; break; + case MK_MBUTTON: message = WM_MBUTTONDOWN; break; + default : ; + } + + + + for (i=0; i + * + * ***** END LICENSE BLOCK ***** */ + +// File Overview.... +// +// This file has the IBrowserFrameGlueObj implementation +// This frame glue object is nested inside of the BrowserFrame +// object(See BrowserFrm.h for more info) +// +// This is the place where all the platform specific interaction +// with the browser frame window takes place in response to +// callbacks from Gecko interface methods +// +// The main purpose of this interface is to separate the cross +// platform code in BrowserImpl*.cpp from the platform specific +// code(which is in this file) +// +// You'll also notice the use of a macro named "METHOD_PROLOGUE" +// through out this file. This macro essentially makes the pointer +// to a "containing" class available inside of the class which is +// being contained via a var named "pThis". In our case, the +// BrowserFrameGlue object is contained inside of the BrowserFrame +// object so "pThis" will be a pointer to a BrowserFrame object +// Refer to MFC docs for more info on METHOD_PROLOGUE macro + + +#include "stdafx.h" +#include "MfcEmbed.h" +#include "BrowserFrm.h" +#include "Dialogs.h" +#include "MenuParser.h" +#include "KmeleonConst.h" +#include "nsIDOMHTMLAreaElement.h" +#include "nsIDOMHTMLInputElement.h" + +extern CMfcEmbedApp theApp; +extern nsresult NewURI(nsIURI **result, const nsACString &spec); + +///////////////////////////////////////////////////////////////////////////// +// IBrowserFrameGlue implementation + +void CBrowserFrame::BrowserFrameGlueObj::UpdateStatusBarText(const PRUnichar *aMessage) +{ +#ifndef _UNICODE + if (aMessage && (wcslen(aMessage) > 1024)) return; +#endif + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + USES_CONVERSION; + CString str; + if (aMessage && wcslen(aMessage) > 0) + str = W2CT(aMessage); + else + str.LoadString(AFX_IDS_IDLEMESSAGE); + + pThis->m_wndStatusBar.SetPaneText(0, str); +} + +void CBrowserFrame::BrowserFrameGlueObj::UpdateProgress(PRInt32 aCurrent, PRInt32 aMax) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + pThis->m_wndProgressBar.SetRange32(0, aMax); + pThis->m_wndProgressBar.SetPos(aCurrent); +} + +void CBrowserFrame::BrowserFrameGlueObj::UpdateBusyState(PRBool aBusy) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + // Just notify the view of the busy state + // There's code in there which will take care of + // updating the STOP toolbar btn. etc + + pThis->m_wndBrowserView.UpdateBusyState(aBusy); + //if (!aBusy) + pThis->PostMessage(UWM_UPDATEBUSYSTATE, aBusy == PR_TRUE ? 1 : 0, 0); + + if (!aBusy) { + CString szUrl; + pThis->m_wndUrlBar.GetEnteredURL(szUrl); + if (_tcscmp(szUrl, _T("about:blank"))==0) + pThis->m_wndUrlBar.MaintainFocus(); + + // XXX We have to resize XUL dialog manually. They should have they own + // glue and window object! + if (pThis->m_bSizeOnLoad) { + nsCOMPtr domWindow; + pThis->m_wndBrowserView.mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (domWindow) + domWindow->SizeToContent(); + + // It must be repositionned somewhat after the resize. Centering it + // all the time is not that bad. + //if (pThis->m_chromeMask & nsIWebBrowserChrome::CHROME_CENTER_SCREEN) + pThis->CenterWindow(); + + pThis->ShowWindow(SW_SHOW); + pThis->UpdateWindow(); + pThis->m_bSizeOnLoad = FALSE; + } + } + else + pThis->m_wndBrowserView.mbDOMLoaded = FALSE; + + pThis->m_wndBrowserView.m_lastMouseActionNode = nsnull; +} + +// Called from the OnLocationChange() method in the nsIWebProgressListener +// interface implementation in CBrowserImpl to update the current URI +// Will get called after a URI is successfully loaded in the browser +// We use this info to update the URL bar's edit box +// +void CBrowserFrame::BrowserFrameGlueObj::UpdateCurrentURI(nsIURI *aLocation) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + if(aLocation) + { + USES_CONVERSION; + nsEmbedCString uriString; + aLocation->GetSpec(uriString); + + nsEmbedString uriString2; + NS_CStringToUTF16(uriString, NS_CSTRING_ENCODING_UTF8, uriString2); + + // Reset the popup notification and the icon uri + if (!(pThis->m_wndBrowserView.m_csHostPopupBlocked.IsEmpty())) { + pThis->m_wndStatusBar.RemoveIcon(ID_POPUP_BLOCKED_ICON); + pThis->m_wndBrowserView.m_csHostPopupBlocked.Empty(); + } +#ifdef INTERNAL_SITEICONS + // Must be done here, before testing if we have the same address + // because xul error page have its own icon, and since the address + // doesn't change when retrying, the icon may stay in the urlbar. + pThis->m_wndBrowserView.m_IconUri = nsnull; +#endif + + // Prevent to move the caret in the urlbar + CString currentURL; + pThis->m_wndUrlBar.GetEnteredURL(currentURL); + if (currentURL.Compare(W2CT(uriString2.get())) == 0) + return; + + // XXX Since Mozilla 1.8.0.2 about:blank is always passed here + // before anything else, broking stuffs, so ignore it! + if ( stricmp (uriString.get(), "about:blank") == 0 && + currentURL.GetLength()) + return; + + pThis->m_wndUrlBar.SetCurrentURL(W2CT(uriString2.get())); + + // Add a MRU entry. Note that I'm only only allowing + // http or https uri + + PRBool allowMRU,b; + aLocation->SchemeIs("http", &b); + allowMRU = b; + aLocation->SchemeIs("https", &b); + allowMRU |= b; + + if ( allowMRU ) { + if (theApp.preferences.MRUbehavior == 0){ + nsEmbedCString password; + aLocation->GetUsername(password); + aLocation->SetUserPass(password); + aLocation->GetSpec(uriString); + theApp.m_MRUList->AddURL(A2CT(uriString.get())); + } + else if (theApp.preferences.MRUbehavior == 1){ + nsEmbedCString nsScheme, nsHost; + aLocation->GetScheme(nsScheme); + aLocation->GetHost(nsHost); + nsHost.Insert("://",0); + nsHost.Insert(nsScheme,0); + theApp.m_MRUList->AddURL(A2CT(nsHost.get())); + } + } + } +} + +void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFrameTitle(PRUnichar **aTitle) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + CString title; + pThis->GetWindowText(title); + +/* TCHAR psz[256]; + CString appTitle; + appTitle.LoadString(AFX_IDS_APP_TITLE); + theApp.preferences.GetString("kmeleon.display.title", psz, appTitle.GetBuffer(0)); + appTitle = psz; + + title.Replace(_T(" (") + appTitle + _T(')'), _T("")); +*/ + if(!title.IsEmpty()) + { + USES_CONVERSION; + nsEmbedString nsTitle; + nsTitle.Assign(T2CW(title)); + *aTitle = NS_StringCloneData(nsTitle); + } +} + +void CBrowserFrame::BrowserFrameGlueObj::SetBrowserFrameTitle(const PRUnichar *aTitle) +{ +#ifndef _UNICODE + if (wcslen(aTitle) > 1024) return; +#endif + + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + TCHAR psz[256]; + CString appTitle; + appTitle.LoadString(AFX_IDS_APP_TITLE); + theApp.preferences.GetString("kmeleon.display.title", psz, appTitle.GetBuffer(0)); + appTitle = psz; + + CString title; + USES_CONVERSION; + title = W2CT(aTitle); + + if (title.IsEmpty()){ + pThis->m_wndUrlBar.GetEnteredURL(title); + } + + if (!appTitle.IsEmpty()) + title += _T(" (") + appTitle + _T(")"); + pThis->SetWindowText(title); + + pThis->PostMessage(UWM_UPDATESESSIONHISTORY, 0, 0); +} + +void CBrowserFrame::BrowserFrameGlueObj::SetBrowserFrameSize(PRInt32 aCX, PRInt32 aCY) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + if (pThis->m_ignoreMoveResize > 0) { + pThis->m_ignoreMoveResize--; + return; + } + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + pThis->GetWindowPlacement(&wp); + if (wp.showCmd != SW_SHOWNORMAL) + return; + + pThis->SetWindowPos(NULL, 0, 0, aCX, aCY, + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER + ); +} + +void CBrowserFrame::BrowserFrameGlueObj::SetBrowserSize(PRInt32 aCX, PRInt32 aCY) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + if (pThis->m_ignoreMoveResize > 0) { + pThis->m_ignoreMoveResize--; + return; + } + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + pThis->GetWindowPlacement(&wp); + if (wp.showCmd != SW_SHOWNORMAL) + return; + + // first we have to figure out how much bigger the frame is than the view + RECT frameRect, viewRect; + pThis->GetWindowRect(&frameRect); + pThis->m_wndBrowserView.GetClientRect(&viewRect); + + int deltax = (frameRect.right - frameRect.left - viewRect.right); + int deltay = (frameRect.bottom - frameRect.top - viewRect.bottom); + + pThis->SetWindowPos(NULL, 0, 0, aCX+deltax, aCY+deltay, + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER + ); +} + +void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFrameSize(PRInt32 *aCX, PRInt32 *aCY) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + RECT wndRect; + pThis->GetWindowRect(&wndRect); + + if (aCX) + *aCX = wndRect.right - wndRect.left; + + if (aCY) + *aCY = wndRect.bottom - wndRect.top; +} + +void CBrowserFrame::BrowserFrameGlueObj::GetBrowserSize(PRInt32 *aCX, PRInt32 *aCY) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + RECT wndRect; + pThis->m_wndBrowserView.GetClientRect(&wndRect); + + if (aCX) + *aCX = wndRect.right - wndRect.left; + + if (aCY) + *aCY = wndRect.bottom - wndRect.top; +} + +void CBrowserFrame::BrowserFrameGlueObj::SetBrowserFramePosition(PRInt32 aX, PRInt32 aY) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + if (pThis->m_ignoreMoveResize > 0) { + pThis->m_ignoreMoveResize--; + return; + } + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + pThis->GetWindowPlacement(&wp); + if (wp.showCmd != SW_SHOWNORMAL) + return; + + pThis->SetWindowPos(NULL, aX, aY, 0, 0, + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); +} + +void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFramePosition(PRInt32 *aX, PRInt32 *aY) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + RECT wndRect; + pThis->GetWindowRect(&wndRect); + + if (aX) + *aX = wndRect.left; + + if (aY) + *aY = wndRect.top; +} + +void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFramePositionAndSize(PRInt32 *aX, PRInt32 *aY, PRInt32 *aCX, PRInt32 *aCY) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + RECT wndRect; + pThis->GetWindowRect(&wndRect); + + if (aX) + *aX = wndRect.left; + + if (aY) + *aY = wndRect.top; + + if (aCX) + *aCX = wndRect.right - wndRect.left; + + if (aCY) + *aCY = wndRect.bottom - wndRect.top; +} + +void CBrowserFrame::BrowserFrameGlueObj::SetBrowserFramePositionAndSize(PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY, PRBool fRepaint) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + if (pThis->m_ignoreMoveResize > 0) { + pThis->m_ignoreMoveResize--; + return; + } + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + pThis->GetWindowPlacement(&wp); + if (wp.showCmd != SW_SHOWNORMAL) + return; + + pThis->SetWindowPos(NULL, aX, aY, aCX, aCY, + SWP_NOACTIVATE | SWP_NOZORDER); +} + +void CBrowserFrame::BrowserFrameGlueObj::SetBrowserPositionAndSize(PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY, PRBool fRepaint) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + if (pThis->m_ignoreMoveResize > 0) { + pThis->m_ignoreMoveResize--; + return; + } + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + pThis->GetWindowPlacement(&wp); + if (wp.showCmd != SW_SHOWNORMAL) + return; + + // first we have to figure out how much bigger the frame is than the view + RECT frameRect, viewRect; + pThis->GetWindowRect(&frameRect); + pThis->m_wndBrowserView.GetClientRect(&viewRect); + + int deltax = (frameRect.right-frameRect.left)-(viewRect.right-viewRect.left); + int deltay = (frameRect.bottom-frameRect.top)-(viewRect.bottom-viewRect.top); + + pThis->SetWindowPos(NULL, aX, aY, aCX+deltax, aCY+(deltay/2), + SWP_NOACTIVATE | SWP_NOZORDER); +} + +void CBrowserFrame::BrowserFrameGlueObj::SetFocus(){ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + //if (!::IsChild(pThis->m_hWnd,::GetFocus())) + // pThis->BringWindowToTop(); + + pThis->m_wndBrowserView.mBaseWindow->SetFocus(); +} + +void CBrowserFrame::BrowserFrameGlueObj::FocusAvailable(PRBool *aFocusAvail) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + HWND focusWnd = ::GetFocus(); // GetFocus()->m_hWnd; + + if ((focusWnd == pThis->m_hWnd) || ::IsChild(pThis->m_hWnd, focusWnd)) + *aFocusAvail = PR_TRUE; + else + *aFocusAvail = PR_FALSE; +} + +void CBrowserFrame::BrowserFrameGlueObj::ShowBrowserFrame(PRBool aShow) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + if(aShow) + { + if (pThis->m_bSizeOnLoad) + return; // Not yet, waiting for resize in UpdateBusyState + + if (pThis->IsIconic()) + return; + + if (!pThis->IsWindowVisible()) { + if (pThis->m_created) + return; + pThis->m_created = true; + } + + pThis->ShowWindow(SW_SHOW); + // pThis->SetActiveWindow(); + pThis->UpdateWindow(); + } + else + { + pThis->ShowWindow(SW_HIDE); + } +} + +void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFrameVisibility(PRBool *aVisible) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + /*// Is the current BrowserFrame the active one? + CWnd *pWnd = GetActiveWindow(); + if (!pWnd || pWnd->m_hWnd != pThis->m_hWnd) + { + *aVisible = PR_FALSE; + return; + }*/ + + *aVisible = pThis->IsIconic() || !pThis->IsWindowVisible() ? PR_FALSE : PR_TRUE; +} + +PRBool CBrowserFrame::BrowserFrameGlueObj::CreateNewBrowserFrame(PRUint32 chromeMask, + PRInt32 x, PRInt32 y, + PRInt32 cx, PRInt32 cy, + nsIWebBrowser** aWebBrowser) +{ + NS_ENSURE_ARG_POINTER(aWebBrowser); + + *aWebBrowser = nsnull; + + CMfcEmbedApp *pApp = (CMfcEmbedApp *)AfxGetApp(); + if(!pApp) + return PR_FALSE; + + // Note that we're calling with the last param set to "false" i.e. + // this instructs not to show the frame window + // This is mainly needed when the window size is specified in the window.open() + // JS call. In those cases Gecko calls us to create the browser with a default + // size (all are -1) and then it calls the SizeBrowserTo() method to set + // the proper window size. If this window were to be visible then you'll see + // the window size changes on the screen causing an unappealing flicker + // + + CBrowserFrame* pFrm = pApp->CreateNewBrowserFrame(chromeMask, x, y, cx, cy, PR_FALSE); + if(!pFrm) + return PR_FALSE; + + // At this stage we have a new CBrowserFrame and a new CBrowserView + // objects. The CBrowserView also would have an embedded browser + // object created. Get the mWebBrowser member from the CBrowserView + // and return it. (See CBrowserView's CreateBrowser() on how the + // embedded browser gets created and how it's mWebBrowser member + // gets initialized) + + NS_IF_ADDREF(*aWebBrowser = pFrm->m_wndBrowserView.mWebBrowser); + + return PR_TRUE; +} + +void CBrowserFrame::BrowserFrameGlueObj::DestroyBrowserFrame() +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + pThis->PostMessage(WM_CLOSE, -1, -1); +} + +void CBrowserFrame::BrowserFrameGlueObj::ShowContextMenu(PRUint32 aContextFlags, nsIContextMenuInfo *aInfo) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + int nodeHack = pThis->m_wndBrowserView.m_iGetNodeHack; + pThis->m_wndBrowserView.m_iGetNodeHack = 0; + + // No context menu for chrome + if (pThis->m_chromeMask & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) + return; + + BOOL bContentHasFrames = FALSE; + UINT nIDResource = IDR_CTXMENU_DOCUMENT; + + if (nodeHack == 0) { + if (GetKeyState(VK_SHIFT) < 0 || + GetKeyState(VK_CONTROL) < 0 || + GetKeyState(VK_MENU) < 0) + return; + } + + // Reset the values from the last invocation + // Clear image src & link url + nsEmbedString empty; + pThis->m_wndBrowserView.SetCtxMenuImageSrc(empty); + pThis->m_wndBrowserView.SetCtxMenuLinkUrl(empty); + pThis->m_wndBrowserView.SetCurrentFrameURL(empty); + + +/* + !!BAD HACK!! !!BAD HACK!! !!BAD HACK!! !!BAD HACK!! !!BAD HACK!! + + The bGetElementHack flag is part of the GetElementFromPoint function. + Basically, there's no easy way that I've found to get the link + information by point from mozilla, so as a workaround, the function + simply sends a contextmenu notifier with the point we want. It's + our job here to make sure the context menu doesn't get shown. + + !!BAD HACK!! !!BAD HACK!! !!BAD HACK!! !!BAD HACK!! !!BAD HACK!! +*/ + + nsCOMPtr node; + nsresult rv = aInfo->GetTargetNode(getter_AddRefs(node)); + if (NS_FAILED(rv)) return; + + + if (nodeHack == 1) { + pThis->m_wndBrowserView.m_pGetNode = node; + return; + } + + nsCOMPtr imgURI; + + // Check if there is a image first + if(aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE) + { + nIDResource = IDR_CTXMENU_IMAGE; + + // Get the IMG SRC + aInfo->GetImageSrc(getter_AddRefs(imgURI)); + if(!imgURI) + return; + } + + if(aContextFlags & nsIContextMenuListener2::CONTEXT_DOCUMENT) + { + nIDResource = IDR_CTXMENU_DOCUMENT; + } + else if(aContextFlags & nsIContextMenuListener2::CONTEXT_TEXT) + { + nIDResource = IDR_CTXMENU_TEXT; + } + else if (aContextFlags & nsIContextMenuListener2::CONTEXT_INPUT) + { + if (!(aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE)) { + // Mozilla don't tell if the input is of type text or password... + nsCOMPtr inputElement(do_QueryInterface(node)); + if (inputElement) { + nsEmbedString inputElemType; + inputElement->GetType(inputElemType); + if ((wcsicmp(inputElemType.get(), L"text") == 0) || + (wcsicmp(inputElemType.get(), L"password") == 0)) + nIDResource = IDR_CTXMENU_TEXT; + } + } + } + else if(aContextFlags & nsIContextMenuListener2::CONTEXT_LINK) + { + nIDResource = IDR_CTXMENU_LINK; + + // Since we handle all the browser menu/toolbar commands + // in the View, we basically setup the Link's URL in the + // BrowserView object. When a menu selection in the context + // menu is made, the appropriate command handler in the + // BrowserView will be invoked and the value of the URL + // will be accesible in the view + + nsEmbedString strUrlUcs2; + nsresult rv = aInfo->GetAssociatedLink(strUrlUcs2); + if(NS_FAILED(rv)) + return; + + // Update the view with the new LinkUrl + // Note that this string is in UCS2 format + pThis->m_wndBrowserView.SetCtxMenuLinkUrl(strUrlUcs2); + } + + // Check for a background image if the menu type is document + if ( (nIDResource == IDR_CTXMENU_DOCUMENT) && !imgURI && + (aContextFlags & nsIContextMenuListener2::CONTEXT_BACKGROUND_IMAGE)) + aInfo->GetBackgroundImageSrc(getter_AddRefs(imgURI)); + + if (imgURI) { + nsEmbedCString strImgSrcUtf8; + imgURI->GetSpec(strImgSrcUtf8); + if(!strImgSrcUtf8.IsEmpty()) { + // Set the new Img Src + nsEmbedString strImgSrc; + NS_CStringToUTF16(strImgSrcUtf8, NS_CSTRING_ENCODING_UTF8, strImgSrc); + pThis->m_wndBrowserView.SetCtxMenuImageSrc(strImgSrc); + + nsCOMPtr img; + aInfo->GetImageContainer(getter_AddRefs(img)); + //pThis->m_wndBrowserView.SetCtxImage(img); + } + } + + // Determine if we need to add the Frame related context menu items + // such as "View Frame Source" etc. + // node is not set for xml documents, ... but we still + // want the context menu for them. + if (node) + { + nsCOMPtr contextDocument; + rv = node->GetOwnerDocument(getter_AddRefs(contextDocument)); + if (NS_FAILED(rv) || !contextDocument) return; + + nsCOMPtr domWindow; + rv = pThis->m_wndBrowserView.mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (NS_FAILED(rv) || !domWindow) return; + + nsCOMPtr document; + rv = domWindow->GetDocument(getter_AddRefs(document)); + if (NS_FAILED(rv)) return; + + if(document != contextDocument) + { + //Determine the current Frame URL + nsCOMPtr htmlDoc(do_QueryInterface(contextDocument, &rv)); + if (NS_SUCCEEDED(rv)) { + nsEmbedString strFrameURL; + rv = htmlDoc->GetURL(strFrameURL); + if (NS_SUCCEEDED(rv)) { + //Set it to the new URL + pThis->m_wndBrowserView.SetCurrentFrameURL(strFrameURL); + bContentHasFrames = TRUE; + } + } + } + } + + TCHAR *menuType = _T(""); + + CString selection; + pThis->m_wndBrowserView.GetSelection(selection); + + if ( !(aContextFlags & nsIContextMenuListener2::CONTEXT_LINK) && + !(aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE) && + selection.GetLength() ) + { + menuType = _T("SelectedText"); + } + else { + + if (!bContentHasFrames) { + switch (nIDResource) { + case IDR_CTXMENU_DOCUMENT: + menuType = _T("DocumentPopup"); + if (imgURI) + menuType = _T("DocumentImagePopup"); + break; + case IDR_CTXMENU_TEXT: + menuType = _T("TextPopup"); + break; + case IDR_CTXMENU_LINK: + menuType = _T("LinkPopup"); + if (imgURI) + menuType = _T("ImageLinkPopup"); + break; + case IDR_CTXMENU_IMAGE: + menuType = _T("ImagePopup"); + break; + } + } + else { + switch (nIDResource) { + case IDR_CTXMENU_DOCUMENT: + menuType = _T("FrameDocumentPopup"); + if (imgURI) + menuType = _T("FrameDocumentImagePopup"); + break; + case IDR_CTXMENU_TEXT: + menuType = _T("FrameTextPopup"); + break; + case IDR_CTXMENU_LINK: + menuType = _T("FrameLinkPopup"); + if (imgURI) + menuType = _T("FrameImageLinkPopup"); + break; + case IDR_CTXMENU_IMAGE: + menuType = _T("FrameImagePopup"); + break; + } + } + } + + /* !!BAD HACK!! !!BAD HACK!! !!BAD HACK!! !!BAD HACK!! */ + if (nodeHack == 2) { + pThis->m_wndBrowserView.m_pGetNode = node; + return; + } + + + CMenu *ctxMenu = theApp.menus.GetMenu(menuType); + if(ctxMenu) + { + POINT cursorPos; + GetCursorPos(&cursorPos); + + /* int offset = theApp.menus.GetOffset(ctxMenu); + + RECT desktopRect; + SystemParametersInfo(SPI_GETWORKAREA, NULL, &desktopRect, 0); + int menuHeight = 0; + unsigned int i; + MENUITEMINFO info; + for (i=0; iGetMenuItemCount(); i++) { + ctxMenu->GetMenuItemInfo(i, &info, TRUE); + if (info.fType & MFT_SEPARATOR) + menuHeight += 0; + else + menuHeight += GetSystemMetrics(SM_CYMENUSIZE); + } + if ( (int)(cursorPos.y - offset) < (int)(desktopRect.bottom - menuHeight) ){ + // we only do this if we're not too close to the bottom of the screen + cursorPos.y -= offset; + if (cursorPos.y < 0){ + cursorPos.y = 0; + } + } else if (cursorPos.y + menuHeight > desktopRect.bottom) { + cursorPos.y = desktopRect.bottom - menuHeight; + }*/ + + ctxMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cursorPos.x, cursorPos.y, pThis); + + } +} + +HWND CBrowserFrame::BrowserFrameGlueObj::GetBrowserFrameNativeWnd() +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + return pThis->m_hWnd; +} + +void CBrowserFrame::BrowserFrameGlueObj::UpdateSecurityStatus(PRInt32 aState) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + pThis->UpdateSecurityStatus(aState); +} + +void CBrowserFrame::BrowserFrameGlueObj::ShowTooltip(PRInt32 x, PRInt32 y, const TCHAR *text) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + if (!text) { + pThis->m_wndToolTip.Hide(); + // WORKAROUND: Because the tooltip is not erased correctly when using the mouse wheel + pThis->m_wndBrowserView.mBaseWindow->Repaint(PR_FALSE); + return; + } + + POINT point; + ::GetCursorPos(&point); + + pThis->m_wndBrowserView.ScreenToClient(&point); + point.y += GetSystemMetrics(SM_CYCURSOR)/2 + 4; // jump to below the cursor, otherwise we appear right on top of the cursor + + pThis->m_wndToolTip.Show(text, point.x, point.y); +} + +void CBrowserFrame::BrowserFrameGlueObj::FocusNextElement() { + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + nsCOMPtr focus = pThis->m_wndBrowserView.mWebBrowserFocus; + if (!focus) return; + + if (pThis->m_wndFindBar){ + focus->Deactivate(); + pThis->m_wndFindBar->SetFocus(); + } + else if (pThis->m_wndUrlBar.IsWindowVisible()) { + focus->Deactivate(); + ::SetFocus(pThis->m_wndUrlBar.m_hwndEdit); + } + else + focus->SetFocusAtFirstElement(); +} + +void CBrowserFrame::BrowserFrameGlueObj::FocusPrevElement() { + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + nsCOMPtr focus = pThis->m_wndBrowserView.mWebBrowserFocus; + if (!focus) return; + + if (pThis->m_wndUrlBar.IsWindowVisible()) { + focus->Deactivate(); + ::SetFocus(pThis->m_wndUrlBar.m_hwndEdit); + } + else + focus->SetFocusAtLastElement(); +} + +void CBrowserFrame::BrowserFrameGlueObj::MouseAction(nsIDOMNode *node) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + pThis->m_wndBrowserView.m_lastMouseActionNode = node; +} + +void CBrowserFrame::BrowserFrameGlueObj::PopupBlocked(const char* uri) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj) + + // Do nothing if an icon was set already or if the user + // don't want popup notification + if (!theApp.preferences.GetBool("browser.popups.showPopupBlocker", PR_TRUE) + || !pThis->m_wndBrowserView.m_csHostPopupBlocked.IsEmpty()) + return; + + pThis->m_wndStatusBar.AddIcon(ID_POPUP_BLOCKED_ICON); + HICON hTmpPopupIcon = + (HICON)::LoadImage(AfxGetResourceHandle(), + MAKEINTRESOURCE(IDI_POPUP_BLOCKED), IMAGE_ICON, 16,16,LR_LOADMAP3DCOLORS); + + CString tpText; + USES_CONVERSION; + const TCHAR* turi = A2CT(uri); + + tpText.Format(IDS_POPUP_BLOCKED, turi); + pThis->m_wndStatusBar.SetIconInfo(ID_POPUP_BLOCKED_ICON, hTmpPopupIcon, tpText); + + pThis->m_wndBrowserView.m_csHostPopupBlocked = turi; +} + +void CBrowserFrame::BrowserFrameGlueObj::SetFavIcon(nsIURI* favUri) +{ + METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj); +#ifdef INTERNAL_SITEICONS + if (favUri == nsnull) + { + // XXX Temporary set m_bDOMLoaded here + pThis->m_wndBrowserView.mbDOMLoaded = TRUE; + + // No site icon found then we're looking for a IE favicon + // Note that this can be called twice, when DOMContentLoaded + // is fired, and when the page finished to load. + // DOMContentLoaded is not fired when page are loaded from cache + // so I'm calling it also when the page is loaded to be sure we + // checked for an IE icon. + + if (pThis->m_wndBrowserView.m_IconUri!=nsnull) return; + + nsCOMPtr currentURI; + nsresult rv = pThis->m_wndBrowserView.mWebNav->GetCurrentURI(getter_AddRefs(currentURI)); + if(NS_FAILED(rv) || !currentURI) return; + + if (theApp.preferences.GetBool("browser.chrome.favicons", PR_TRUE)) + { + nsCOMPtr currentURI; + nsEmbedCString nsUri; + rv = pThis->m_wndBrowserView.mWebNav->GetCurrentURI(getter_AddRefs(currentURI)); + if (NS_FAILED(rv)) return; + + PRBool ishttp, b; + currentURI->SchemeIs("http", &b); + ishttp = b; + currentURI->SchemeIs("https", &b); + ishttp |= b; + + if (ishttp) + { + currentURI->Resolve(NS_LITERAL_CSTRING("/favicon.ico"), nsUri); + + nsCOMPtr iconURI; + rv = NewURI(getter_AddRefs(iconURI), nsUri); + if(NS_FAILED(rv) || !iconURI) return; + + pThis->m_wndBrowserView.m_IconUri = iconURI; + pThis->SetFavIcon(theApp.favicons.GetIcon(iconURI, TRUE)); + } + else + pThis->SetFavIcon(theApp.favicons.GetDefaultIcon()); + } + else + pThis->SetFavIcon(theApp.favicons.GetDefaultIcon()); + } + else + { + pThis->m_wndBrowserView.m_IconUri = favUri; + pThis->SetFavIcon(theApp.favicons.GetIcon(favUri, TRUE)); + } +#endif +} diff --git a/k-meleon/BrowserFrm.cpp b/k-meleon/BrowserFrm.cpp new file mode 100644 index 00000000..916eb72d --- /dev/null +++ b/k-meleon/BrowserFrm.cpp @@ -0,0 +1,1613 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * + * ***** END LICENSE BLOCK ***** */ + +// File Overview.... +// +// The typical MFC View, toolbar, statusbar creation done +// in CBrowserFrame::OnCreate() +// +// Code to update the Status/Tool bars in response to the +// Web page loading progress(called from methods in CBrowserImpl) +// +// SetupFrameChrome() determines what, if any, UI elements this Frame +// will sport based on the current "chromeMask" +// +// Also take a look at OnClose() which gets used when you close a browser +// window. This needs to be overrided mainly to handle supporting multiple +// browser frame windows via the "New Browser Window" menu item +// Without this being overridden the MFC framework handles the OnClose and +// shutsdown the complete application when a frame window is closed. +// In our case, we want the app to shutdown when the File/Exit menu is chosen +// +// Another key functionality this object implements is the IBrowserFrameGlue +// interface - that's the interface the Gecko embedding interfaces call +// upong to update the status bar etc. +// (Take a look at IBrowserFrameGlue.h for the interface definition and +// the BrowserFrm.h to see how we implement this interface - as a nested +// class) +// We pass this Glue object pointer to the CBrowserView object via the +// SetBrowserFrameGlue() method. The CBrowserView passes this on to the +// embedding interface implementaion +// +// Please note the use of the macro METHOD_PROLOGUE in the implementation +// of the nested BrowserFrameGlue object. Essentially what this macro does +// is to get you access to the outer (or the object which is containing the +// nested object) object via the pThis pointer. +// Refer to the AFXDISP.H file in VC++ include dirs +// +// Next suggested file to look at : BrowserView.cpp + +#include "stdafx.h" + +#include "BrowserFrm.h" +#include "BrowserView.h" +#include "ToolBarEx.h" +#include "KmeleonConst.h" +#include "PasswordViewerDlg.h" +#include "CookiesViewerDlg.h" +#include "Permissions.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CBrowserFrame + +IMPLEMENT_DYNAMIC(CBrowserFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CBrowserFrame, CFrameWnd) + //{{AFX_MSG_MAP(CBrowserFrame) + ON_WM_CREATE() + ON_WM_SETFOCUS() + ON_WM_SIZE() + ON_WM_MOVE() + ON_WM_CLOSE() + ON_WM_ACTIVATE() + ON_WM_SYSCOLORCHANGE() + ON_WM_SYSCOMMAND() + ON_WM_INITMENUPOPUP() + + ON_COMMAND(ID_SELECT_URL, OnSelectUrl) + ON_COMMAND(ID_WINDOW_NEXT, OnWindowNext) + ON_COMMAND(ID_WINDOW_PREV, OnWindowPrev) + + ON_MESSAGE(UWM_REFRESHMRULIST, RefreshMRUList) +#ifdef INTERNAL_SITEICONS + ON_MESSAGE(UWM_NEWSITEICON, OnNewSiteIcon) +#endif + ON_COMMAND(ID_CLOSE, CloseNothing) + ON_COMMAND_RANGE(TOOLBAR_MENU_START_ID, TOOLBAR_MENU_END_ID, ToggleToolBar) + ON_COMMAND(ID_TOOLBARS_LOCK, ToggleToolbarLock) + ON_COMMAND(ID_COOKIES_VIEWER, OnCookiesViewer) + ON_COMMAND(ID_PASSWORDS_VIEWER, OnPasswordsViewer) + ON_COMMAND(ID_COOKIE_PERM, OnCookiePermissions) + ON_COMMAND(ID_IMAGE_PERM, OnImagePermissions) + ON_COMMAND(ID_POPUP_PERM, OnPopupPermissions) + + ON_UPDATE_COMMAND_UI(ID_TOOLBARS_LOCK, OnUpdateToggleToolbarLock) +#ifdef INTERNAL_SIDEBAR + ON_COMMAND_RANGE(SIDEBAR_MENU_START_ID, SIDEBAR_MENU_END_ID, ToggleSideBar) + ON_UPDATE_COMMAND_UI_RANGE(SIDEBAR_MENU_START_ID, SIDEBAR_MENU_END_ID, OnUpdateSideBarMenu) +#endif + ON_UPDATE_COMMAND_UI_RANGE(TOOLBAR_MENU_START_ID, TOOLBAR_MENU_END_ID, OnUpdateToolBarMenu) + ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR, OnUpdateViewStatusBar) + ON_COMMAND(ID_EDIT_FIND, OnShowFindBar) + ON_COMMAND(ID_VIEW_STATUS_BAR, OnViewStatusBar) + ON_NOTIFY(RBN_LAYOUTCHANGED, AFX_IDW_REBAR, OnRbnLayoutChanged) + + ON_COMMAND(ID_EDIT_FINDNEXT, OnFindNext) + ON_COMMAND(ID_EDIT_FINDPREV, OnFindPrev) + ON_COMMAND(IDC_WRAP_AROUND, OnWrapAround) + ON_COMMAND(IDC_MATCH_CASE, OnMatchCase) + ON_COMMAND(IDC_HIGHLIGHT, OnHighlight) + +// ON_MESSAGE(WM_ENTERSIZEMOVE, OnEnterSizeMove) +// ON_MESSAGE(WM_EXITSIZEMOVE, OnExitSizeMove) + //}}AFX_MSG_MAP + +// ON_WM_MOVING() + ON_WM_DESTROY() +END_MESSAGE_MAP() + +#define PREF_TOOLBAND_LOCKED "kmeleon.general.toolbars_locked" + +CBitmap CBrowserFrame::m_bmpBack; + +///////////////////////////////////////////////////////////////////////////// +// CBrowserFrame construction/destruction + +CBrowserFrame::CBrowserFrame(PRUint32 chromeMask, LONG style = 0) +{ + // Save the chromeMask off. It'll be used + // later to determine whether this browser frame + // will have menubar, toolbar, statusbar etc. + + m_chromeMask = chromeMask; + m_style = style; + m_created = FALSE; + m_hSecurityIcon = NULL; + m_wndFindBar = NULL; + m_searchString = NULL; + m_wndLastFocused = NULL; + m_wndBrowserView = NULL; +} + +CBrowserFrame::~CBrowserFrame() +{ + if (m_hSecurityIcon) + DestroyIcon(m_hSecurityIcon); + if (m_wndFindBar) + delete m_wndFindBar; + if (m_searchString) + free(m_searchString); +} + +BOOL CBrowserFrame::PreTranslateMessage(MSG* pMsg) +{ + if (pMsg->message==WM_KEYDOWN) + { + if ( pMsg->wParam == VK_TAB && !(GetKeyState(VK_CONTROL) & 0x8000)) { + if (pMsg->hwnd == m_wndUrlBar.m_hwndEdit) { + if (GetKeyState(VK_SHIFT) & 0x8000) + if (m_wndFindBar) + m_wndFindBar->SetFocus(); + else { + CBrowserView* view = GetActiveView(); + if (view) view->GetBrowserWrapper()->FocusLastElement(); + } + else { + CBrowserView* view = GetActiveView(); + if (view) view->GetBrowserWrapper()->FocusFirstElement(); + } + return 1; + } + else if ( m_wndFindBar && (pMsg->hwnd == m_wndFindBar->m_cEdit.m_hWnd)) { + + if (GetKeyState(VK_SHIFT) & 0x8000) { + CBrowserView* view = GetActiveView(); + if (view) view->GetBrowserWrapper()->FocusLastElement(); + } + else if (m_wndUrlBar.IsWindowVisible()) + ::SetFocus(m_wndUrlBar.m_hwndEdit); + else { + CBrowserView* view = GetActiveView(); + if (view) view->GetBrowserWrapper()->FocusFirstElement(); + } + + return 1; + } + } + + // Prevent accels to interfere with input controls + else if (pMsg->wParam >= VK_END && pMsg->wParam <= VK_DOWN) { + if ( GetActiveView()->IsChild(GetFocus()) && GetActiveView()->GetBrowserWrapper()->InputHasFocus() ) + return 0; + } + else if (MapVirtualKey(pMsg->wParam, 2 /*MAPVK_VK_TO_CHAR*/) != 0) { + if (!(GetKeyState(VK_CONTROL) & 0x8000) && (GetActiveView()->IsChild(GetFocus()) && GetActiveView()->GetBrowserWrapper()->InputHasFocus())) + return 0; + } + + /* else if ( pMsg->wParam == VK_BACK ) { + if (m_wndBrowserView.InputHasFocus()) + return 0; + }*/ + + } else if ( pMsg->wParam == 0xff ) { + if ( (pMsg->lParam & 0x00ff0000) == 0x000b0000) { + GetActiveView()->GetBrowserWrapper()->ChangeTextSize(1); + return 1; + } + else if ( (pMsg->lParam & 0x00ff0000) == 0x00110000) { + GetActiveView()->GetBrowserWrapper()->ChangeTextSize(-1); + return 1; + } + } + return CFrameWnd::PreTranslateMessage(pMsg); +} + +void CBrowserFrame::OnClose() +{ + DWORD dwWaitResult; + dwWaitResult = WaitForSingleObject( theApp.m_hMutex, 1000L); + if (dwWaitResult != WAIT_OBJECT_0) { + return; + } + + // tell all our plugins that we are closing + if (!IsDialog()) + theApp.plugins.SendMessage("*", "* OnClose", "Close", (long)m_hWnd); + + // the browserframeglue will be deleted soon, so we set it to null so it won't try to access it after it's deleted. + //GetActiveView()->SetBrowserFrameGlue(NULL); + //GetActiveView()->SetBrowserGlue(NULL); + + if (theApp.m_pMostRecentBrowserFrame == this) { + CBrowserFrame* pFrame; + + POSITION pos = theApp.m_FrameWndLst.Find(this); + if (pos) theApp.m_FrameWndLst.GetPrev(pos); + + pFrame = pos ? + (CBrowserFrame *) theApp.m_FrameWndLst.GetPrev(pos) : // previous frame + (CBrowserFrame *) theApp.m_FrameWndLst.GetTail(); // last frame + + // if no other browser views exist, nullify the pointer + theApp.m_pMostRecentBrowserFrame = (pFrame != this) ? pFrame : NULL; + } + + SaveWindowPos(); + + + // XXX: Destroying the window with the findbar open, will activate + // it during destruction because I'm setting back the focus to the + // view, and m_pMostRecentBrowserFrame will point to an deleted + // object. + CBrowserFrame* pTemp = theApp.m_pMostRecentBrowserFrame; + + if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL)) + EndModalLoop(IDCANCEL); + else + DestroyWindow(); + + if (theApp.m_pMostRecentBrowserFrame == this) { + theApp.m_pMostRecentBrowserFrame = pTemp; + } + + ReleaseMutex(theApp.m_hMutex); +} + +void CBrowserFrame::OnDestroy() +{ + // if we don't do this, then our menu will be destroyed when the first window is. + // that's bad because our menu is shared between all windows + SetMenu(NULL); + + if (!IsDialog()) + theApp.plugins.SendMessage("*", "* OnClose", "Destroy", (long)m_hWnd); + + theApp.RemoveFrameFromList(this); + m_wndStatusBar.RemoveIcon(ID_SECURITY_STATE_ICON); + CFrameWnd::OnDestroy(); +} + + +// This is where the UrlBar, ToolBar, StatusBar, ProgressBar +// get created +// +int CBrowserFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + // Will be deleted in CBrowserView::PostNcDestroy() + m_wndBrowserView = new CBrowserView(); + + // tell all our plugins that we were created + if (!IsDialog()) + theApp.plugins.SendMessage("*", "* OnCreate", "Create", (long)this->m_hWnd, 0); + + // Create a ReBar window to which the toolbar and UrlBar + // will be added + BOOL hasLine = theApp.preferences.GetBool("kmeleon.display.toolbars_line", TRUE); + if (!m_wndReBar.Create(this, RBS_DBLCLKTOGGLE | RBS_VARHEIGHT | (hasLine ? RBS_BANDBORDERS:0))) + { + TRACE0("Failed to create ReBar\n"); + return -1; // fail to create + } + + // Pass "this" to the View for later callbacks + // and/or access to any public data members, if needed + // + m_wndBrowserView->SetBrowserFrame(this); + + // Pass on the BrowserFrameGlue also to the View which + // it will use during the Init() process after creation + // of the BrowserImpl obj. Essentially, the View object + // hooks up the Embedded browser's callbacks to the BrowserFrame + // via this BrowserFrameGlue object + //m_wndBrowserView.SetBrowserFrameGlue((PBROWSERFRAMEGLUE)&m_xBrowserFrameGlueObj); + m_wndBrowserView->SetBrowserGlue(new CBrowserGlue(this, m_wndBrowserView)); + + // create a view to occupy the client area of the frame + // This will be the view in which the embedded browser will + // be displayed in + if (!m_wndBrowserView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, + CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) + { + TRACE0("Failed to create view window\n"); + return -1; + } + + return InitLayout(); +} + +int CBrowserFrame::InitLayout() +{ + // create the URL bar (essentially a ComboBoxEx object) + if (!m_wndUrlBar.Create(CBS_DROPDOWN | WS_CHILD, CRect(0, 0, 200, 150), this, ID_URL_BAR)) + { + TRACE0("Failed to create URL Bar\n"); + return -1; // fail to create + } +#ifdef INTERNAL_SITEICONS + m_wndUrlBar.SetImageList(&theApp.favicons); +#endif + + // Load the Most Recently Used(MRU) Urls into the UrlBar + m_wndUrlBar.LoadMRUList(); + + // Create the animation control.. + BOOL bThrobber = TRUE; + if (!m_wndAnimate.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 10, 10), this, ID_THROBBER)) + { + TRACE0("Failed to create animation\n"); + bThrobber = FALSE; + } + + CString throbberPath; + theApp.FindSkinFile(throbberPath, _T("Throbber.avi")); + if (!m_wndAnimate.Open(throbberPath)) + bThrobber = FALSE; + + //Add the UrlBar and Throbber windows to the rebar + CString urlTitle; + urlTitle.LoadString(IDS_TOOLBAR_URL); + m_wndReBar.AddBar(&m_wndUrlBar, theApp.preferences.GetString("kmeleon.display.URLbarTitle", urlTitle)); + m_wndReBar.RegisterBand(m_wndUrlBar.m_hWnd, _T("URL Bar"), true); + + if (bThrobber) { + m_wndReBar.AddBar(&m_wndAnimate, NULL, NULL, RBBS_FIXEDSIZE | RBBS_FIXEDBMP); + m_wndReBar.RegisterBand(m_wndAnimate.m_hWnd, _T("Throbber"), false); + } + + if (!m_wndStatusBar.CreateEx(this)) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + // Create the progress bar as a child of the status bar. + // Note that the ItemRect which we'll get at this stage + // is bogus since the status bar panes are not fully + // positioned yet i.e. we'll be passing in an invalid rect + // to the Create function below + // The actual positioning of the progress bar will be done + // in response to OnSize() + RECT rc; + m_wndStatusBar.GetItemRect (m_wndStatusBar.CommandToIndex(ID_PROG_BAR), &rc); + if (!m_wndProgressBar.Create(WS_CHILD|PBS_SMOOTH, rc, &m_wndStatusBar, ID_PROG_BAR)) + { + TRACE0("Failed to create progress bar\n"); + return -1; // fail to create + } + + m_wndStatusBar.AddIcon(ID_SECURITY_STATE_ICON); + + if (!theApp.preferences.GetBool("kmeleon.display.statusbar", TRUE)) + m_wndStatusBar.ShowWindow(SW_HIDE); + + if (!IsDialog()) + theApp.plugins.SendMessage("*", "* OnCreate", "DoRebar", (long)m_wndReBar.GetReBarCtrl().m_hWnd); + + m_wndReBar.RestoreBandSizes(); + m_wndReBar.LockBars(theApp.preferences.GetBool(PREF_TOOLBAND_LOCKED, false)); + + // Create the tooltip window + m_wndToolTip.Create(this); + + // Also, set the padlock icon to be the insecure icon to begin with + UpdateSecurityStatus(nsIWebProgressListener::STATE_IS_INSECURE); + +#ifdef INTERNAL_SIDEBAR + // Create the side bar. Must be created last for proper layout calc + if (!m_wndSideBar.CreateEx(WS_EX_WINDOWEDGE, NULL, NULL, WS_CLIPSIBLINGS | WS_CHILD, CRect(0, 0, 0, 0), this, ID_SIDE_BAR , NULL)) + { + TRACE0("Failed to create SideBar\n"); + return -1; // fail to create + } + + theApp.plugins.SendMessage("*", "* OnCreate", "DoSidebar", (long)m_wndSideBar.m_hWnd); +#endif + + LoadBackImage(); + SetBackImage(); + + // Based on the "chromeMask" we were supplied during construction + // hide any requested UI elements - statusbar, menubar etc... + // Note that the window styles (WM_RESIZE etc) are set inside + // of PreCreateWindow() + + SetupFrameChrome(); + m_created = TRUE; + return 0; +} + +void CBrowserFrame::SetupFrameChrome() +{ + if(m_chromeMask == nsIWebBrowserChrome::CHROME_ALL) + return; + + if(! (m_chromeMask & nsIWebBrowserChrome::CHROME_TOOLBAR) && + ! (m_chromeMask & nsIWebBrowserChrome::CHROME_MENUBAR) && + ! (m_chromeMask & nsIWebBrowserChrome::CHROME_LOCATIONBAR) ) { + m_wndReBar.ShowWindow(SW_HIDE); // Hide the Rebar + SetMenu(NULL); + } + else { + if(! (m_chromeMask & nsIWebBrowserChrome::CHROME_TOOLBAR) ) { + int i = m_wndReBar.count(); + int iMenubar = m_wndReBar.FindByName(_T("Menu")); + int iUrlbar = m_wndReBar.FindByName(_T("URL Bar")); + while (i-- > 0) { + if (i != iMenubar && i != iUrlbar) + m_wndReBar.ShowBand(i, false); + } + m_wndReBar.lineup(); + m_wndReBar.LockBars(true); + } + + if(! (m_chromeMask & nsIWebBrowserChrome::CHROME_MENUBAR) ) { + SetMenu(NULL); // Hide the MenuBar + int iMenubar = m_wndReBar.FindByName(_T("Menu")); + if (iMenubar >= 0) + m_wndReBar.ShowBand(iMenubar, false); + } + + if(! (m_chromeMask & nsIWebBrowserChrome::CHROME_LOCATIONBAR) ) { + int iUrlbar = m_wndReBar.FindByName(_T("URL Bar")); + if (iUrlbar >= 0) + m_wndReBar.ShowBand(iUrlbar, false); + } + } + + if(! (m_chromeMask & nsIWebBrowserChrome::CHROME_STATUSBAR)) + m_wndStatusBar.ShowWindow(SW_HIDE); // Hide the StatusBar + + if (!(m_chromeMask & nsIWebBrowserChrome::CHROME_DEFAULT) && + !(m_chromeMask & nsIWebBrowserChrome::CHROME_SCROLLBARS)) + GetActiveView()->GetBrowserWrapper()->ShowScrollbars(FALSE); +} + +BOOL CBrowserFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + + //cs.lpszClass = BROWSER_WINDOW_CLASS; + cs.dwExStyle &= ~WS_EX_CLIENTEDGE; + + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CBrowserFrame message handlers +void CBrowserFrame::OnSetFocus(CWnd* pOldWnd) +{ + if (theApp.m_pMostRecentBrowserFrame != this) { + theApp.m_pMostRecentBrowserFrame = this; + + // update session history for the current window + PostMessage(UWM_UPDATESESSIONHISTORY, 0, 0); + } + + // forward focus to the browser window + if (GetActiveView()) GetActiveView()->SetFocus(); +} + +BOOL CBrowserFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) +{ + if (nCode == CN_COMMAND){ + if (pHandlerInfo && theApp.plugins.OnUpdate(nID)){ + return true; + } + } + + // Don't let MFC mess with plugin command + if (nCode == CN_UPDATE_COMMAND_UI && theApp.plugins.IsPluginCommand(nID)) { + ((CCmdUI*)pExtra)->m_bEnableChanged = TRUE; + return TRUE; + } + + // let the view have first crack at the command + CBrowserView* pView = GetActiveView(); + if (pView && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) + return TRUE; + + // otherwise, do default handling + return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); +} + +BOOL CBrowserFrame::OnCommand(WPARAM wParam, LPARAM lParam) +{ + // Intercept menu item click + if (HIWORD(wParam) == 0 && lParam == 0) + if (theApp.menus.MenuCommand(LOWORD(wParam))) + return TRUE; + + return CFrameWnd::OnCommand(wParam, lParam); +} + +// Needed to properly position/resize the progress bar +// +void CBrowserFrame::OnSize(UINT nType, int cx, int cy) +{ + CFrameWnd::OnSize(nType, cx, cy); + + // Get the ItemRect of the status bar's Pane 0 + // That's where the progress bar will be located + RECT rc; + if (m_wndStatusBar.m_hWnd) + m_wndStatusBar.GetItemRect(m_wndStatusBar.CommandToIndex(ID_PROG_BAR), &rc); + + // Move the progress bar into it's correct location + // + if (m_wndProgressBar.m_hWnd) + m_wndProgressBar.MoveWindow(&rc); + + if (m_created) SaveWindowPos(); + + // Fix rebar redrawing bug when xp themes are enabled + // and the background image is disabled and the the tabbar is fixed. + m_wndReBar.RedrawWindow(0, 0, RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE); +} + +void CBrowserFrame::SaveWindowPos() +{ + // only record the window size for non-popup windows + if (IsPopup() || IsDialog()) + return; + + WINDOWPLACEMENT wp; + wp.length = sizeof (WINDOWPLACEMENT); + GetWindowPlacement(&wp); + + if (wp.showCmd == SW_SHOWMAXIMIZED) + // record the maximized state + theApp.preferences.bMaximized = true; + else if (wp.showCmd == SW_SHOWNORMAL) { + // record the window size/pos + theApp.preferences.bMaximized = false; + + RECT rc; // = wp.rcNormalPosition; + GetWindowRect(&rc); + if (rc.left >= 0 && rc.top >= 0 ) { + theApp.preferences.windowWidth = rc.right - rc.left; + theApp.preferences.windowHeight = rc.bottom - rc.top; + theApp.preferences.windowXPos = rc.left; + theApp.preferences.windowYPos = rc.top; + } + } + +} + +#if 0 +void CBrowserFrame::OnMove(int x, int y) +{ + CFrameWnd::OnMove(x, y); + + WINDOWPLACEMENT wp; + wp.length = sizeof (WINDOWPLACEMENT); + GetWindowPlacement(&wp); + + // only record the window position for non-popup windows + if (!(m_style & WS_POPUP) && (wp.showCmd != SW_SHOWMAXIMIZED)){ + RECT rc; + + GetWindowRect(&rc); + if (rc.left > 0 && rc.top > 0 ) { + theApp.preferences.windowWidth = rc.right - rc.left; + theApp.preferences.windowHeight = rc.bottom - rc.top; + theApp.preferences.windowXPos = rc.left; + theApp.preferences.windowYPos = rc.top; + } + } +} +#endif + +#ifdef _DEBUG +void CBrowserFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CBrowserFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +void CBrowserFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) +{ + if (nState != WA_INACTIVE && theApp.m_pMostRecentBrowserFrame != this) { + theApp.m_pMostRecentBrowserFrame = this; + + // update session history for the current window + PostMessage(UWM_UPDATESESSIONHISTORY, 0, 0); + } + + CFrameWnd::OnActivate(nState, pWndOther, bMinimized); + if (pWndOther == this) + return; + + if(bMinimized) // This isn't an activate event that Gecko cares about + { + // When we get there, the focus is already lost !! + // So CBrowserFrame::OnSysCommand take care of it + return; + } + + CBrowserView* view = GetActiveView(); + if (!view) + return; + + switch(nState) { + case WA_ACTIVE: + case WA_CLICKACTIVE: + + // The window dirrectly inside the view always change o_o breaking + // this code so I'm testing if the windows still exist + if (!IsWindow(m_wndLastFocused) || !m_wndLastFocused || + m_wndLastFocused == view->GetSafeHwnd() || + ::IsChild(view->m_hWnd, m_wndLastFocused)) { + view->Activate(TRUE); + } + else + ::SetFocus(m_wndLastFocused); + break; + case WA_INACTIVE: + m_wndLastFocused = ::GetFocus(); + if ( ::IsChild(view->m_hWnd, m_wndLastFocused) + || m_wndLastFocused == view->GetSafeHwnd()) + view->Activate(FALSE); + + break; + default: + break; + } + // m_wndBrowserView.Activate(nState, pWndOther, bMinimized); +} + +// CMyStatusBar Class +// The current implementation is bad but enough for what I want to do now. +CMyStatusBar::CMyStatusBar() +{ +} + +CMyStatusBar::~CMyStatusBar() +{ + int count = arrIcons.GetSize(); + for (int i=0; ihIcon) DestroyIcon(ii->hIcon); + } +} + +void CMyStatusBar::RefreshPanes() +{ + if (!m_hWnd) return; + int count = arrIcons.GetSize(), i; + + CString statusText = GetPaneText(0); + UINT* indicators = new UINT[2+count]; + indicators[0] = ID_SEPARATOR; + indicators[1] = ID_PROG_BAR; + + for (i=2;im_wndProgressBar.MoveWindow(&rc); + + delete indicators; +} + +BOOL CMyStatusBar::RemoveIcon(UINT nID) +{ + BOOL done = FALSE; + + for (int i=0; ihIcon); + arrIcons.RemoveAt(i); + done = TRUE; + break; + } + } + if (done) + RefreshPanes(); + + return done; +} + +BOOL CMyStatusBar::SetIconInfo(UINT nID, HICON hIcon, LPCTSTR tpText) +{ + for (int i=0; icsTpText = tpText; + if (ii->hIcon == hIcon) { + int index = CommandToIndex(nID); + if (tpText) GetStatusBarCtrl().SetTipText(index, tpText); + } + else { + if (ii->hIcon) DestroyIcon(ii->hIcon); + ii->hIcon = hIcon; + + // Better way to get the width ? + BITMAP bm; + ICONINFO iconinfo; + GetIconInfo(hIcon, &iconinfo); + GetObject(iconinfo.hbmMask, sizeof(BITMAP), &bm); + ii->lWidth = bm.bmWidth; + DeleteObject(iconinfo.hbmColor); + DeleteObject(iconinfo.hbmMask); + + /*int index = CommandToIndex(nID); + SetPaneInfo(index, nID, SBPS_NORMAL|SBPS_NOBORDERS, ii->lWidth); + if (hIcon) GetStatusBarCtrl().SetIcon(index, hIcon); + if (tpText) GetStatusBarCtrl().SetTipText(index, tpText); + RedrawWindow();*/ + + // Why do I have to refresh the panes ? + RefreshPanes(); + } + return TRUE; + } + } + } + return FALSE; +} + +BOOL CMyStatusBar::AddIcon(UINT nID) +{ + BOOL idOk = TRUE; + int count = arrIcons.GetSize(); + for (int i=0; i1 && r->right-r->left < width) r->right = r->left+width+GetSystemMetrics(SM_CXEDGE); +} + +void CMyStatusBar::OnLButtonDown(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(WM_COMMAND, id, 0); + GetParentFrame()->SendMessage(SB_LBUTTONDOWN, id, 0); + return; + } + + CStatusBar::OnLButtonDown(nFlags, point); +} + +void CMyStatusBar::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(SB_LBUTTONDBLCLK, id, 0); + return; + } + + CStatusBar::OnLButtonDblClk(nFlags, point); +} + +void CMyStatusBar::OnMButtonDown(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(SB_MBUTTONDOWN, id, 0); + return; + } + + CStatusBar::OnMButtonDown(nFlags, point); +} + +void CMyStatusBar::OnMButtonDblClk(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(SB_MBUTTONDBLCLK, id, 0); + return; + } + + CStatusBar::OnMButtonDblClk(nFlags, point); +} + +void CMyStatusBar::OnRButtonDblClk(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(SB_RBUTTONDBLCLK, id, 0); + return; + } + + CStatusBar::OnRButtonDblClk(nFlags, point); +} + +void CMyStatusBar::OnRButtonDown(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(SB_RBUTTONDOWN, id, 0); + return; + } + + CStatusBar::OnRButtonDown(nFlags, point); +} + +void CMyStatusBar::OnLButtonUp(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(SB_LBUTTONUP, id, 0); + return; + } + + CStatusBar::OnLButtonUp(nFlags, point); +} + +void CMyStatusBar::OnRButtonUp(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(SB_RBUTTONUP, id, 0); + return; + } + + CStatusBar::OnRButtonUp(nFlags, point); +} + +void CMyStatusBar::OnMButtonUp(UINT nFlags, CPoint point) +{ + int id = HitTest(point); + if (id != -1 ) { + GetParentFrame()->SendMessage(SB_MBUTTONUP, id, 0); + return; + } + + CStatusBar::OnMButtonUp(nFlags, point); +} + +int CMyStatusBar::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CStatusBar::OnCreate(lpCreateStruct) == -1) + return -1; + + // Set the default status bar font, I wonder why windows doesn't + // set it automatically + NONCLIENTMETRICS ncm ; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&ncm,0)) + return FALSE; + + if (m_statusFont.CreateFontIndirect(&ncm.lfStatusFont)) + SetFont(&m_statusFont); + + UINT indicators[2] = {ID_SEPARATOR, ID_PROG_BAR}; + SetIndicators(indicators, 2); + SetPaneStyle(0, SBPS_STRETCH); + return 0; +} + +int CMyStatusBar::HitTest(POINT point) +{ + // Check to see if the mouse click was within one of the icon + RECT rc; + int count = arrIcons.GetSize(); + for (int i=0;im_wndReBar.ToggleVisibility(uID - TOOLBAR_MENU_START_ID); + } +} + +void CBrowserFrame::ToggleToolbarLock() +{ + BOOL locked = theApp.preferences.GetBool(PREF_TOOLBAND_LOCKED, false); + locked = !locked; + theApp.preferences.SetBool(PREF_TOOLBAND_LOCKED, locked); + CBrowserFrame* pBrowserFrame; + POSITION pos = theApp.m_FrameWndLst.GetHeadPosition(); + while( pos != NULL ) { + pBrowserFrame = (CBrowserFrame *) theApp.m_FrameWndLst.GetNext(pos); + pBrowserFrame->m_wndReBar.LockBars(locked); + } +} + +#ifdef INTERNAL_SIDEBAR +void CBrowserFrame::ToggleSideBar(UINT uID) +{ + m_wndSideBar.ToggleVisibility(uID - SIDEBAR_MENU_START_ID); +} + +void CBrowserFrame::OnUpdateSideBarMenu(CCmdUI* pCmdUI) +{ + if (m_wndSideBar.GetCurrent() == pCmdUI->m_nID) + pCmdUI->SetCheck(true); + else + pCmdUI->SetCheck(false); +} +#endif + +void CBrowserFrame::OnUpdateToolBarMenu(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( + m_wndReBar.GetVisibility(pCmdUI->m_nID - TOOLBAR_MENU_START_ID) + ); +} + +void CBrowserFrame::OnUpdateToggleToolbarLock(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(theApp.preferences.GetBool(PREF_TOOLBAND_LOCKED, false)); +} + + +BOOL CALLBACK EnumToolbar(HWND hwnd, LPARAM lParam) +{ + TCHAR pszName[20]; + GetClassName(hwnd, pszName, 20); + if ( GetParent(hwnd) == GetParent((HWND)lParam) && _tcscmp(TOOLBARCLASSNAME, pszName) == 0 + && ( (GetWindowLong(hwnd, GWL_STYLE) & CCS_BOTTOM) == CCS_BOTTOM)) + { + SetWindowPos((HWND)lParam, hwnd ,0,0,0,0,SWP_NOMOVE); + //return FALSE; + } + return TRUE; +} + +// create a linked list of CToolBarEx controls, return the hwnd +HWND CBrowserFrame::CreateToolbar(UINT style) { + return m_tbList.Add(this, style); +} + +#include "nsITypeAheadFind.h" +#include ".\browserfrm.h" + +void CBrowserFrame::OnShowFindBar() +{ + // When the the user chooses the Find menu item + // and if a Find dlg. is already being shown + // just set focus to the existing dlg instead of + // creating a new one + if(m_wndFindBar) + { + m_wndFindBar->SetFocus(); + return; + } + +#ifdef FINDBAR_USE_TYPEAHEAD + nsresult rv; + nsCOMPtr tafinder = do_GetService(NS_TYPEAHEADFIND_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) + { + PRBool b; + tafinder->GetIsActive(&b); + if (b == PR_FALSE) + { + nsCOMPtr dom(do_GetInterface(GetActiveView()->mWebBrowser)); + tafinder->StartNewFind(dom, PR_FALSE); + } + } +#endif + + // Create the find bar + m_wndFindBar = new CFindRebar(m_searchString, + theApp.preferences.bFindMatchCase, + FALSE, + theApp.preferences.bFindWrapAround, + theApp.preferences.bFindHighlight, this); + + m_wndFindBar->Create(this, CBRS_BOTTOM); + + // It must stay above the sidebar + m_wndFindBar->SetWindowPos(&m_wndStatusBar ,0,0,0,0,SWP_NOMOVE); + + // And above any bottom toolbar ? + EnumChildWindows(m_hWnd, EnumToolbar, (LPARAM)m_wndFindBar->m_hWnd); + + // Update the layout + RecalcLayout(); +} + +void CBrowserFrame::ClearFindBar() +{ + delete m_wndFindBar; + m_wndFindBar = NULL; + RecalcLayout(); + // WORKAROUND: Setting back the focus to gecko + //m_wndBrowserView.mBaseWindow->SetFocus(); // WHY IT DOES NOTHING ? + GetActiveView()->Activate(TRUE); +} + +#ifdef INTERNAL_SITEICONS +void CBrowserFrame::SetFavIcon(int iIcon) +{ + COMBOBOXEXITEM cb; + cb.mask = CBEIF_IMAGE|CBEIF_SELECTEDIMAGE; + cb.iSelectedImage = cb.iImage = iIcon; + cb.iItem = -1; + m_wndUrlBar.SetItem(&cb); + + if (theApp.preferences.GetBool("kmeleon.favicons.titleBar", FALSE)) + { + HICON icon = GetIcon(FALSE); + if (icon!=theApp.GetDefaultIcon(FALSE)) + DestroyIcon(icon); + + if (iIcon == theApp.favicons.GetDefaultIcon()) + { + SetIcon(theApp.GetDefaultIcon(TRUE), TRUE); + SetIcon(theApp.GetDefaultIcon(FALSE), FALSE); + } else { + icon = theApp.favicons.ExtractIcon(iIcon); + SetIcon(icon, FALSE); + SetIcon(icon, TRUE); + } + } +/* cb.iSelectedImage = cb.iImage = I_IMAGECALLBACK; + cb.iItem = 0; + mpBrowserFrame->m_wndUrlBar.SetItem(&cb); + cb.iItem = 1; + mpBrowserFrame->m_wndUrlBar.SetItem(&cb); + cb.iItem = 2; + mpBrowserFrame->m_wndUrlBar.SetItem(&cb);*/ +} + +LRESULT CBrowserFrame::OnNewSiteIcon(WPARAM url, LPARAM index) +{ + int i = theApp.favicons.GetIcon(GetActiveView()->GetBrowserGlue()->mIconURI); + + if (i==-1) {// The icon doesn't exist anymore, was deleted + GetActiveView()->GetBrowserGlue()->mIconURI = nsnull; + SetFavIcon(theApp.favicons.GetDefaultIcon()); + } + else + if (index==-1 || index == i) SetFavIcon(i); + + return 0; +} +#endif + +void CBrowserFrame::OnSysCommand(UINT nID, LPARAM lParam) +{ + if (nID == SC_MINIMIZE) { + // We're taking care of the focus here, because it will + // be lost after that and not correctly memorized. + m_wndLastFocused = ::GetFocus(); + if (::IsChild(GetActiveView()->m_hWnd, m_wndLastFocused)) + GetActiveView()->Activate(FALSE); + } + + CFrameWnd::OnSysCommand(nID, lParam); +} + +INT_PTR CBrowserFrame::DoModal() +{ + CWinApp* pApp = AfxGetApp(); + if (pApp != NULL) + pApp->EnableModeless(FALSE); + + HWND hWndTop = NULL; + HWND hWndParent = CWnd::GetSafeOwner_(GetParent()->GetSafeHwnd(), &hWndTop); + + BOOL bEnableParent = FALSE; + if (hWndParent && hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent)) + { + ::EnableWindow(hWndParent, FALSE); + ::EnableWindow(m_hWnd, TRUE); + bEnableParent = TRUE; + } + + m_nFlags |= WF_CONTINUEMODAL; + RunModalLoop(0); + + if (bEnableParent) + ::EnableWindow(hWndParent, TRUE); + if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd) + ::SetActiveWindow(hWndParent); + + if (::IsWindow(hWndTop)) + ::EnableWindow(hWndTop, TRUE); + + if (pApp != NULL) + pApp->EnableModeless(TRUE); + + INT_PTR res = m_nModalResult; + DestroyWindow(); + return res; +} + +void CBrowserFrame::OnRbnLayoutChanged(NMHDR *pNMHDR, LRESULT *pResult) +{ + *pResult = 0; + + if ( !(m_chromeMask & nsIWebBrowserChrome::CHROME_TOOLBAR) || + !(m_chromeMask & nsIWebBrowserChrome::CHROME_MENUBAR) || + !(m_chromeMask & nsIWebBrowserChrome::CHROME_LOCATIONBAR) ) + return; + + m_wndReBar.SaveBandSizes(); + CBrowserFrame* pBrowserFrame; + POSITION pos = theApp.m_FrameWndLst.GetHeadPosition(); + while( pos != NULL ) { + pBrowserFrame = (CBrowserFrame *) theApp.m_FrameWndLst.GetNext(pos); + pBrowserFrame->m_wndReBar.RestoreBandSizes(); + } +} + +HACCEL CBrowserFrame::GetDefaultAccelerator() +{ + if (!(m_chromeMask & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) + return theApp.accel.GetTable(); + return NULL; +} + +void CBrowserFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) +{ + // This will rebuild the menu if needed + theApp.menus.Activate(pPopupMenu); + CFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); +} + +void CBrowserFrame::OnCookiesViewer() +{ + CCookiesViewerDlg dlg(this); + dlg.DoModal(); +} + +void CBrowserFrame::OnPasswordsViewer() +{ + CPasswordViewerDlg dlg(this); + dlg.DoModal(); +} + +void CBrowserFrame::OnCookiePermissions() { + CPermissionsDlg dlg("cookie", this); + dlg.DoModal(); +} + +void CBrowserFrame::OnImagePermissions() { + CPermissionsDlg dlg("image", this); + dlg.DoModal(); +} + +void CBrowserFrame::OnPopupPermissions() { + CPermissionsDlg dlg("popup", this); + dlg.DoModal(); +} + +void CBrowserFrame::OnWindowPrev() +{ + CFrameWnd* pFrame; + POSITION pos = theApp.m_FrameWndLst.Find(this); + theApp.m_FrameWndLst.GetNext(pos); + if (pos) pFrame = (CFrameWnd *) theApp.m_FrameWndLst.GetNext(pos); + else pFrame = (CFrameWnd *) theApp.m_FrameWndLst.GetHead(); + + pFrame->ActivateFrame(); +} + +void CBrowserFrame::OnWindowNext() +{ + CFrameWnd* pFrame; + POSITION pos = theApp.m_FrameWndLst.Find(this); + theApp.m_FrameWndLst.GetPrev(pos); + if (pos) pFrame = (CFrameWnd *) theApp.m_FrameWndLst.GetPrev(pos); + else pFrame = (CFrameWnd *) theApp.m_FrameWndLst.GetTail(); + + pFrame->ActivateFrame(); +} + +void CBrowserFrame::OnSelectUrl() +{ + m_wndUrlBar.SetFocus(); +} + +void CBrowserFrame::OnUpdateViewStatusBar(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_wndStatusBar.IsWindowVisible()); +} + +void CBrowserFrame::OnFind(BOOL backward) +{ + CBrowserView* view = GetActiveView(); + if (!view) return; + + CBrowserWrapper* wrapper = view->GetBrowserWrapper(); + + const wchar_t* searchString = NULL; + BOOL ahead = FALSE; + if (m_wndFindBar) { + searchString = m_wndFindBar->GetUFindString(); + ahead = m_wndFindBar->StartSel(); + if (m_searchString) free(m_searchString); + m_searchString = wcsdup(searchString); + } + + BOOL didFind = wrapper->Find(searchString, + theApp.preferences.bFindMatchCase, + theApp.preferences.bFindWrapAround, + backward, ahead); + + if (!didFind) { + if (!m_wndFindBar) OnShowFindBar(); + if (m_wndFindBar && m_searchString && *m_searchString) + m_wndFindBar->OnNotFound(); + } else if (m_wndFindBar) + m_wndFindBar->OnFound(); +} + +void CBrowserFrame::OnFindNext() +{ + OnFind(FALSE); +} + +void CBrowserFrame::OnFindPrev() +{ + OnFind(TRUE); +} + +void CBrowserFrame::OnWrapAround() +{ + if (!m_wndFindBar) + theApp.preferences.bFindWrapAround = !theApp.preferences.bFindWrapAround; + else + theApp.preferences.bFindWrapAround = m_wndFindBar->WrapAround(); +} + +void CBrowserFrame::OnMatchCase() +{ + if (theApp.preferences.bFindHighlight) + GetActiveView()->Highlight(NULL, theApp.preferences.bFindMatchCase); + + if (!m_wndFindBar) + theApp.preferences.bFindMatchCase = !theApp.preferences.bFindMatchCase; + else + theApp.preferences.bFindMatchCase = m_wndFindBar->MatchCase(); + + if (theApp.preferences.bFindHighlight) + GetActiveView()->Highlight(m_searchString, theApp.preferences.bFindMatchCase); +} + +void CBrowserFrame::OnHighlight() +{ + theApp.preferences.bFindHighlight = m_wndFindBar->Highlight(); + GetActiveView()->Highlight(NULL, theApp.preferences.bFindMatchCase); + if (theApp.preferences.bFindHighlight) + GetActiveView()->Highlight(m_searchString, theApp.preferences.bFindMatchCase); +} + +void CBrowserFrame::OpenURL(LPCTSTR url, LPCTSTR refferer, BOOL focusUrl, BOOL allowFixup) +{ + GetActiveView()->OpenURL(url, refferer, allowFixup); + if (focusUrl) m_wndUrlBar.SetFocus(); +} + +void CBrowserFrame::OnViewStatusBar() +{ + if (m_wndStatusBar.IsVisible()) { + theApp.preferences.SetBool("kmeleon.display.statusbar", FALSE); + m_wndStatusBar.ShowWindow(SW_HIDE); + } else { + theApp.preferences.SetBool("kmeleon.display.statusbar", TRUE); + m_wndStatusBar.ShowWindow(SW_SHOW); + } + RecalcLayout(); +} + +/****************************************************************************/ + +void CBrowserFrame::UpdateSecurityStatus(PRInt32 aState) +{ + UINT tpTextId, iconResID; + + if(aState & nsIWebProgressListener::STATE_IS_INSECURE) { + iconResID = IDI_SECURITY_UNLOCK; + m_wndUrlBar.Highlight(0); + tpTextId = IDS_SECURITY_UNLOCK; + } + else if(aState & nsIWebProgressListener::STATE_IS_BROKEN) { + iconResID = IDI_SECURITY_BROKEN; + m_wndUrlBar.Highlight(2); + tpTextId = IDS_SECURITY_BROKEN; + } + else if(aState & nsIWebProgressListener::STATE_IS_SECURE) { + iconResID = IDI_SECURITY_LOCK; + m_wndUrlBar.Highlight(1); + tpTextId = IDS_SECURITY_LOCK; + } + else + { + ASSERT(FALSE); + return; + } + + CString tpText; + tpText.LoadString(tpTextId); + + HICON hTmpSecurityIcon = + (HICON)::LoadImage(AfxGetResourceHandle(), + MAKEINTRESOURCE(iconResID), IMAGE_ICON, 16,16,LR_LOADMAP3DCOLORS); + + m_wndStatusBar.SetIconInfo(ID_SECURITY_STATE_ICON, hTmpSecurityIcon, tpText); +} + +void CBrowserFrame::UpdateStatus(LPCTSTR aStatus) +{ + m_wndStatusBar.SetPaneText(0, aStatus); +} + +void CBrowserFrame::UpdateSiteIcon(int aIcon) +{ + SetFavIcon(aIcon); +} + +void CBrowserFrame::UpdateLocation(LPCTSTR aLocation, BOOL aIgnoreTyping) +{ + if (!aLocation) return; + // XXX Since Mozilla 1.8.0.2 about:blank is always passed here + // before anything else, broking stuffs, so ignore it! + //if ( _tcscmp(aLocation, _T("about:blank")) == 0 && +// m_wndUrlBar.GetEnteredURL().GetLength()) + //return; + + m_wndUrlBar.SetCurrentURL(aLocation, aIgnoreTyping); +} + +void CBrowserFrame::UpdateProgress(int aCurrent, int aMax) +{ + m_wndProgressBar.SetRange32(0, aMax); + m_wndProgressBar.SetPos(aCurrent); +} + +void CBrowserFrame::UpdateLoading(BOOL aLoading) +{ + if (!aLoading) { + m_wndAnimate.Stop(); + m_wndAnimate.Seek(0); + m_wndProgressBar.ShowWindow(SW_HIDE); + + CString szUrl = m_wndUrlBar.GetEnteredURL(); + + if (szUrl.CompareNoCase(_T("about:blank"))==0) + m_wndUrlBar.SetFocus(); + } + else { + m_wndAnimate.Play(0, -1, -1); + m_wndProgressBar.ShowWindow(SW_SHOW); + } +} + +void CBrowserFrame::UpdateTitle(LPCTSTR aTitle) +{ + CString appTitle; + appTitle.LoadString(AFX_IDS_APP_TITLE); + appTitle = theApp.preferences.GetString("kmeleon.display.title", appTitle); + + CString title = aTitle; + if (title.IsEmpty()) + title = GetActiveView()->GetBrowserGlue()->mLocation; + + if (!appTitle.IsEmpty()) + title += _T(" (") + appTitle + _T(")"); + + SetWindowText(title); + theApp.UpdateWindowListMenu(); +} + +void CBrowserFrame::UpdatePopupNotification(LPCTSTR uri) +{ + if (uri && *uri) { + if (m_wndStatusBar.AddIcon(ID_POPUP_BLOCKED_ICON)) { + HICON hTmpPopupIcon = + (HICON)::LoadImage(AfxGetResourceHandle(), + MAKEINTRESOURCE(IDI_POPUP_BLOCKED), IMAGE_ICON, 16,16,LR_LOADMAP3DCOLORS); + + CString tpText; + tpText.Format(IDS_POPUP_BLOCKED, uri); + m_wndStatusBar.SetIconInfo(ID_POPUP_BLOCKED_ICON, hTmpPopupIcon, tpText); + } + } + else + m_wndStatusBar.RemoveIcon(ID_POPUP_BLOCKED_ICON); +} \ No newline at end of file diff --git a/k-meleon/BrowserFrm.h b/k-meleon/BrowserFrm.h new file mode 100644 index 00000000..423039ff --- /dev/null +++ b/k-meleon/BrowserFrm.h @@ -0,0 +1,358 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * + * ***** END LICENSE BLOCK ***** */ + +// BrowserFrm.h : interface of the CBrowserFrame class +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef _IBROWSERFRM_H +#define _IBROWSERFRM_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "IBrowserFrameGlue.h" +#include "ToolBarEx.h" +#include "KmeleonConst.h" +#include "ReBarEx.h" +#include "Tooltips.h" +#include "urlbar.h" +#include "sidebar.h" +#include "Dialogs.h" + +class CBrowserView; + +class CBrowserGlue : public IBrowserGlue +{ +public: + CString mTitle; + CString mLocation; + CString mStatusText; + CString mPopupBlockedHost; + CString mPendingLocation; + int mIcon; + int mSecurityState; + BOOL mLoading; + BOOL mDOMLoaded; + int mProgressCurrent; + int mProgressMax; + + nsCOMPtr mIconURI; + nsCOMPtr mContextNode; + + CBrowserGlue(CBrowserFrame* frame, CBrowserView* view) : mIcon(0), + mSecurityState(nsIWebProgressListener::STATE_IS_INSECURE), + mProgressCurrent(0), + mProgressMax(100), + mLoading(FALSE), + mDOMLoaded(FALSE), + mpBrowserFrame(frame), + mpBrowserView(view) + { + } + + virtual ~CBrowserGlue(); + + //SetFrame(CBrowserFrame* frame) {mpBrowserFrame = } + + NS_DECL_BROWSERGLUE; + +protected: + CBrowserFrame* mpBrowserFrame; + CBrowserView* mpBrowserView; +}; + +// CMyStatusBar class +class CMyStatusBar : public CStatusBar +{ +public: + CMyStatusBar(); + virtual ~CMyStatusBar(); + + BOOL RemoveIcon(UINT nID); + BOOL AddIcon(UINT nID); + BOOL SetIconInfo(UINT nID, HICON hIcon, LPCTSTR tpText = NULL); + void GetItemRect(UINT i, LPRECT r); + +protected: + struct icon_info + { + UINT nID; + HICON hIcon; + LONG lWidth; + CString csTpText; + }; + + CArray arrIcons; + CFont m_statusFont; + + void RefreshPanes(); + int HitTest(POINT point); + + DECLARE_MESSAGE_MAP() + + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); +public: + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonUp(UINT nFlags, CPoint point); +}; + +class CToolBarList; +class CToolBarItem { +friend class CToolBarList; +public: + CToolBarItem(CWnd *wnd, UINT style) + { + m_tb = new CToolBarEx; + int sstyle = WS_CHILD|WS_VISIBLE| (style&CCS_BOTTOM ? CBRS_ALIGN_BOTTOM : CBRS_ALIGN_TOP); + m_tb->CreateEx(wnd, style, sstyle); + m_next = NULL; + } + ~CToolBarItem() { + delete m_tb; + } +private: + CToolBarEx *m_tb; + CToolBarItem *m_next; +}; + +class CToolBarList { +public: + CToolBarList() { + m_head = NULL; + m_tail = NULL; + }; + ~CToolBarList() { + CToolBarItem *cur=m_head, *temp; + while (cur) { + temp = cur; + cur = cur->m_next; + delete temp; + } + } + HWND Add(CWnd *wnd, UINT style) + { + CToolBarItem *newTB = new CToolBarItem(wnd, style); + + if (!m_head) + m_head = m_tail = newTB; + else { + m_tail->m_next = newTB; + m_tail = newTB; + } + return newTB->m_tb->m_hWnd; + } +private: + CToolBarItem *m_head; + CToolBarItem *m_tail; +}; + + + +class CBrowserFrame : public CFrameWnd +{ +protected: + // The view inside which the embedded browser will + // be displayed in + CBrowserView* m_wndBrowserView; + + CAnimateCtrl m_wndAnimate; + CFindRebar* m_wndFindBar; + wchar_t* m_searchString; + + HICON m_hSecurityIcon; + + // This specifies what UI elements this frame will support + // w.r.t. toolbar, statusbar, urlbar etc. + PRUint32 m_chromeMask; + LONG m_style; + + BOOL m_created; // set after we are created + CToolBarList m_tbList; + + int m_cx; + int m_cy; + +public: + CUrlBar m_wndUrlBar; + // note: right now it's just a CStatic, but eventually it will become something better + CKmToolTip m_wndToolTip; + CReBarEx m_wndReBar; + CMyStatusBar m_wndStatusBar; + CProgressCtrl m_wndProgressBar; + HWND m_wndLastFocused; + +#ifdef INTERNAL_SIDEBAR + CSideBar m_wndSideBar; +#endif + + static CBitmap m_bmpBack; + friend CBrowserGlue; + DECLARE_DYNAMIC(CBrowserFrame); + + CBrowserFrame(PRUint32 chromeMask, LONG style); + virtual ~CBrowserFrame(); + + void OpenURL(LPCTSTR url, LPCTSTR refferer = NULL, BOOL focusUrl = FALSE, BOOL allowFixup = TRUE); + + virtual CBrowserView* GetActiveView() { return m_wndBrowserView; } + BOOL IsDialog() { return (m_chromeMask & nsIWebBrowserChrome::CHROME_OPENAS_CHROME); } + BOOL IsPopup() { return (m_style & WS_POPUP); } + + void UpdateSecurityStatus(PRInt32 aState); + void UpdateStatus(LPCTSTR aStatus); + void UpdateSiteIcon(int aIcon); + void UpdateLocation(LPCTSTR aLocation, BOOL aIgnoreTyping = FALSE); + void UpdateProgress(int aCurrent, int aMax); + void UpdateLoading(BOOL aLoading); + void UpdateTitle(LPCTSTR aTitle); + void UpdatePopupNotification(LPCTSTR uri); + + void ClearFindBar(); + void CloseNothing(){} + INT_PTR DoModal(); + + HWND CreateToolbar(UINT style); + + + +protected: + int InitLayout(); + void SetupFrameChrome(); + + void LoadBackImage (); + void SetBackImage (); + void SaveWindowPos(); + void OnFind(BOOL backward = FALSE); +#ifdef INTERNAL_SITEICONS + void SetFavIcon(int iIcon); +#endif + + // + // This nested class implements the IBrowserFramGlue interface + // The Gecko embedding interfaces call on this interface + // to update the status bars etc. + // + /* class BrowserFrameGlueObj : public IBrowserFrameGlue + { + // + // NS_DECL_BROWSERFRAMEGLUE below is a macro which expands + // to the function prototypes of methods in IBrowserFrameGlue + // Take a look at IBrowserFrameGlue.h for this macro define + // + + NS_DECL_BROWSERFRAMEGLUE + + } m_xBrowserFrameGlueObj; + friend class BrowserFrameGlueObj;*/ + + + +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + + DECLARE_MESSAGE_MAP() + // Generated message map functions + //{{AFX_MSG(CBrowserFrame) + afx_msg void OnShowFindBar(); + afx_msg void OnClose(); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSetFocus(CWnd *pOldWnd); + afx_msg void OnSize(UINT nType, int cx, int cy); + // afx_msg void OnMove(int x, int y); + afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); + afx_msg void OnSysColorChange(); + + afx_msg void OnSelectUrl(); + afx_msg void OnWindowNext(); + afx_msg void OnWindowPrev(); + afx_msg LRESULT RefreshToolBarItem(WPARAM ItemID, LPARAM unused); + afx_msg LRESULT RefreshMRUList(WPARAM ItemID, LPARAM unused); + afx_msg void ToggleToolBar(UINT uID); + afx_msg void ToggleToolbarLock(); + afx_msg void OnUpdateToggleToolbarLock(CCmdUI* pCmdUI); + afx_msg void OnUpdateToolBarMenu(CCmdUI*); +#ifdef INTERNAL_SIDEBAR + afx_msg void ToggleSideBar(UINT uID); + afx_msg void OnUpdateSideBarMenu(CCmdUI*); +#endif +#ifdef INTERNAL_SITEICONS + afx_msg LRESULT OnNewSiteIcon(WPARAM url, LPARAM index); +#endif + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg LRESULT OnEnterSizeMove(WPARAM, LPARAM); + afx_msg LRESULT OnExitSizeMove(WPARAM, LPARAM); + afx_msg void OnRbnLayoutChanged(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); + afx_msg void OnUpdateViewStatusBar(CCmdUI* pCmdUI); + afx_msg void OnViewStatusBar(); + afx_msg void OnFindNext(); + afx_msg void OnFindPrev(); + afx_msg void OnWrapAround(); + afx_msg void OnMatchCase(); + afx_msg void OnHighlight(); + + afx_msg void OnCookiesViewer(); + afx_msg void OnPasswordsViewer(); + afx_msg void OnCookiePermissions(); + afx_msg void OnImagePermissions(); + afx_msg void OnPopupPermissions(); + afx_msg void OnMoving(UINT fwSide, LPRECT pRect); + afx_msg void OnDestroy(); + //}}AFX_MSG + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CBrowserFrame) + virtual HACCEL GetDefaultAccelerator(); + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); + virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); + //}}AFX_VIRTUAL +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif //_IBROWSERFRM_H diff --git a/k-meleon/BrowserFrmTab.cpp b/k-meleon/BrowserFrmTab.cpp new file mode 100644 index 00000000..108da0f8 --- /dev/null +++ b/k-meleon/BrowserFrmTab.cpp @@ -0,0 +1,876 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* +*/ + +#include "stdafx.h" +#include "BrowserFrm.h" +#include "BrowserFrmTab.h" + +class CBrowserGlueTab : public CBrowserGlue +{ +public: + CBrowserGlueTab(CBrowserFrame* frame, CBrowserView* view) : + CBrowserGlue(frame, view) + {} + + CBrowserWrapper* ReuseWindow(BOOL useCurrent) + { + if (mpBrowserFrame->IsPopup() || mpBrowserFrame->IsDialog()) + return NULL; + + if (useCurrent) + return mpBrowserView->GetBrowserWrapper(); + + CBrowserTab* tab = ((CBrowserFrmTab*)mpBrowserFrame)->CreateBrowserTab(); + if ( !theApp.preferences.GetBool("kmeleon.tabs.loadDivertedInBackground", FALSE) + && mpBrowserView == mpBrowserFrame->GetActiveView()) + ((CBrowserFrmTab*)mpBrowserFrame)->SetActiveBrowser(tab); + return tab->GetBrowserWrapper(); + } + + void SetBrowserTitle(LPCTSTR aTitle) + { + CBrowserGlue::SetBrowserTitle(aTitle); + if (!theApp.preferences.GetBool("kmeleon.tabs.useLoadingTitle", FALSE)) + ((CBrowserFrmTab*)mpBrowserFrame)->SetTabTitle((CBrowserTab*)mpBrowserView, aTitle); + } + + void SetFavIcon(nsIURI *favUri) + { + CBrowserGlue::SetFavIcon(favUri); + if (!theApp.preferences.GetBool("kmeleon.tabs.useLoadingIcon", TRUE)) { + mIcon = theApp.favicons.GetIcon(mIconURI); + ((CBrowserFrmTab*)mpBrowserFrame)->SetTabIcon((CBrowserTab*)mpBrowserView, mIcon); + } + } + + void UpdateBusyState(BOOL aBusy) + { + CBrowserGlue::UpdateBusyState(aBusy); + CString title; + + if (aBusy) { + title.LoadString(IDS_LOADING); + if (theApp.preferences.GetBool("kmeleon.tabs.useLoadingIcon", TRUE)) + ((CBrowserFrmTab*)mpBrowserFrame)->SetTabIcon((CBrowserTab*)mpBrowserView, theApp.favicons.GetLoadingIcon()); + } else { + mIcon = theApp.favicons.GetIcon(mIconURI); + ((CBrowserFrmTab*)mpBrowserFrame)->SetTabIcon((CBrowserTab*)mpBrowserView, mIcon); + if (mTitle.IsEmpty()) { + if (mLocation.IsEmpty() || mLocation.Compare(_T("about:blank")) == 0) + title.LoadString(IDS_EMPTY); + else + title = mLocation; + } + else title = mTitle; + } + + + ((CBrowserFrmTab*)mpBrowserFrame)->SetTabTitle((CBrowserTab*)mpBrowserView, title); + } + + void GetVisibility(BOOL *aVisible) + { + *aVisible = mpBrowserFrame->IsIconic() || + !mpBrowserFrame->IsWindowVisible() || + mpBrowserFrame->GetActiveView() != mpBrowserView ? PR_FALSE : PR_TRUE; + } + + void DestroyBrowserFrame() + { + CBrowserFrmTab* frame = ((CBrowserFrmTab*)mpBrowserFrame); + if (frame->GetTabCount()>1) + frame->CloseTab((CBrowserTab*)mpBrowserView); + else + frame->PostMessage(WM_CLOSE, -1, -1); + } + +}; + +IMPLEMENT_DYNAMIC(CBrowserFrmTab, CBrowserFrame) + +BEGIN_MESSAGE_MAP(CBrowserFrmTab, CBrowserFrame) + ON_WM_CREATE() + ON_WM_CLOSE() + ON_MESSAGE(WM_OPENTAB, OnOpenTab) + ON_MESSAGE(WM_CLOSETAB, OnCloseTab) + ON_COMMAND(ID_TAB_NEXT, OnNextTab) + ON_COMMAND(ID_TAB_PREV, OnPrevTab) + ON_COMMAND(ID_TAB_LAST, OnLastTab) + ON_COMMAND(ID_NEW_TAB, OnNewTab) + ON_COMMAND(ID_CLOSE_TAB, OnCloseTab) + ON_COMMAND(ID_CLOSE_ALLTAB, OnCloseAllTab) + ON_COMMAND(ID_CLOSE_ALLOTHERTAB, OnCloseAllOtherTab) + ON_UPDATE_COMMAND_UI_RANGE(TABS_START_ID, TABS_STOP_ID, OnUpdateTabs) + ON_COMMAND_RANGE(TABS_START_ID, TABS_STOP_ID, OnTabSelect) + ON_NOTIFY(TBN_BEGINDRAG, ID_TABS_BAR, OnTbnBeginDrag) + ON_MESSAGE(UWM_NEWSITEICON, OnNewSiteIcon) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText) +// ON_MESSAGE(UWM_GETFAVICON, OnGetFavIcon) + ON_WM_KEYDOWN() +END_MESSAGE_MAP() + +BOOL CBrowserFrmTab::OnToolTipText(UINT id, NMHDR* pNMHDR, LRESULT* pResult) +{ + static char* tip = NULL; + static WCHAR* wtip = NULL; + + int tooltipWidth = theApp.preferences.GetInt("kmeleon.tabs.tooltipWidth", 100); + + if (pNMHDR->idFrom < TABS_START_ID || pNMHDR->idFrom > TABS_STOP_ID) + return CFrameWnd::OnToolTipText(id, pNMHDR, pResult); + + CBrowserTab* tab = (CBrowserTab*)m_Tabs[IDTOTABINDEX(pNMHDR->idFrom)]; + if (!tab) return CFrameWnd::OnToolTipText(id, pNMHDR, pResult); + + TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; + TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; + + CString tabBarTip = tab->GetBrowserGlue()->mLocation; + if (tabBarTip.GetLength()>tooltipWidth) + tabBarTip = tabBarTip.Mid(0, tooltipWidth-3) + _T("..."); + if (!tab->GetBrowserGlue()->mTitle.IsEmpty() && tab->GetBrowserGlue()->mTitle.Compare(tab->GetBrowserGlue()->mLocation) != 0) + tabBarTip = tab->GetBrowserGlue()->mTitle + _T("\n") + tabBarTip; + + USES_CONVERSION; + if (pNMHDR->code == TTN_NEEDTEXTA) + { + if (tip) free(tip); + tip = strdup(T2CA(tabBarTip)); + pTTTA->lpszText = tip; + } + else + { + if (wtip) free(wtip); + wtip = wcsdup(T2CW(tabBarTip)); + pTTTW->lpszText = wtip; + } + + *pResult = 0; + + // bring the tooltip window above other popup windows + ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0, + SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); + + return TRUE; +} + +CBrowserFrmTab::CBrowserFrmTab(PRUint32 chromeMask, LONG style) +: CBrowserFrame(chromeMask,style) +{ + m_pPreviousSelectedTab = NULL; + m_wndCBrowserTab = NULL; + m_wndTabs = NULL; + m_iBrowserCount = 0; +} + +CBrowserFrmTab::~CBrowserFrmTab() +{ +/* for (int i=0;i1) + { + ActivateFrame(); + CString str; + str.Format(IDS_CLOSE_SEVERAL_TABS, m_iBrowserCount); + if (MessageBox(str, 0, MB_OKCANCEL|MB_ICONWARNING) != IDOK) + return; + } + + //for (int i = 0;iDestroy(); + + CBrowserFrame::OnClose(); +} + + +int CBrowserFrmTab::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + + // tell all our plugins that we were created + if (!IsDialog()) + theApp.plugins.SendMessage("*", "* OnCreate", "Create", (long)this->m_hWnd, 1); + + // Create a ReBar window to which the toolbar and UrlBar + // will be added + BOOL hasLine = theApp.preferences.GetBool("kmeleon.display.toolbars_line", TRUE); + if (!m_wndReBar.Create(this, RBS_DBLCLKTOGGLE | RBS_VARHEIGHT | (hasLine ? RBS_BANDBORDERS:0))) + { + TRACE0("Failed to create ReBar\n"); + return -1; // fail to create + } + + if (CBrowserFrame::InitLayout() == -1) + return -1; + + // Create the bar which will contain the tab list + // It would be better to use a tabcontrol but, currently + // i'm not sure how to deal with it, and it would not fit + // the skin. + m_wndTabs = new CTabReBar(); + if (!m_wndTabs->Create(&m_wndReBar, ID_TABS_BAR)) + { + TRACE0("Failed to create the tab toolbar\n"); + return -1; + } +/* + m_wndReBar.AddBar(m_wndTabs, + theApp.preferences.GetString(PREFERENCE_REBAR_TITLE, _T("")) + ,0, RBBS_USECHEVRON | RBBS_CHILDEDGE | RBBS_FIXEDBMP ); + + m_wndReBar.RegisterBand(m_wndTabs->m_hWnd, _T("Tabs"), false); +*/ + + // Set the favicon image list for the tab bar + m_wndTabs->GetToolBarCtrl().SetImageList(&theApp.favicons); + + // Create the first tab + if (CreateBrowserTab(true)==NULL) + { + TRACE0("Failed to create view window\n"); + return -1; + } + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + m_wndReBar.RestoreBandSizes(); + + // If we try to hide it sooner then CrashBadaboum + if (theApp.preferences.bAutoHideTabControl) { + int index = m_wndReBar.FindByName(_T("Tabs")); + m_wndReBar.ShowBand(index, FALSE); + } + + return 0; +} + +CBrowserTab* CBrowserFrmTab::CreateBrowserTab(bool first) +{ + // Fail if we reached the maximun number of tabs + if (m_iBrowserCount >= MAX_TABS_NUMBER) + { + ::AfxMessageBox(IDS_MAXTABSNUMBER, MB_ICONSTOP ); + return NULL; + } + + // Create a new Tab + m_Tabs[m_iBrowserCount] = new CBrowserTab(); + + // Pass "this" to the View for later callbacks + // and/or access to any public data members, if needed + m_Tabs[m_iBrowserCount]->SetBrowserFrame(this); + + // Pass on the BrowserFrameGlue also to the View which + // it will use during the Init() process after creation + // of the BrowserImpl obj. Essentially, the View object + // hooks up the Embedded browser's callbacks to the BrowserFrame + // via this BrowserFrameGlue object + // It will be deleted by the view. + m_Tabs[m_iBrowserCount]->SetBrowserGlue(new CBrowserGlueTab(this, m_Tabs[m_iBrowserCount])); + + // Create the view + BOOL r = m_Tabs[m_iBrowserCount]->Create(this, m_iBrowserCount); + + if (r) + { + // + CString str; + str.LoadString(IDS_EMPTY); + int buttonIndex = m_iBrowserCount; + if (theApp.preferences.iOnOpenTab == 1 + && m_iCBrowserView>=0) + buttonIndex = m_wndTabs->FindById(TABINDEXTOID(m_iCBrowserView)) + 1; + + m_wndTabs->InsertItem(buttonIndex, TABINDEXTOID(m_iBrowserCount), (LPCTSTR)str, (DWORD_PTR)m_Tabs[m_iBrowserCount]); + + if (first) + { + m_wndCBrowserTab = m_Tabs[0]; + m_iCBrowserView = 0; + + // This is our current active tab but it doesn't mean it can + // get the focus yet. + m_Tabs[0]->SetActive(true, false); + //SetActiveBrowser(m_Tabs[0]); + } + //else + // m_Tabs[m_iBrowserCount]->SetActive(false); + UpdateTabListMenu(); + return m_Tabs[m_iBrowserCount++]; + } + + // Failed to create the view. Cleaning. + delete m_Tabs[m_iBrowserCount]; + + return NULL; +} + +void CBrowserFrmTab::OnTabSelect(UINT id) +{ + int index = IDTOTABINDEX(id) ; + SetActiveBrowser(m_Tabs[index]); +} + +BOOL CBrowserFrmTab::SafeSetActiveBrowser(CBrowserTab* aNewActiveTab) +{ + unsigned count = GetTabCount(); + if (!count) return FALSE; + + for (unsigned i=0; iIsActive()) return; + + if (m_wndCBrowserTab && aNewActiveTab!=m_wndCBrowserTab) + { + m_wndCBrowserTab->SetActive(false); + m_pPreviousSelectedTab = m_wndCBrowserTab; + } + //SendMessage(WM_SWITCHTAB, (WPARAM)m_wndCBrowserTab, (LPARAM)aNewActiveTab); + theApp.plugins.SendMessage("*", "*", "SwitchTab", (long)aNewActiveTab, (long)m_wndCBrowserTab); + + m_iCBrowserView = aNewActiveTab->m_iIndex; + m_wndCBrowserTab = aNewActiveTab; + + //m_wndTabs->SelectItem(TABINDEXTOID(aNewActiveTab->m_iIndex)); + + //m_wndCBrowserView->Activate(WA_ACTIVE, NULL, false); + //m_Tabs[index].xBrowserFrameGlueObj->m_bActive = true; + + // BUG: We may be here because of a call to this function. + aNewActiveTab->SetActive(TRUE); + + UpdateTitle(m_wndCBrowserTab->GetBrowserGlue()->mTitle); + UpdateSecurityStatus(m_wndCBrowserTab->GetBrowserGlue()->mSecurityState); + UpdatePopupNotification(m_wndCBrowserTab->GetBrowserGlue()->mPopupBlockedHost); + UpdateLocation(m_wndCBrowserTab->GetBrowserGlue()->mLocation); + UpdateLoading(m_wndCBrowserTab->GetBrowserGlue()->mLoading); + UpdateProgress(m_wndCBrowserTab->GetBrowserGlue()->mProgressCurrent, m_wndCBrowserTab->GetBrowserGlue()->mProgressMax); + UpdateSiteIcon(theApp.favicons.GetIcon(m_wndCBrowserTab->GetBrowserGlue()->mIconURI)); + UpdateStatus(m_wndCBrowserTab->GetBrowserGlue()->mStatusText); + + // Remove a possible tooltip + m_wndToolTip.Hide(); + + // Reposition the view + RecalcLayout(); + +} + + +// I'm overriding RecalcLayout so the current active browser view +// is repositionned. +void CBrowserFrmTab::RecalcLayout(BOOL bNotify) +{ + if (m_bInRecalcLayout) + return; + + m_bInRecalcLayout = TRUE; + // clear idle flags for recalc layout if called elsewhere + if (m_nIdleFlags & idleNotify) + bNotify = TRUE; + m_nIdleFlags &= ~(idleLayout|idleNotify); + + + RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST + m_iCBrowserView, reposExtra, &m_rectBorder); + m_bInRecalcLayout = FALSE; +} + +void CBrowserFrmTab::OnNewTab() +{ + if (IsDialog() || IsPopup()) + return; + + CBrowserTab* tab; + if ( (tab=CreateBrowserTab()) == NULL) + { + TRACE0("Failed to create view window\n"); + return; + } + + switch (theApp.preferences.iNewWindowOpenAs) { + case PREF_NEW_WINDOW_CURRENT: + if (m_wndCBrowserTab) + m_wndCBrowserTab->CloneBrowser(tab); + break; + case PREF_NEW_WINDOW_HOME: + tab->LoadHomePage(); + break; + case PREF_NEW_WINDOW_BLANK: + tab->OpenURL(_T("about:blank")); + break; + case PREF_NEW_WINDOW_URL: { + CString newUrl = theApp.preferences.newWindowURL; + if (newUrl.IsEmpty()) + tab->OpenURL(_T("about:blank")); + else + tab->OpenURL(newUrl); + } + break; + } + + SetActiveBrowser(tab); + + if (theApp.preferences.GetBool("kmeleon.display.NewWindowHasUrlFocus", FALSE)) + m_wndUrlBar.SetFocus(); +} + +void CBrowserFrmTab::OnUpdateTabs(CCmdUI* pCmd) +{ + pCmd->Enable(); + if (pCmd->m_nID == TABINDEXTOID(m_wndCBrowserTab->m_iIndex)) + pCmd->SetCheck(1); + else + pCmd->SetCheck(0); +} + +#include "nsISHistory.h" +#include ".\browserfrmtab.h" + +void CBrowserFrmTab::OnCloseAllTab() +{ + while (m_iBrowserCount>1) + CloseTab(m_wndCBrowserTab); + + CBrowserWrapper* browser = GetActiveView()->GetBrowserWrapper(); + if (!browser) return; + + nsCOMPtr sHistory; + if (!browser->GetSHistory(getter_AddRefs(sHistory))) + return; + + GetActiveView()->OpenURL(_T("about:blank")); + PRInt32 shcount; + sHistory->GetCount(&shcount); + sHistory->PurgeHistory(shcount); +} + +void CBrowserFrmTab::OnCloseAllOtherTab() +{ + CBrowserView* current = GetActiveView(); + + while (m_iBrowserCount>1) { + if (current != this->m_Tabs[m_iCBrowserView]) + CloseTab(m_Tabs[m_iCBrowserView]); + else if (m_iCBrowserView>0) + CloseTab(m_Tabs[m_iCBrowserView-1]); + else + CloseTab(m_Tabs[m_iCBrowserView+1]); + } +} + +void CBrowserFrmTab::OnCloseTab() +{ + CloseTab(m_wndCBrowserTab); +} + +LRESULT CBrowserFrmTab::OnOpenTab(WPARAM wParam, LPARAM lParam) +{ + CBrowserTab* tab = CreateBrowserTab(); + if (!tab) return 0; + + USES_CONVERSION; + if (wParam) tab->OpenURL(A2CT((char*)wParam)); + SetActiveBrowser(tab); + return (LRESULT)tab; +} + +LRESULT CBrowserFrmTab::OnCloseTab(WPARAM wParam, LPARAM lParam) +{ + if (lParam && ((CObject*)lParam)->IsKindOf(RUNTIME_CLASS(CBrowserTab))) + return CloseTab(((CBrowserTab*)lParam)); + + return -1; +} + +BOOL CBrowserFrmTab::CloseTab(CBrowserTab* tab) +{ + //if (index <0 || index >=m_iBrowserCount) return FALSE; + + // Close if it's a popup + if (IsPopup() || IsDialog()) { + SendMessage(WM_CLOSE,0,0); + return TRUE; + } + + //If only one tab, close the window. + if (m_iBrowserCount<2){ + + switch (theApp.preferences.iOnCloseLastTab) + { + case 0: + SendMessage(WM_CLOSE,0,0); + return TRUE; + case 1: + m_wndCBrowserTab->OpenURL(_T("about:blank"), nsnull); + return FALSE; + case 2: + return FALSE; + } + } + + // Check if we're closing the last active tab, so we can set the + // pointer to something valid. + if (m_pPreviousSelectedTab == tab) + m_pPreviousSelectedTab = NULL; // Have to fix that + + int index = tab->m_iIndex; + m_Tabs[index] = NULL; + tab->Destroy(); + //delete m_Tabs[index]; + + // If we're closing the active tab + CBrowserTab* newActiveTab; + if (tab==m_wndCBrowserTab) + { + m_wndCBrowserTab = NULL; + int newTabIndex; + switch (theApp.preferences.iOnCloseTab) + { + case 2: + if (m_pPreviousSelectedTab){ + newActiveTab = m_pPreviousSelectedTab; + break; + } + + case 0: // Next + newTabIndex = IDTOTABINDEX(m_wndTabs->GetNextItem(TABINDEXTOID(index),false)); + newActiveTab = m_Tabs[newTabIndex]; + break; + + default: + case 1: // Previous + newTabIndex = IDTOTABINDEX(m_wndTabs->GetPreviousItem(TABINDEXTOID(index),false)); + newActiveTab = m_Tabs[newTabIndex]; + break; + + } + } + + m_wndTabs->DeleteItem(TABINDEXTOID(index)); + m_iBrowserCount--; + + // There are better way to do that but ... + // Update our BrowserView array + for (int i=index;iSetIndex(i); + m_wndTabs->SetItemCommandID(TABINDEXTOID(i + 1), TABINDEXTOID(i)); + } + + if (index==m_iCBrowserView) + { + m_iCBrowserView = -1; + m_wndCBrowserTab = NULL; + SetActiveBrowser(newActiveTab); + } + else if (indexGetNextItem(TABINDEXTOID(m_iCBrowserView))); + + /* + int newBrowser; + if (m_iCBrowserViewGetPreviousItem(TABINDEXTOID(m_iCBrowserView))); + /* + int newBrowser; + if (m_iCBrowserView>0) + newBrowser = m_iCBrowserView - 1; + else + newBrowser = m_iBrowserCount - 1; + */ + SetActiveBrowser(m_Tabs[newTabID]); +} + +void CBrowserFrmTab::OnLastTab() +{ + SetActiveBrowser(m_pPreviousSelectedTab); +} + +LRESULT CBrowserFrmTab::OnGetFavIcon(WPARAM wParam, LPARAM lParam) +{ + nsCOMPtr sURI; + nsDependentCString uri; + int index = IDTOTABINDEX(wParam); + int iIcon = theApp.favicons.GetDefaultIcon(); +/* + if (m_Tabs[index]->mWebNav) { + nsresult rv = m_Tabs[index]->mWebNav->GetCurrentURI(getter_AddRefs(sURI)); + if (NS_SUCCEEDED(rv)) { + iIcon = theApp.favicons.GetIcon(sURI); + } + } +*/ + return iIcon; +} + +LRESULT CBrowserFrmTab::OnNewSiteIcon(WPARAM url, LPARAM index) +{ + for (int i =0; im_iBrowserCount; i++) + { + int icon = theApp.favicons.GetIcon(m_Tabs[i]->GetBrowserGlue()->mIconURI); + if (icon==-1) {// The icon doesn't exist anymore, was deleted + m_Tabs[i]->GetBrowserGlue()->mIconURI = nsnull; + SetFavIcon(theApp.favicons.GetDefaultIcon()); + SetTabIcon(m_Tabs[i], theApp.favicons.GetDefaultIcon()); + } + else + if (index==-1 || index == icon) { + SetFavIcon(icon); + SetTabIcon(m_Tabs[i], icon); + } + } + + return 0; +} + +void CBrowserFrmTab::OnTbnBeginDrag(NMHDR *pNMHDR, LRESULT *pResult) +{ + USES_CONVERSION; + *pResult = 0; + + LPNMTOOLBAR pNMTB = reinterpret_cast(pNMHDR); + + UINT cfTabPt = ::RegisterClipboardFormat(CFSTR_TABPT); + + CBrowserTab* tab = (CBrowserTab*)m_Tabs[IDTOTABINDEX(pNMTB->iItem)]; + + HGLOBAL hTab = GlobalAlloc(GHND, sizeof(CBrowserTab*)); + CBrowserTab** pTab = (CBrowserTab**)GlobalLock(hTab); + *pTab = tab; + GlobalUnlock(hTab); + + COleDataSource datasource; + //datasource.CacheGlobalData(cfTabPt, hTab); + tab->AddURLAndPerformDrag(datasource); + + GlobalFree(hTab); +} + +void CBrowserFrmTab::DrawTabListMenu(HMENU menu) +{ + for (int i=0; iGetBrowserWrapper(); + if (!wrapper) continue; + + CString title = wrapper->GetTitle(); + if (title.IsEmpty()) + title = wrapper->GetURI(); + + AppendMenu(menu, MF_ENABLED | MF_STRING, TABINDEXTOID(i), title); + } +} + +void CBrowserFrmTab::UpdateTabListMenu() +{ + KmMenu* menu = theApp.menus.GetKMenu(_T("@TabList")); + if (menu) menu->Invalidate(); +} + +/**********************************************/ + +CBrowserTab::CBrowserTab() : CBrowserView() +{ + m_bActive = false; + mpFrameTab = NULL; +} + +CBrowserTab::~CBrowserTab() +{ +} + +BOOL CBrowserTab::Create(CBrowserFrmTab* aFrame, int index) +{ + mpFrameTab = aFrame; + m_iIndex = index; + + return CBrowserView::Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, + CRect(0, 0, 0, 0), aFrame, AFX_IDW_PANE_FIRST+index, NULL); +} + +void CBrowserTab::Destroy() +{ + DestroyWindow(); +} + +void CBrowserTab::SetIndex(int i) +{ + m_iIndex = i; +// m_xBrowserFrameGlueObj.m_iViewIndex = i; + SetWindowLong(m_hWnd, GWL_ID, AFX_IDW_PANE_FIRST + i); +} + +bool CBrowserTab::SetActive(bool state, bool haveFocus) +{ + bool old = m_bActive; + m_bActive = state; + + if (state) + { + if (haveFocus && GetParentFrame() == GetActiveWindow()) + CBrowserView::Activate(TRUE); + ShowWindow(SW_SHOW); + } + else + { + CBrowserView::Activate(FALSE); + ShowWindow(SW_HIDE); + } + + return old; +} + +CBrowserTab* CBrowserTab::OpenURLInNewTab(LPCTSTR url, LPCTSTR refferer, BOOL bBackground, BOOL allowFixup) +{ + CBrowserTab* tab; + if ( !((CBrowserGlue*)m_pBrowserGlue)->mLoading && + GetCurrentURI().Compare(_T("about:blank")) == 0 ) + tab = this; + else if ( (tab=mpFrameTab->CreateBrowserTab()) == NULL) + { + TRACE0("Failed to create view window\n"); + return NULL; + } + + tab->OpenURL(url, refferer, allowFixup); + + if (!bBackground) + mpFrameTab->SetActiveBrowser(tab); + + return tab; +} + +IMPLEMENT_DYNAMIC(CBrowserTab, CBrowserView) + +BEGIN_MESSAGE_MAP(CBrowserTab, CBrowserView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_COMMAND(ID_OPEN_LINK_IN_NEW_TAB, OnOpenLinkInNewTab) + ON_COMMAND(ID_OPEN_LINK_IN_BACKGROUNDTAB, OnOpenLinkInBackgroundTab) + ON_COMMAND(ID_OPEN_FRAME_IN_NEW_TAB, OnOpenFrameInNewTab) + ON_COMMAND(ID_OPEN_FRAME_IN_BACKGROUNDTAB, OnOpenFrameInBackgroundTab) + ON_WM_KEYDOWN() + ON_WM_KEYUP() +END_MESSAGE_MAP() + +int CBrowserTab::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CBrowserView::OnCreate(lpCreateStruct) == -1) + return -1; + + theApp.plugins.SendMessage("*", "* OnCreateTab", "CreateTab", (long)mpBrowserFrame->m_hWnd, (long)this->m_hWnd); +// GetParent()->SendMessage(WM_CREATETAB, 0, (LPARAM)this); + + return 0; +} + +void CBrowserTab::OnDestroy() +{ + theApp.plugins.SendMessage("*", "* OnDestroyTab", "DestroyTab", (long)mpBrowserFrame->m_hWnd, (long)this->m_hWnd); + CBrowserView::OnDestroy(); + //GetParent()->SendMessage(WM_CLOSETAB, m_iIndex, (LPARAM)this); +} + +void CBrowserTab::OpenURLWithCommand(UINT idCommand, LPCTSTR url, LPCTSTR refferer, BOOL allowFixup) +{ + switch (idCommand) + { + case ID_OPEN_LINK_IN_NEW_TAB: + OpenURLInNewTab(url, refferer, FALSE, allowFixup); + break; + case ID_OPEN_LINK_IN_BACKGROUNDTAB: + OpenURLInNewTab(url, refferer, TRUE, allowFixup); + break; + default: + CBrowserView::OpenURLWithCommand(idCommand, url, refferer, allowFixup); + return; + } +} + +void CBrowserTab::OnOpenLinkInBackgroundTab() +{ + CString url, title; + if (!GetLinkTitleAndHref(m_contextNode, url, title)) + return; + OpenURLInNewTab(url, GetCurrentURI(), TRUE); +} + +void CBrowserTab::OnCloseTab() +{ + theApp.plugins.SendMessage("*", "* OnCloseTab", "CloseTab", (long)mpBrowserFrame->m_hWnd, (long)this->m_hWnd); + Destroy(); +} + +void CBrowserTab::OnOpenLinkInNewTab() +{ + CString url, title; + if (!GetLinkTitleAndHref(m_contextNode, url, title)) + return; + OpenURLInNewTab(url, GetCurrentURI(), FALSE); +} + +void CBrowserTab::OnOpenFrameInNewTab() +{ + CString url = m_pWindow->GetFrameURL(m_contextNode); + if (url.IsEmpty()) return; + OpenURLInNewTab(url, GetCurrentURI(), FALSE); +} + +void CBrowserTab::OnOpenFrameInBackgroundTab() +{ + CString url = m_pWindow->GetFrameURL(m_contextNode); + if (url.IsEmpty()) return; + OpenURLInNewTab(url, GetCurrentURI(), TRUE); +} diff --git a/k-meleon/BrowserFrmTab.h b/k-meleon/BrowserFrmTab.h new file mode 100644 index 00000000..efa75e70 --- /dev/null +++ b/k-meleon/BrowserFrmTab.h @@ -0,0 +1,173 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* +*/ + +#pragma once + +#define MAX_TABS_NUMBER 80 +#define TABS_START_ID 2300 +#define TABS_STOP_ID TABS_START_ID + MAX_TABS_NUMBER + +#define WM_CLOSETAB WM_APP + 150 +#define WM_OPENTAB WM_APP + 151 +#define WM_SWITCHTAB WM_APP + 152 + +#define IDTOTABINDEX(ID) (ID - TABS_START_ID) +#define TABINDEXTOID(index) (TABS_START_ID + index) + +#include "BrowserView.h" +#include "BrowserFrm.h" +#include "TabRebar.h" + +class CBrowserFrmTab; + +class CBrowserTab : public CBrowserView +{ +public: + DECLARE_DYNAMIC(CBrowserTab) + + CBrowserTab(); + ~CBrowserTab(); + BOOL Create(CBrowserFrmTab* aFrame, int index); + void Destroy(); + + inline bool IsActive() {return m_bActive;} + inline bool SetActive(bool state, bool haveFocus=true); + + CBrowserTab* OpenURLInNewTab(LPCTSTR url, LPCTSTR refferer = NULL, BOOL bBackground = FALSE, BOOL allowFixup = FALSE); + CBrowserFrame* OpenURLInNewWindow(LPCTSTR url, LPCTSTR refferer = NULL, BOOL bBackground = FALSE); + virtual void OpenURLWithCommand(UINT idCommand, LPCTSTR url, LPCTSTR refferer = NULL, BOOL allowFixup = FALSE); +/* void SetFrameGlue(PBROWSERFRAMEGLUE glue){ + m_wndView.SetBrowserFrameGlue(glue); + }*/ + + void SetIndex(int i); + + //CBrowserView m_wndView; + int m_iIndex; + +protected: +/* + class BrowserFrameTabGlueObj : public IBrowserFrameGlue + { + // + // NS_DECL_BROWSERFRAMEGLUE below is a macro which expands + // to the function prototypes of methods in IBrowserFrameGlue + // Take a look at IBrowserFrameGlue.h for this macro define + // + + NS_DECL_BROWSERFRAMEGLUE + + } m_xBrowserFrameTabGlueObj; + friend class BrowserFrameTabGlueObj; +*/ + PBROWSERFRAMEGLUE mpBrowserFrameTabGlue; + + bool m_bActive; + CBrowserFrmTab* mpFrameTab; + + afx_msg void OnOpenFrameInNewTab(); + afx_msg void OnOpenFrameInBackgroundTab(); + afx_msg void OnOpenLinkInNewTab(); + afx_msg void OnOpenLinkInBackgroundTab(); + + DECLARE_MESSAGE_MAP() + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnCloseTab(); +}; + +class CBrowserFrmTab : public CBrowserFrame +{ + +public: + DECLARE_DYNAMIC(CBrowserFrmTab) + + CBrowserFrmTab(PRUint32 chromeMask, LONG style); + ~CBrowserFrmTab(); + + void DrawTabListMenu(HMENU menu); + void UpdateTabListMenu(); + + CBrowserTab* CreateBrowserTab(bool first=false); + void SetActiveBrowser(CBrowserTab*); + BOOL SafeSetActiveBrowser(CBrowserTab*); + BOOL CloseTab(CBrowserTab*); + virtual CBrowserView* GetActiveView() { return (CBrowserView*)m_wndCBrowserTab; } + CBrowserTab* GetActiveTab() { return m_wndCBrowserTab; } + + BOOL SetTabIcon(CBrowserTab* tab, int icon) { + return m_wndTabs->SetItemImage(TABINDEXTOID(tab->m_iIndex), icon); + } + + BOOL SetTabTitle(CBrowserTab* tab, CString title){ + UpdateTabListMenu(); + title.Replace(_T("&"), _T("&&")); + return m_wndTabs->SetItemText(TABINDEXTOID(tab->m_iIndex), title); + } + + BOOL GetTabTitle(CBrowserTab* tab, CString& title){ + return m_wndTabs->GetItemText(TABINDEXTOID(tab->m_iIndex), title); + } + + int GetTabCount() { + return m_iBrowserCount; + } + + CBrowserTab* GetTabIndex(int index) { + if (index<0||index>=m_iBrowserCount) + return NULL; + return m_Tabs[index]; + } + + virtual void RecalcLayout(BOOL bNotify = TRUE); + +protected: + + CBrowserTab* m_wndCBrowserTab; + CBrowserTab* m_Tabs[MAX_TABS_NUMBER]; + CBrowserTab* m_pPreviousSelectedTab; + + int m_iBrowserCount; // Number of tab + int m_iCBrowserView; // Index of the current active tab + CTabReBar* m_wndTabs; // Toolbar with the tabs selector + CString m_tabBarTip; + + DECLARE_MESSAGE_MAP() + afx_msg void OnClose(); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnCloseTab(); + afx_msg void OnCloseAllTab(); + afx_msg void OnCloseAllOtherTab(); + afx_msg LRESULT OnCloseTab(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnOpenTab(WPARAM wParam, LPARAM lParam); + afx_msg void OnUpdateTabs(CCmdUI*); + afx_msg void OnNextTab(); + afx_msg void OnPrevTab(); + afx_msg void OnLastTab(); + afx_msg void OnTabSelect(UINT id); + afx_msg LRESULT OnGetFavIcon(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnNewSiteIcon(WPARAM url, LPARAM index); + afx_msg void OnTbnBeginDrag(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg BOOL OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult); +public: // Temporary + afx_msg void OnNewTab(); +}; + + diff --git a/k-meleon/BrowserGlue.cpp b/k-meleon/BrowserGlue.cpp new file mode 100644 index 00000000..8bad2bd3 --- /dev/null +++ b/k-meleon/BrowserGlue.cpp @@ -0,0 +1,434 @@ + /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** +/* + * Copyright (C) 2006 Dorian Boissonnade + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "stdafx.h" +#include "BrowserFrm.h" +#include "BrowserView.h" +#include "KmeleonConst.h" +#include "MozUtils.h" +#include "nsIURIFixup.h" // XXX + +CBrowserGlue::~CBrowserGlue() +{ + if ( !mPopupBlockedHost.IsEmpty()) + mpBrowserFrame->UpdatePopupNotification(NULL); +} + +void CBrowserGlue::UpdateStatusBarText(LPCTSTR aMessage) +{ + if (aMessage && *aMessage) + mStatusText = aMessage; + else + mStatusText.LoadString(AFX_IDS_IDLEMESSAGE); + + if (mpBrowserFrame->GetActiveView() == mpBrowserView) + mpBrowserFrame->UpdateStatus(mStatusText); +} + +void CBrowserGlue::UpdateProgress(int aCurrent, int aMax) +{ + mProgressMax = aMax; + mProgressCurrent = aCurrent; + if (mpBrowserFrame->GetActiveView() == mpBrowserView) + mpBrowserFrame->UpdateProgress(mProgressCurrent, mProgressMax); +} + +void CBrowserGlue::UpdateBusyState(BOOL aBusy) +{ + mDOMLoaded = mLoading = aBusy; + if (aBusy) { + mContextNode = nsnull; + mpBrowserView->m_contextNode = nsnull; + } + else { + SetFavIcon(nsnull); + mPendingLocation = _T(""); + } + + mpBrowserFrame->PostMessage(UWM_UPDATEBUSYSTATE, aBusy == PR_TRUE ? 1 : 0, (LPARAM)mpBrowserView->GetSafeHwnd()); + if (mpBrowserFrame->GetActiveView() == mpBrowserView) + mpBrowserFrame->UpdateLoading(aBusy); +} + +void CBrowserGlue::UpdateCurrentURI(nsIURI *aLocation) +{ + if(aLocation) + { + nsEmbedCString uriString; + nsCOMPtr exposable; + nsCOMPtr fixup(do_GetService("@mozilla.org/docshell/urifixup;1")); + if (fixup && NS_SUCCEEDED(fixup->CreateExposableURI(aLocation, getter_AddRefs(exposable))) && exposable) + exposable->GetSpec(uriString); + else + aLocation->GetSpec(uriString); + +#ifdef INTERNAL_SITEICONS + // Must be done here, before testing if we have the same address + // because xul error page have its own icon, and since the address + // doesn't change when retrying, the icon may stay in the urlbar. + mIconURI = nsnull; +#endif + mLocation = NSUTF8StringToCString(uriString); + + // XXX Since Mozilla 1.8.0.2 about:blank is always passed here + // before anything else, broking stuffs, so ignore it! + if (mLocation.Compare(_T("about:blank")) == 0 && + mPendingLocation.GetLength()) + mLocation = mPendingLocation; + + + if (mpBrowserFrame->GetActiveView() == mpBrowserView) { + mpBrowserFrame->UpdateLocation(mLocation); + if (!(mPopupBlockedHost.IsEmpty())) + mpBrowserFrame->UpdatePopupNotification(NULL); + } + + mPopupBlockedHost.Empty(); + + // Add a MRU entry. Note that I'm only only allowing + // http or https uri + + PRBool allowMRU,b; + aLocation->SchemeIs("http", &b); + allowMRU = b; + aLocation->SchemeIs("https", &b); + allowMRU |= b; + + if ( allowMRU ) { + if (theApp.preferences.MRUbehavior == 0){ + nsEmbedCString password; + aLocation->GetUsername(password); + aLocation->SetUserPass(password); + aLocation->GetSpec(uriString); + theApp.m_MRUList->AddURL(NSUTF8StringToCString(uriString)); + } + else if (theApp.preferences.MRUbehavior == 1){ + nsEmbedCString nsScheme, nsHost; + aLocation->GetScheme(nsScheme); + aLocation->GetHost(nsHost); + nsHost.Insert("://",0); + nsHost.Insert(nsScheme,0); + theApp.m_MRUList->AddURL(NSUTF8StringToCString(nsHost)); + } + } + } +} + +void CBrowserGlue::GetBrowserTitle(CString& aTitle) +{ + mpBrowserFrame->GetWindowText(aTitle); +} + +void CBrowserGlue::SetBrowserTitle(LPCTSTR aTitle) +{ + mTitle = aTitle; + if (mpBrowserFrame->GetActiveView() != mpBrowserView) + return; + + mpBrowserFrame->UpdateTitle(mTitle); + mpBrowserFrame->PostMessage(UWM_UPDATESESSIONHISTORY, 0, 0); +} + +void CBrowserGlue::SetBrowserSize(int aCX, int aCY) +{/* + if (theApp.preferences.GetBool("kmeleon.display.dontResizeNewWindow", FALSE) && + !(mpBrowserFrame->IsDialog())) + return;*/ + + CWnd* frame = mpBrowserView->GetParentFrame(); + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + frame->GetWindowPlacement(&wp); + if (wp.showCmd != SW_SHOWNORMAL) + return; + + // first we have to figure out how much bigger the frame is than the view + RECT frameRect, viewRect; + frame->GetWindowRect(&frameRect); + mpBrowserView->GetClientRect(&viewRect); + + int deltax = frameRect.right - frameRect.left - viewRect.right; + int deltay = frameRect.bottom - frameRect.top - viewRect.bottom; + + frame->SetWindowPos(NULL, 0, 0, aCX+deltax, aCY+deltay, + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER + ); +} + +void CBrowserGlue::SetFocus() +{ + //if (!::IsChild(pThis->m_hWnd,::GetFocus())) + // pThis->BringWindowToTop(); +} + +void CBrowserGlue::SetVisibility(BOOL aVisibility) +{ + TRACE2("Set Visibility %u for window %s\n", aVisibility, mTitle); + if(aVisibility) + { + if (mpBrowserFrame->IsIconic()) + return; +/* + if (!mpBrowserFrame->IsWindowVisible()) { + if (pThis->m_created) + return; + pThis->m_created = true; + }*/ + + mpBrowserFrame->ShowWindow(SW_SHOW); + // pThis->SetActiveWindow(); + mpBrowserFrame->UpdateWindow(); + } + else + { + mpBrowserFrame->ShowWindow(SW_HIDE); + } +} + +void CBrowserGlue::GetVisibility(BOOL *aVisible) +{ + *aVisible = mpBrowserFrame->IsIconic() || !mpBrowserFrame->IsWindowVisible() ? PR_FALSE : PR_TRUE; +} + +void CBrowserGlue::DestroyBrowserFrame() +{ + mpBrowserFrame->PostMessage(WM_CLOSE, -1, -1); +} + +HWND CBrowserGlue::GetBrowserFrameNativeWnd() +{ + return mpBrowserFrame->GetSafeHwnd(); +} + +void CBrowserGlue::UpdateSecurityStatus(PRInt32 aState) +{ + mSecurityState = aState; + if (mpBrowserFrame->GetActiveView() == mpBrowserView) + mpBrowserFrame->UpdateSecurityStatus(aState); +} + +void CBrowserGlue::ShowTooltip(PRInt32 x, PRInt32 y, const TCHAR *text) +{ + if (!text) { + mpBrowserFrame->m_wndToolTip.Hide(); + return; + } + + POINT point; + ::GetCursorPos(&point); + + // XXX For an unknow reason the tooltips are also displayed when the cursor is + // outside the view, so verify that the mouse is on the view ... + CRect r; + mpBrowserView->GetWindowRect(r); + if (!r.PtInRect(point)) + return; + + mpBrowserFrame->ScreenToClient(&point); + point.y += GetSystemMetrics(SM_CYCURSOR)/2 + 4; // jump to below the cursor, otherwise we appear right on top of the cursor + + mpBrowserFrame->m_wndToolTip.Show(text, point.x, point.y); +} + +BOOL CBrowserGlue::MouseAction(nsIDOMNode *node, UINT flags) +{ + mContextNode = node; + mpBrowserView->m_contextNode = node; + + UINT id = theApp.accel.CheckMouse(flags); + + // Since accels can't currently be triggered depending on what's below + // the cursor (link, img, ...) the middle mouse button for panning + // has to be handled separately. + + CString href, title; + if (flags == MK_MBUTTON && + (!id || !::GetLinkTitleAndHref(node, href, title))) { + mpBrowserView->StartPanning(TRUE); + return TRUE; + } else if (id>0) { + mpBrowserFrame->PostMessage(WM_COMMAND, (WPARAM)id, 0); + return TRUE; + } + + return FALSE; +} + +void CBrowserGlue::PopupBlocked(const char* uri) +{ + // Do nothing if an icon was set already or if the user + // don't want popup notification + if (!theApp.preferences.GetBool("browser.popups.showPopupBlocker", PR_TRUE) + || !mPopupBlockedHost.IsEmpty()) + return; + + USES_CONVERSION; + mPopupBlockedHost = A2CT(uri); + if (mpBrowserFrame->GetActiveView() == mpBrowserView) + mpBrowserFrame->UpdatePopupNotification(mPopupBlockedHost); +} + +void CBrowserGlue::SetFavIcon(nsIURI* favUri) +{ +#ifdef INTERNAL_SITEICONS + if (favUri == nsnull) + { + // XXX Temporary set m_bDOMLoaded here + mDOMLoaded = TRUE; + + // No site icon found then we're looking for a IE favicon + // Note that this can be called twice, when DOMContentLoaded + // is fired, and when the page finished to load. + // DOMContentLoaded is not fired when page are loaded from cache + // so I'm calling it also when the page is loaded to be sure we + // checked for an IE icon. + + if (mIconURI != nsnull) return; + mIcon = theApp.favicons.GetDefaultIcon(); + + if (theApp.preferences.GetBool("browser.chrome.favicons", PR_TRUE)) + { + nsCOMPtr currentURI; + nsEmbedCString nsUri; + + mpBrowserView->GetBrowserWrapper()->GetCurrentURI(getter_AddRefs(currentURI)); + if (!currentURI) return; + + PRBool ishttp, b; + currentURI->SchemeIs("http", &b); + ishttp = b; + currentURI->SchemeIs("https", &b); + ishttp |= b; + + if (ishttp) + { + currentURI->Resolve(NS_LITERAL_CSTRING("/favicon.ico"), nsUri); + + nsCOMPtr iconURI; + nsresult rv = NewURI(getter_AddRefs(iconURI), nsUri); + if(NS_FAILED(rv) || !iconURI) return; + + mIconURI = iconURI; + mIcon = theApp.favicons.GetIcon(iconURI, TRUE); + } + } + } + else + { + mIconURI = favUri; + mIcon = theApp.favicons.GetIcon(favUri, TRUE); + } + + if (mpBrowserFrame->GetActiveView() == mpBrowserView) + mpBrowserFrame->UpdateSiteIcon(mIcon); +#endif +} + +BOOL CBrowserGlue::FocusNextElement() +{ + if (mpBrowserFrame->m_wndFindBar){ + mpBrowserFrame->GetActiveView()->Activate(FALSE); + mpBrowserFrame->m_wndFindBar->SetFocus(); + } + else if (mpBrowserFrame->m_wndUrlBar.IsWindowVisible()) { + mpBrowserFrame->GetActiveView()->Activate(FALSE); + ::SetFocus(mpBrowserFrame->m_wndUrlBar.m_hwndEdit); + } + else + return FALSE; + return TRUE; +} + +BOOL CBrowserGlue::FocusPrevElement() +{ + if (mpBrowserFrame->m_wndUrlBar.IsWindowVisible()) { + mpBrowserFrame->GetActiveView()->Activate(FALSE); + mpBrowserFrame->m_wndFindBar->SetFocus(); + return TRUE; + } + + return FALSE; +} + +void CBrowserGlue::ShowContextMenu(UINT aContextFlags, nsIDOMNode* node) +{ + CString menu; + if ( !(aContextFlags & nsIContextMenuListener2::CONTEXT_LINK) && + !(aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE) && + mpBrowserView->GetBrowserWrapper()->CanCopy()) + { + menu = _T("SelectedText"); + } + else { + if (mpBrowserView->GetBrowserWrapper()->GetFrameURL(node).GetLength()) + menu = _T("Frame"); + + if(aContextFlags & nsIContextMenuListener2::CONTEXT_DOCUMENT) + { + if ((aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE) || + (aContextFlags & nsIContextMenuListener2::CONTEXT_BACKGROUND_IMAGE)) + menu += _T("DocumentImagePopup"); + else + menu += _T("DocumentPopup"); + } + else if(aContextFlags & nsIContextMenuListener2::CONTEXT_TEXT) + { + menu += _T("TextPopup"); + } + else if(aContextFlags & nsIContextMenuListener2::CONTEXT_LINK) + { + if (aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE) + menu += _T("ImageLinkPopup"); + else + menu += _T("LinkPopup"); + } + else if(aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE) + { + menu += _T("ImagePopup"); + } + else menu += _T("DocumentPopup"); + } + + mpBrowserView->m_contextNode = node; + CMenu *ctxMenu = theApp.menus.GetMenu(menu); + if(ctxMenu) + { + POINT cursorPos; + GetCursorPos(&cursorPos); + ctxMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cursorPos.x, cursorPos.y, mpBrowserFrame); + } + +} + +CBrowserWrapper* CBrowserGlue::CreateNewBrowser(PRUint32 chromeMask) +{ + return NULL; +} + +CBrowserWrapper* CBrowserGlue::ReuseWindow(BOOL useCurrent) +{ + if (useCurrent && !mpBrowserFrame->IsPopup() && !mpBrowserFrame->IsDialog()) + return mpBrowserView->GetBrowserWrapper(); + + return NULL; +} \ No newline at end of file diff --git a/k-meleon/BrowserImpl.cpp b/k-meleon/BrowserImpl.cpp new file mode 100644 index 00000000..f5fe072f --- /dev/null +++ b/k-meleon/BrowserImpl.cpp @@ -0,0 +1,847 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * + * ***** END LICENSE BLOCK ***** */ + +// File Overview.... +// This is the class which implements all the interfaces +// required(and optional) by the mozilla embeddable browser engine +// +// Note that this obj gets passed in the IBrowserFrameGlue* using the +// Init() method. Many of the interface implementations use this +// to get the actual task done. Ex: to update the status bar +// +// Look at the INTERFACE_MAP_ENTRY's below for the list of +// the currently implemented interfaces +// +// This file currently has the implementation for all the interfaces +// which are required of an app embedding Gecko +// Implementation of other optional interfaces are in separate files +// to avoid cluttering this one and to demonstrate other embedding +// principles. For example, nsIPrompt is implemented in a separate DLL. +// +// nsIWebBrowserChrome - This is a required interface to be implemented +// by embeddors +// +// nsIEmbeddingSiteWindow - This is a required interface to be implemented +// by embedders +// - SetTitle() gets called after a document +// load giving us the chance to update our +// titlebar +// +// Some points to note... +// +// nsIWebBrowserChrome interface's SetStatus() gets called when a user +// mouses over the links on a page +// +// nsIWebProgressListener interface's OnStatusChange() gets called +// to indicate progress when a page is being loaded +// +// Next suggested file(s) to look at : +// Any of the BrowserImpl*.cpp files for other interface +// implementation details +// + +#include "stdafx.h" +#include "BrowserImpl.h" +#include "BrowserWindow.h" +#include "MozUtils.h" + +#include "nsIDOMEvent.h" +#include "nsIDOMPopupBlockedEvent.h" +#include "nsIDOMMouseEvent.h" +#include "nsIDOMContextMenuListener.h" +#include "nsIDOMEventTarget.h" +#include "nsIDOMAbstractView.h" +#include "nsIDOMDocumentView.h" +#include "nsIDOMEventTarget.h" +#include "nsIDOM3Document.h" +#include "nsIDOMNSDocument.h" +#include "nsIDOMWindow2.h" +#include "nsIScriptSecurityManager.h" + +#ifdef USE_WINDOW_PROVIDER +#include "nsIBrowserDOMWindow.h" +#endif +#include "jsapi.h" +#include "nsIJSContextStack.h" +#include "BrowserFrm.h" // XXXXX +#include "BrowserView.h" + +CBrowserImpl::CBrowserImpl() +{ + m_pBrowserFrameGlue = NULL; + mWebBrowser = nsnull; + mChromeFlags = 0; + mChromeLoaded = PR_FALSE; +} + + +CBrowserImpl::~CBrowserImpl() +{ +} + +// It's very important that the creator of this CBrowserImpl object +// Call on this Init() method with proper values after creation +// +NS_METHOD CBrowserImpl::Init(PBROWSERGLUE pBrowserFrameGlue, + nsIWebBrowser* aWebBrowser) +{ + m_pBrowserFrameGlue = pBrowserFrameGlue; + + SetWebBrowser(aWebBrowser); + + return NS_OK; +} + +//***************************************************************************** +// CBrowserImpl::nsISupports +//***************************************************************************** + +NS_IMPL_ADDREF(CBrowserImpl) +NS_IMPL_RELEASE(CBrowserImpl) + +NS_INTERFACE_MAP_BEGIN(CBrowserImpl) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) +#ifdef USE_WINDOW_PROVIDER + NS_INTERFACE_MAP_ENTRY(nsIWindowProvider) +#endif + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus) + NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow) + NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow2) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) + NS_INTERFACE_MAP_ENTRY(nsIContextMenuListener2) + NS_INTERFACE_MAP_ENTRY(nsITooltipListener) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + // NS_INTERFACE_MAP_ENTRY(nsISHistoryListener) + //NS_INTERFACE_MAP_ENTRY(nsIObserver) + NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) + //NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener) +NS_INTERFACE_MAP_END + +/* +NS_IMETHODIMP CBrowserImpl::MouseDown(nsIDOMEvent* aMouseEvent) {return NS_OK;} +NS_IMETHODIMP CBrowserImpl::MouseUp(nsIDOMEvent* aMouseEvent) {return NS_OK;} +NS_IMETHODIMP CBrowserImpl::MouseClick(nsIDOMEvent* aMouseEvent){return NS_OK;} +NS_IMETHODIMP CBrowserImpl::MouseDblClick(nsIDOMEvent* aMouseEvent) {return NS_OK;} +NS_IMETHODIMP CBrowserImpl::MouseOver(nsIDOMEvent* aMouseEvent) {return NS_OK;} +NS_IMETHODIMP CBrowserImpl::MouseOut(nsIDOMEvent* aMouseEvent) {return NS_OK;} +*/ +/* +NS_IMETHODIMP CBrowserImpl::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) +{ + return NS_ERROR_NOT_IMPLEMENTED; + + //"nsWebBrowserFind_FindAgain" + //return m_pBrowserFrameGlue->OnFindNext(aSubject); +} + +NS_IMETHODIMP CBrowserImpl::OnHistoryNewEntry(nsIURI *aNewURI) +{ + nsEmbedCString str; + aNewURI->GetSpec(str); + CString cStr = str.get(); + m_pBrowserFrameGlue->UpdateMRU(str.get()); + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::OnHistoryGoBack(nsIURI *aBackURI, PRBool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} +NS_IMETHODIMP CBrowserImpl::OnHistoryGoForward(nsIURI *aForwardURI, PRBool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} +NS_IMETHODIMP CBrowserImpl::OnHistoryReload(nsIURI *aReloadURI, PRUint32 aReloadFlags, PRBool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; + +} +NS_IMETHODIMP CBrowserImpl::OnHistoryGotoIndex(PRInt32 aIndex, nsIURI *aGotoURI, PRBool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} +NS_IMETHODIMP CBrowserImpl::OnHistoryPurge(PRInt32 aNumEntries, PRBool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} +*/ +//***************************************************************************** +// CBrowserImpl::nsIInterfaceRequestor +//***************************************************************************** + +NS_IMETHODIMP CBrowserImpl::GetInterface(const nsIID &aIID, void** aInstancePtr) +{ + // Note that we're wrapping our nsIPrompt impl. with the + // nsISingleSignOnPrompt - if USE_SINGLE_SIGN_ON is defined + // (and if single sign-on support dll's are present and enabled) + // This allows the embedding app to use the password save + // feature. When signing on to a host which needs authentication + // the Single sign-on service will check to see if the auth. info + // is already saved and if so uses it to pre-fill the sign-on form + // If not, our nsIPrompt impl will be called + // to present the auth UI and return the required auth info. + // If we do not compile with single sign-on support or if that + // service is missing we just fall back to the regular + // implementation of nsIPrompt + + if(aIID.Equals(NS_GET_IID(nsIDOMWindow))) + { + if (mWebBrowser) + return mWebBrowser->GetContentDOMWindow((nsIDOMWindow **) aInstancePtr); + return NS_ERROR_NOT_INITIALIZED; + } + + return QueryInterface(aIID, aInstancePtr); +} + +//***************************************************************************** +// CBrowserImpl::nsIWebBrowserChrome +//***************************************************************************** + +//Gets called when you mouseover links etc. in a web page +// +NS_IMETHODIMP CBrowserImpl::SetStatus(PRUint32 aType, const PRUnichar* aStatus) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + +#ifndef _UNICODE + if (wcslen(aStatus) > 1024) + return NS_OK; +#endif + + m_pBrowserFrameGlue->UpdateStatusBarText(PRUnicharToCString(aStatus)); + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::GetWebBrowser(nsIWebBrowser** aWebBrowser) +{ + NS_ENSURE_ARG_POINTER(aWebBrowser); + + *aWebBrowser = mWebBrowser; + + NS_IF_ADDREF(*aWebBrowser); + + return NS_OK; +} + +// Currently called from Init(). I'm not sure who else +// calls this +// +NS_IMETHODIMP CBrowserImpl::SetWebBrowser(nsIWebBrowser* aWebBrowser) +{ + NS_ENSURE_ARG_POINTER(aWebBrowser); + + mWebBrowser = aWebBrowser; + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::GetChromeFlags(PRUint32* aChromeMask) +{ + NS_ENSURE_ARG_POINTER(aChromeMask); + *aChromeMask = mChromeFlags; + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::SetChromeFlags(PRUint32 aChromeMask) +{ + mChromeFlags = aChromeMask; + return NS_OK; +} + +// Will get called in response to JavaScript window.close() +// +NS_IMETHODIMP CBrowserImpl::DestroyBrowserWindow() +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + m_pBrowserFrameGlue->DestroyBrowserFrame(); + + return NS_OK; +} + +// Gets called in response to set the size of a window +// Ex: In response to a JavaScript Window.Open() call of +// the form +// +// window.open("http://www.mozilla.org", "theWin", "width=200, height=400"); +// +// First the CreateBrowserWindow() call will be made followed by a +// call to this method to resize the window +// +NS_IMETHODIMP CBrowserImpl::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + m_pBrowserFrameGlue->SetBrowserSize(aCX, aCY); + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::ShowAsModal(void) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + HWND h = m_pBrowserFrameGlue->GetBrowserFrameNativeWnd(); + CBrowserFrame* frame = (CBrowserFrame*)CWnd::FromHandle(h); + + nsCOMPtr stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1")); + if (stack && NS_SUCCEEDED(stack->Push(nsnull))) { + + frame->DoModal(); + + JSContext* cx; + stack->Pop(&cx); + NS_ASSERTION(cx == nsnull, "JSContextStack mismatch"); + } + else + return NS_ERROR_FAILURE; + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::IsWindowModal(PRBool *retval) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + HWND h = m_pBrowserFrameGlue->GetBrowserFrameNativeWnd(); + CWnd* frame = CWnd::FromHandle(h); + *retval = frame->m_nFlags & WF_CONTINUEMODAL; + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::ExitModalEventLoop(nsresult aStatus) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + HWND h = m_pBrowserFrameGlue->GetBrowserFrameNativeWnd(); + CWnd* frame = CWnd::FromHandle(h); + frame->PostMessage(WM_CLOSE, 0, 0); + //frame->EndModalLoop(aStatus); + return NS_OK; +} + +#if 0 + +NS_IMETHODIMP +CBrowserImpl::SetPersistence(PRBool aPersistX, PRBool aPersistY, + PRBool aPersistCX, PRBool aPersistCY, + PRBool aPersistSizeMode) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +CBrowserImpl::GetPersistence(PRBool* aPersistX, PRBool* aPersistY, + PRBool* aPersistCX, PRBool* aPersistCY, + PRBool* aPersistSizeMode) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +#endif + +//***************************************************************************** +// CBrowserImpl::nsIWebBrowserChromeFocus +//***************************************************************************** + +NS_IMETHODIMP CBrowserImpl::FocusNextElement() +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + if (!m_pBrowserFrameGlue->FocusNextElement()) + return NS_ERROR_FAILURE; + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::FocusPrevElement() +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + if (!m_pBrowserFrameGlue->FocusPrevElement()) + return NS_ERROR_FAILURE; + return NS_OK; +} + +//***************************************************************************** +// CBrowserImpl::nsIEmbeddingSiteWindow +//***************************************************************************** + +NS_IMETHODIMP CBrowserImpl::SetDimensions(PRUint32 aFlags, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + HWND h = m_pBrowserFrameGlue->GetBrowserFrameNativeWnd(); + CBrowserFrame* frame = (CBrowserFrame*)CWnd::FromHandle(h); + + UINT flags = SWP_NOACTIVATE | SWP_NOZORDER; + + if (!(aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION)) + flags |= SWP_NOMOVE; + + if ((aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER)) + { + CWnd* view = (CWnd*)frame->GetActiveView(); + NS_ENSURE_TRUE(view, NS_ERROR_FAILURE); + + RECT frameRect, viewRect; + frame->GetWindowRect(&frameRect); + view->GetClientRect(&viewRect); + + int deltax = frameRect.right - frameRect.left - viewRect.right; + int deltay = frameRect.bottom - frameRect.top - viewRect.bottom; + + frame->SetWindowPos(NULL, x, y, cx+deltax, cy+deltay, flags); + } + else if ((aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER)) + { + frame->SetWindowPos(NULL, x, y, cx, cy, flags); + } + else + { + flags |= SWP_NOSIZE; + frame->SetWindowPos(NULL, x, y, 0, 0, flags); + } + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::GetDimensions(PRUint32 aFlags, PRInt32 *x, PRInt32 *y, PRInt32 *cx, PRInt32 *cy) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + RECT wndRect; + HWND h = m_pBrowserFrameGlue->GetBrowserFrameNativeWnd(); + CBrowserFrame* frame = (CBrowserFrame*)CWnd::FromHandle(h); + + if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) + { + frame->GetWindowRect(&wndRect); + *x = wndRect.left; + *y = wndRect.top; + } + + if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER) + { + CWnd* view = (CWnd*)frame->GetActiveView(); + NS_ENSURE_TRUE(view, NS_ERROR_FAILURE); + + view->GetClientRect(&wndRect); + *cx = wndRect.right; + *cy = wndRect.bottom; + } + else if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) + { + frame->GetWindowRect(&wndRect); + *cx = wndRect.right - wndRect.left; + *cy = wndRect.bottom - wndRect.top; + } + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::GetSiteWindow(void** aSiteWindow) +{ + if (!aSiteWindow) + return NS_ERROR_NULL_POINTER; + + *aSiteWindow = 0; + if (m_pBrowserFrameGlue) { + HWND w = m_pBrowserFrameGlue->GetBrowserFrameNativeWnd(); + *aSiteWindow = reinterpret_cast(w); + } + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::SetFocus() +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + m_pBrowserFrameGlue->SetFocus(); + + nsresult rv; + nsCOMPtr baseWindow = do_QueryInterface(mWebBrowser, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = baseWindow->SetFocus(); + + return rv; +} + +NS_IMETHODIMP CBrowserImpl::GetTitle(PRUnichar** aTitle) +{ + NS_ENSURE_ARG_POINTER(aTitle); + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + CString title; + m_pBrowserFrameGlue->GetBrowserTitle(title); + + nsEmbedString nsTitle; + *aTitle = NS_StringCloneData(CStringToNSString(title)); + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::SetTitle(const PRUnichar* aTitle) +{ + NS_ENSURE_ARG_POINTER(aTitle); + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + +#ifndef _UNICODE + if (wcslen(aTitle)>1024) + return NS_OK; +#endif + + m_pBrowserFrameGlue->SetBrowserTitle(PRUnicharToCString(aTitle)); + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::GetVisibility(PRBool *aVisibility) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + m_pBrowserFrameGlue->GetVisibility(aVisibility); + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::SetVisibility(PRBool aVisibility) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + if (!mChromeLoaded && (mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) + return NS_OK; // Not yet, waiting for resize in UpdateBusyState + + m_pBrowserFrameGlue->SetVisibility(aVisibility); + + return NS_OK; +} + +//***************************************************************************** +// CBrowserImpl::nsIEmbeddingSiteWindow2 +//***************************************************************************** + +NS_IMETHODIMP CBrowserImpl::Blur() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + + +//***************************************************************************** +// CBrowserImpl::nsITooltipListener +//***************************************************************************** + +/* void onShowTooltip (in long aXCoords, in long aYCoords, in wstring aTipText); */ +NS_IMETHODIMP CBrowserImpl::OnShowTooltip(PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText) +{ + NS_ENSURE_ARG_POINTER(aTipText); + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + m_pBrowserFrameGlue->ShowTooltip(aXCoords, aYCoords, PRUnicharToCString(aTipText)); + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::OnHideTooltip() +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_ERROR_FAILURE); + + // WORKAROUND: Because the tooltip is not erased correctly when using the mouse wheel + // XXXX + nsCOMPtr baseWindow = do_QueryInterface(mWebBrowser); + if (baseWindow) baseWindow->Repaint(PR_FALSE); + + m_pBrowserFrameGlue->ShowTooltip(0, 0, nsnull); + + return NS_OK; +} + +#ifdef USE_WINDOW_PROVIDER +NS_IMETHODIMP CBrowserImpl::ProvideWindow(nsIDOMWindow *aParent, PRUint32 aChromeFlags, PRBool aPositionSpecified, PRBool aSizeSpecified, nsIURI *aURI, const nsAString & aName, const nsACString & aFeatures, PRBool *aWindowIsNew, nsIDOMWindow **_retval) +{ + NS_ENSURE_ARG_POINTER(aParent); + *_retval = nsnull; + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_OK); + + nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); + NS_ENSURE_TRUE(prefs, NS_OK); + + nsCOMPtr branch; + prefs->GetBranch("browser.link.", getter_AddRefs(branch)); + NS_ENSURE_TRUE(branch, NS_OK); + + PRInt32 containerPref; + NS_ENSURE_SUCCESS(branch->GetIntPref("open_newwindow", &containerPref), NS_OK); + + if ( containerPref != nsIBrowserDOMWindow::OPEN_NEWTAB && + containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) + return NS_OK; + + /* Now check our restriction pref. The restriction pref is a power-user's + fine-tuning pref. values: + 770 0: no restrictions - divert everything + 771 1: don't divert window.open at all + 772 2: don't divert window.open with features + 773 */ + + PRInt32 restrictionPref; + if (NS_FAILED(branch->GetIntPref("open_newwindow.restriction", + &restrictionPref)) || + restrictionPref < 0 || + restrictionPref > 2) + restrictionPref = 2; // Sane default behavior + + if (restrictionPref == 1) return NS_OK; + + if (restrictionPref == 2 && + // Only continue if there are no size/position features and no special + // chrome flags. + (aChromeFlags != nsIWebBrowserChrome::CHROME_ALL || + aPositionSpecified || aSizeSpecified)) + return NS_OK; + + CBrowserWrapper* window = m_pBrowserFrameGlue->ReuseWindow(containerPref == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW); + if (!window) return NS_OK; + + nsCOMPtr browser = window->GetWebBrowser(); + NS_ENSURE_TRUE(browser, NS_OK); + + nsCOMPtr domWindow; + browser->GetContentDOMWindow(getter_AddRefs(domWindow)); + NS_ENSURE_TRUE(domWindow, NS_OK); + + nsCOMPtr currentWindow; + mWebBrowser->GetContentDOMWindow(getter_AddRefs(currentWindow)); + NS_ENSURE_TRUE(currentWindow, NS_OK); + + //*aWindowIsNew = (containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW); + *aWindowIsNew = (currentWindow != domWindow); + + NS_ADDREF(*_retval = domWindow); + return NS_OK; +} +#endif + +//***************************************************************************** +// CBrowserImpl::nsIDOMEventListener +//***************************************************************************** + +NS_IMETHODIMP CBrowserImpl::HandleEvent(nsIDOMEvent *event) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_OK); + + nsresult rv; + nsEmbedString type; + event->GetType(type); + + if (type.Equals(NS_LITERAL_STRING("mousedown"))) + { + // XXXXXXXXXX: Quick fix for the gesture plugin + nsCOMPtr target; + event->GetTarget(getter_AddRefs(target)); + nsCOMPtr node = do_QueryInterface(target); + + HWND h = m_pBrowserFrameGlue->GetBrowserFrameNativeWnd(); + CBrowserFrame* frame = (CBrowserFrame*)CWnd::FromHandle(h); + CBrowserView* view = (CBrowserView*)frame->GetActiveView(); + view->m_contextNode = node; + return NS_OK; + } + + if (type.Equals(NS_LITERAL_STRING("click"))) + { + //event->PreventDefault(); + + nsCOMPtr mouseEvent(do_QueryInterface(event)); + NS_ENSURE_TRUE(mouseEvent, NS_ERROR_FAILURE); + + PRUint16 button; + mouseEvent->GetButton(&button); + + PRBool altKey, shiftKey, ctrlKey; + mouseEvent->GetCtrlKey(&ctrlKey); + mouseEvent->GetShiftKey(&shiftKey); + mouseEvent->GetAltKey(&altKey); + + UINT flags = 0; + + switch (button) { + case 0: flags = MK_LBUTTON; break; + case 1: flags = MK_MBUTTON; break; + case 2: flags = MK_RBUTTON; break; + default : ; + } + + if (altKey) flags |= FALT << 8; + if (shiftKey) flags |= FSHIFT << 8; + if (ctrlKey) flags |= FCONTROL << 8; + + nsCOMPtr target; + event->GetTarget(getter_AddRefs(target)); + nsCOMPtr node = do_QueryInterface(target); + + if (m_pBrowserFrameGlue->MouseAction(node, flags)) + event->PreventDefault(); + + return NS_OK; + } + + if (type.Equals(NS_LITERAL_STRING("DOMContentLoaded"))) + { + // DOMContentLoaded is not send if the page is reloaded from cache + // Nevertheless I'm using it to get the IE favicon without waiting + // for all images of the page to be loaded + m_pBrowserFrameGlue->SetFavIcon(nsnull); + return NS_OK; + } + + if (type.Equals(NS_LITERAL_STRING("DOMLinkAdded"))) + { + nsCOMPtr target; + event->GetTarget(getter_AddRefs(target)); + NS_ENSURE_TRUE (target, NS_ERROR_FAILURE); + + nsCOMPtr elem = do_QueryInterface(target); + NS_ENSURE_TRUE (elem, NS_ERROR_FAILURE); + + nsEmbedString value; + rv = elem->GetTagName(value); + + rv = elem->GetAttribute(NS_LITERAL_STRING("rel"), value); + NS_ENSURE_SUCCESS (rv, rv); + + if ( wcsicmp(value.get(), L"SHORTCUT ICON") == 0 || + wcsicmp(value.get(), L"ICON") == 0 ) + { + + /* rv = elem->GetAttribute(NS_LITERAL_STRING("type"), value); + NS_ENSURE_SUCCESS (rv, rv); + if (value.Equals(NS_LITERAL_STRING("image/png"))) + return NS_OK;*/ + + rv = elem->GetAttribute (NS_LITERAL_STRING("href"), value); + NS_ENSURE_SUCCESS (rv, rv); + NS_ENSURE_FALSE (value.IsEmpty(), NS_ERROR_FAILURE); + + nsCOMPtr domDoc; + elem->GetOwnerDocument (getter_AddRefs(domDoc)); + NS_ENSURE_TRUE (domDoc, NS_ERROR_FAILURE); + + /* See if this is from the toplevel frame */ + nsCOMPtr docView (do_QueryInterface (domDoc)); + NS_ENSURE_TRUE (docView, NS_ERROR_FAILURE); + + nsCOMPtr abstractView; + docView->GetDefaultView (getter_AddRefs (abstractView)); + + nsCOMPtr domWin (do_QueryInterface (abstractView)); + NS_ENSURE_TRUE (domWin, NS_ERROR_FAILURE); + + nsCOMPtr topDomWin; + domWin->GetTop (getter_AddRefs (topDomWin)); + + nsCOMPtr domWinAsISupports (do_QueryInterface (domWin)); + nsCOMPtr topDomWinAsISupports (do_QueryInterface (topDomWin)); + /* disallow subframes to set favicon */ + if (domWinAsISupports != topDomWinAsISupports) return NS_OK; + + nsCOMPtr doc = do_QueryInterface (domDoc); + NS_ENSURE_TRUE (doc, NS_ERROR_FAILURE); + + nsEmbedString spec; + rv = doc->GetDocumentURI (spec); + NS_ENSURE_SUCCESS (rv, NS_ERROR_FAILURE); + + nsCOMPtr docUri; + NewURI (getter_AddRefs (docUri), spec); + + nsEmbedCString favicon; + nsEmbedCString cvalue; + NS_UTF16ToCString(value, NS_CSTRING_ENCODING_UTF8, cvalue); + rv = docUri->Resolve (cvalue, favicon); + NS_ENSURE_SUCCESS (rv, NS_ERROR_FAILURE); + + nsCOMPtr favUri; + NewURI (getter_AddRefs (favUri), favicon); + NS_ENSURE_TRUE (favUri, NS_ERROR_FAILURE); + + /* check if load is allowed */ + nsCOMPtr secMan + (do_GetService("@mozilla.org/scriptsecuritymanager;1")); + /* refuse if we can't check */ + NS_ENSURE_TRUE (secMan, NS_ERROR_FAILURE); + + rv = secMan->CheckLoadURI(docUri, favUri, + nsIScriptSecurityManager::STANDARD); + /* failure means it didn't pass the security check */ + if (NS_FAILED (rv)) return NS_OK; + + /* Hide password part */ + nsEmbedCString password; + favUri->GetUsername(password); + favUri->SetUserPass(password); + + m_pBrowserFrameGlue->SetFavIcon(favUri); + } + return NS_OK; + } + + if (type.Equals(NS_LITERAL_STRING("DOMPopupBlocked"))) + { + nsCOMPtr popupEvent = do_QueryInterface(event); + NS_ENSURE_TRUE (popupEvent, NS_ERROR_FAILURE); + + nsCOMPtr uri; +#if GECKO_VERSION > 18 + // FIXME + popupEvent->GetPopupWindowURI(getter_AddRefs(uri)); +#else + popupEvent->GetRequestingWindowURI(getter_AddRefs(uri)); +#endif + NS_ENSURE_TRUE (uri, NS_ERROR_FAILURE); + + nsEmbedCString host; + rv = uri->GetHost(host); + NS_ENSURE_SUCCESS (rv, rv); + NS_ENSURE_TRUE (host.Length(), NS_OK); + + m_pBrowserFrameGlue->PopupBlocked(host.get()); + return NS_OK; + } + + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/k-meleon/BrowserImpl.h b/k-meleon/BrowserImpl.h new file mode 100644 index 00000000..b03707f8 --- /dev/null +++ b/k-meleon/BrowserImpl.h @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _BROWSERIMPL_H +#define _BROWSERIMPL_H +#define USE_WINDOW_PROVIDER + +#include "IBrowserFrameGlue.h" + +#include "nsIWebBrowserChromeFocus.h" +#include "nsIDOMEventListener.h" +#include "nsISHistoryListener.h" +#include "nsIObserver.h" +#include "nsIDOMMouseListener.h" +#include "nsITooltipListener.h" +#ifdef USE_WINDOW_PROVIDER +#include "nsIWindowProvider.h" +#endif + +class CBrowserImpl : public nsIInterfaceRequestor, + public nsIWebBrowserChrome, + public nsIWebBrowserChromeFocus, + public nsIEmbeddingSiteWindow2, + public nsIWebProgressListener, + public nsIContextMenuListener2, + public nsITooltipListener, + public nsSupportsWeakReference, + // public nsISHistoryListener, + // public nsIObserver, +#ifdef USE_WINDOW_PROVIDER + public nsIWindowProvider, +#endif + public nsIDOMEventListener + + //public nsIDOMMouseListener +{ +public: + CBrowserImpl(); + ~CBrowserImpl(); + NS_METHOD Init(PBROWSERGLUE pBrowserFrameGlue, + nsIWebBrowser* aWebBrowser); + + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSIWEBBROWSERCHROME + NS_DECL_NSIWEBBROWSERCHROMEFOCUS + NS_DECL_NSIEMBEDDINGSITEWINDOW + NS_DECL_NSIEMBEDDINGSITEWINDOW2 + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_NSICONTEXTMENULISTENER2 + NS_DECL_NSITOOLTIPLISTENER + //NS_DECL_NSISHISTORYLISTENER + //NS_DECL_NSIOBSERVER + NS_DECL_NSIDOMEVENTLISTENER +#ifdef USE_WINDOW_PROVIDER + NS_DECL_NSIWINDOWPROVIDER +#endif + /*NS_IMETHOD MouseDown(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseUp(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseClick(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseDblClick(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseOver(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseOut(nsIDOMEvent* aDOMEvent);*/ + +protected: + + PBROWSERGLUE m_pBrowserFrameGlue; + nsCOMPtr mWebBrowser; + PRUint32 mChromeFlags; + PRBool mChromeLoaded; +}; + +class CFavIconListener : public nsIDOMEventListener +{ + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDOMEVENTLISTENER + + CFavIconListener(); + virtual ~CFavIconListener(); + + //nsresult Init(CBrowserView* aBrowser); + nsresult Init(PBROWSERGLUE pBrowserFrameGlue); + void LoadFavIcon(nsIURI* iconURI); + void AddIcon(char* uri, TCHAR* file, nsresult astatus); + void Reset(nsIURI*); + + static void DwnCall(char* , TCHAR* , nsresult, void* ); + + + protected: + PBROWSERFRAMEGLUE m_pBrowserFrameGlue; +// CBrowserView *mBrowser; + BOOL m_bIcon; +}; + +#endif //_BROWSERIMPL_H diff --git a/k-meleon/BrowserImplCtxMenuLstnr.cpp b/k-meleon/BrowserImplCtxMenuLstnr.cpp new file mode 100644 index 00000000..6d185002 --- /dev/null +++ b/k-meleon/BrowserImplCtxMenuLstnr.cpp @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * + * ***** END LICENSE BLOCK ***** */ + + +#include "stdafx.h" + + +#include "BrowserImpl.h" +#include "IBrowserFrameGlue.h" + +#include "nsIDOMEvent.h" +#include "nsIDOMEventTarget.h" +#include "nsIDOMHTMLInputElement.h" + + +//***************************************************************************** +// CBrowserImpl::nsIContextMenuListener +//***************************************************************************** + +NS_IMETHODIMP CBrowserImpl::OnShowContextMenu(PRUint32 aContextFlags, nsIContextMenuInfo *aInfo) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_OK); + + // No context menu for chrome + if (mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) + return NS_OK; + + /* + SContextData ctx; + + nsCOMPtr node; + nsresult rv = aInfo->GetTargetNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + + ctx.node = node; + + */ + + nsCOMPtr node; + nsresult rv = aInfo->GetTargetNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + + if (aContextFlags & nsIContextMenuListener2::CONTEXT_INPUT) + { + if (!(aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE)) { + // Mozilla don't tell if the input is of type text or password... + nsCOMPtr inputElement(do_QueryInterface(node)); + if (inputElement) { + nsEmbedString inputElemType; + inputElement->GetType(inputElemType); + if ((wcsicmp(inputElemType.get(), L"text") == 0) || + (wcsicmp(inputElemType.get(), L"password") == 0)) + aContextFlags |= nsIContextMenuListener2::CONTEXT_TEXT; + } + } + } + m_pBrowserFrameGlue->ShowContextMenu(aContextFlags, node); + + return NS_OK; +} diff --git a/k-meleon/BrowserImplWebPrgrsLstnr.cpp b/k-meleon/BrowserImplWebPrgrsLstnr.cpp new file mode 100644 index 00000000..0a15caf1 --- /dev/null +++ b/k-meleon/BrowserImplWebPrgrsLstnr.cpp @@ -0,0 +1,189 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * + * ***** END LICENSE BLOCK ***** */ + + +#include "stdafx.h" + +#include "BrowserImpl.h" +#include "IBrowserFrameGlue.h" +#include "nsIRequest.h" +#include "nsIChannel.h" + +//***************************************************************************** +// CBrowserImpl::nsIWebProgressListener Implementation +//***************************************************************************** +// +// - Implements browser progress update functionality +// while loading a page into the embedded browser +// +// - Calls methods via the IBrowserFrameGlue interace +// (available thru' the m_pBrowserFrameGlue member var) +// to do the actual statusbar/progress bar updates. +// + +NS_IMETHODIMP CBrowserImpl::OnProgressChange(nsIWebProgress *progress, + nsIRequest *request, + PRInt32 curSelfProgress, + PRInt32 maxSelfProgress, + PRInt32 curTotalProgress, + PRInt32 maxTotalProgress) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_OK); + + PRInt32 nProgress = curTotalProgress; + PRInt32 nProgressMax = maxTotalProgress; + + if (nProgressMax == 0) + nProgressMax = LONG_MAX; + + if (nProgress > nProgressMax) + nProgress = nProgressMax; // Progress complete + + m_pBrowserFrameGlue->UpdateProgress(nProgress, nProgressMax); + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::OnStateChange(nsIWebProgress *progress, + nsIRequest *request, + PRUint32 progressStateFlags, + nsresult status) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_OK); + + if ((progressStateFlags & STATE_START) && (progressStateFlags & STATE_IS_NETWORK)) + { + // Navigation has begun + m_pBrowserFrameGlue->UpdateBusyState(PR_TRUE); + } + + if ((progressStateFlags & STATE_STOP) && (progressStateFlags & STATE_IS_NETWORK)) + { + // We've completed the navigation + /*if (request) + { + CString msg; + + nsCOMPtr channel = do_QueryInterface(request); + if (channel) + { + switch (status) { + case 0x804B0002: + msg = "Stopped"; + break; + case 0x804B000E: + msg = "Time out"; + break; + } + } + }*/ + + if (!mChromeLoaded && mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) + { + mChromeLoaded = PR_TRUE; + + nsCOMPtr domWindow; + mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + NS_ENSURE_TRUE(domWindow, NS_OK); + + domWindow->SizeToContent(); + + // It must be repositionned somewhat after the resize. Centering it + // all the time is not that bad. + //if (pThis->m_chromeMask & nsIWebBrowserChrome::CHROME_CENTER_SCREEN) + HWND h = m_pBrowserFrameGlue->GetBrowserFrameNativeWnd(); + CWnd* frame = CWnd::FromHandle(h); + frame->CenterWindow(); + SetVisibility(PR_TRUE); + } + m_pBrowserFrameGlue->UpdateBusyState(PR_FALSE); + m_pBrowserFrameGlue->UpdateProgress(0, 100); // Clear the prog bar + m_pBrowserFrameGlue->UpdateStatusBarText(nsnull); // Clear the status bar + } + + return NS_OK; +} + +NS_IMETHODIMP CBrowserImpl::OnLocationChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsIURI *location) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_OK); + + PRBool isSubFrameLoad = PR_FALSE; // Is this a subframe load + if (aWebProgress) { + nsCOMPtr domWindow; + nsCOMPtr topDomWindow; + aWebProgress->GetDOMWindow(getter_AddRefs(domWindow)); + if (domWindow) { // Get root domWindow + domWindow->GetTop(getter_AddRefs(topDomWindow)); + } + if (domWindow != topDomWindow) + isSubFrameLoad = PR_TRUE; + + } + + if (isSubFrameLoad) + return NS_OK; + + m_pBrowserFrameGlue->UpdateCurrentURI(location); + + return NS_OK; +} + +NS_IMETHODIMP +CBrowserImpl::OnStatusChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsresult aStatus, + const PRUnichar* aMessage) +{ + PRBool b; + // Prevent showing status update for download. + // Hope it's not a bad way to do that + aWebProgress->GetIsLoadingDocument(&b); + + if (b) SetStatus(0, aMessage); + + return NS_OK; +} + + + +NS_IMETHODIMP +CBrowserImpl::OnSecurityChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRUint32 state) +{ + NS_ENSURE_TRUE(m_pBrowserFrameGlue, NS_OK); + m_pBrowserFrameGlue->UpdateSecurityStatus(state); + + return NS_OK; +} diff --git a/k-meleon/BrowserView.cpp b/k-meleon/BrowserView.cpp new file mode 100644 index 00000000..e192016e --- /dev/null +++ b/k-meleon/BrowserView.cpp @@ -0,0 +1,1022 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * Rod Spears + * + * ***** END LICENSE BLOCK ***** */ + +// File Overview.... +// +// When the CBrowserFrm creates this View: +// - CreateBrowser() is called in OnCreate() to create the +// mozilla embeddable browser +// +// OnSize() method handles the window resizes and calls the approriate +// interface method to resize the embedded browser properly +// +// Command handlers to handle browser navigation - OnNavBack(), +// OnNavForward() etc +// +// DestroyBrowser() called for cleaning up during object destruction +// +// Some important coding notes.... +// +// 1. Make sure we do not have the CS_HREDRAW|CS_VREDRAW in the call +// to AfxRegisterWndClass() inside of PreCreateWindow() below +// If these flags are present then you'll see screen flicker when +// you resize the frame window +// +// Next suggested file to look at : BrowserImpl.cpp +// + +#include "stdafx.h" +#include "MfcEmbed.h" +#include "BrowserView.h" +#include "BrowserFrm.h" +#include "BrowserWindow.h" +#include "MozUtils.h" +#include "Permissions.h" +#include "Utils.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +static const TCHAR* KMELEON_HOMEPAGE_URL = _T("http://kmeleon.sourceforge.net/"); +static const TCHAR* KMELEON_FORUM_URL = _T("http://kmeleon.sourceforge.net/forum/"); +static const TCHAR* KMELEON_FAQ_URL = _T("http://kmeleon.sourceforge.net/docs/faq.php"); +static const TCHAR* KMELEON_MANUAL_URL = _T("http://kmeleon.sourceforge.net/manual/"); +static const TCHAR* ABOUT_PLUGINS_URL = _T("about:plugins"); +static const TCHAR* ABOUT_KMELEON = _T("about:"); + +IMPLEMENT_DYNAMIC(CBrowserView, CWnd) + +BEGIN_MESSAGE_MAP(CBrowserView, CWnd) + //{{AFX_MSG_MAP(CBrowserView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_SIZE() + ON_WM_TIMER() + ON_WM_MOUSEACTIVATE() + ON_WM_ACTIVATE() + + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs) + ON_COMMAND(ID_FILE_CLOSE, OnFileClose) + ON_COMMAND(ID_VIEW_SOURCE, OnViewSource) + ON_COMMAND(ID_VIEW_INFO, OnViewInfo) + ON_COMMAND(ID_NAV_BACK, OnNavBack) + ON_COMMAND(ID_NAV_FORWARD, OnNavForward) + ON_COMMAND(ID_NAV_SEARCH, OnNavSearch) + ON_COMMAND(ID_NAV_HOME, OnNavHome) + ON_COMMAND(ID_NAV_RELOAD, OnNavReload) + ON_COMMAND(ID_NAV_FORCE_RELOAD, OnNavForceReload) + ON_COMMAND(ID_FILE_SAVE_FRAME_AS, OnFileSaveFrameAs) + ON_COMMAND(ID_NAV_STOP, OnNavStop) + ON_COMMAND(ID_NAV_GO, OnNewUrlEnteredInUrlBar) + ON_COMMAND(ID_EDIT_CUT, OnCut) + ON_COMMAND(ID_EDIT_COPY, OnCopy) + ON_COMMAND(ID_EDIT_PASTE, OnPaste) + ON_COMMAND(ID_EDIT_UNDO, OnUndo) + ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateCut) + ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateCopy) + ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdatePaste) + ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateUndo) + ON_COMMAND(ID_EDIT_SELECT_ALL, OnSelectAll) + ON_COMMAND(ID_EDIT_SELECT_NONE, OnSelectNone) + ON_COMMAND(ID_OPEN_LINK_IN_NEW_WINDOW, OnOpenLinkInNewWindow) + ON_COMMAND(ID_OPEN_LINK_IN_BACKGROUND, OnOpenLinkInBackground) + ON_COMMAND(ID_VIEW_IMAGE, OnViewImageInNewWindow) + ON_COMMAND(ID_COPY_LINK_LOCATION, OnCopyLinkLocation) + ON_COMMAND(ID_COPY_IMAGE_LOCATION, OnCopyImageLocation) + ON_COMMAND(ID_COPY_IMAGE_CONTENT, OnCopyImageContent) + ON_COMMAND(ID_OPEN_LINK, OnOpenLink) + ON_COMMAND(ID_SAVE_LINK_AS, OnSaveLinkAs) + ON_COMMAND(ID_SAVE_IMAGE_AS, OnSaveImageAs) + //ON_COMMAND(ID_EDIT_FIND, OnShowFindDlg) + ON_COMMAND(ID_FILE_PRINT, OnFilePrint) + ON_COMMAND(ID_FILE_PRINTPREVIEW, OnFilePrintPreview) + ON_COMMAND(ID_FILE_PRINTSETUP, OnFilePrintSetup) + ON_COMMAND(ID_VIEW_FRAME_SOURCE, OnViewFrameSource) + ON_COMMAND(ID_VIEW_PAGE_INFO, OnViewPageInfo) + ON_COMMAND(ID_VIEW_FRAME_INFO, OnViewFrameInfo) + ON_COMMAND(ID_OPEN_FRAME, OnOpenFrame) + ON_COMMAND(ID_OPEN_FRAME_IN_NEW_WINDOW, OnOpenFrameInNewWindow) + ON_COMMAND(ID_OPEN_FRAME_IN_BACKGROUND, OnOpenFrameInBackground) + //ON_REGISTERED_MESSAGE(WM_FINDMSG, OnFindMsg) + ON_COMMAND(ID_LINK_KMELEON_HOME, OnKmeleonHome) + ON_COMMAND(ID_LINK_KMELEON_FORUM, OnKmeleonForum) + ON_UPDATE_COMMAND_UI(ID_NAV_BACK, OnUpdateNavBack) + ON_UPDATE_COMMAND_UI(ID_NAV_FORWARD, OnUpdateNavForward) + ON_UPDATE_COMMAND_UI(ID_NAV_STOP, OnUpdateNavStop) + ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnUpdateFilePrint) + ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, OnUpdateFileSave) + // ON_UPDATE_COMMAND_UI(ID_FILE_PRINTSETUP, OnUpdatePrintSetup) + ON_UPDATE_COMMAND_UI(ID_FILE_PRINTPREVIEW, OnUpdateFilePrintPreview) + ON_UPDATE_COMMAND_UI(ID_VIEW_IMAGE, OnUpdateViewImage) + + ON_COMMAND(ID_FONT_INCREASE, OnIncreaseFont) + ON_COMMAND(ID_FONT_DECREASE, OnDecreaseFont) + ON_COMMAND(ID_LINK_KMELEON_FAQ, OnKmeleonFAQ) + ON_COMMAND(ID_LINK_KMELEON_MANUAL, OnKmeleonManual) + ON_COMMAND(ID_LINK_ABOUT_PLUGINS, OnAboutPlugins) + //ON_COMMAND(ID_MOUSE_ACTION, OnMouseAction) + ON_COMMAND(ID_SECURITY_STATE_ICON, OnSecurityStateIcon) + ON_COMMAND(ID_POPUP_BLOCKED_ICON, OnPopupBlockedIcon) + + + //ON_MESSAGE(UWM_REFRESHTOOLBARITEM, RefreshToolBarItem) + ON_NOTIFY(CBEN_DRAGBEGIN, ID_URL_BAR, OnDragURL) + ON_NOTIFY(CBEN_BEGINEDIT, ID_URL_BAR, OnBeginEditURL) + ON_COMMAND(IDOK, OnNewUrlEnteredInUrlBar) + ON_CBN_SELENDOK(ID_URL_BAR, OnUrlSelectedInUrlBar) + + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +CBrowserView::CBrowserView() +{ + m_pWindow = NULL; + m_pBrowserFrameGlue = NULL; + m_pBrowserGlue = NULL; + +// m_pFindDlg = NULL; +// m_pPrintProgressDlg = NULL; + m_bCurrentlyPrinting = FALSE; + + m_InPrintPreview = FALSE; + + m_tempFileCount = 0; + + m_contextNode = NULL; + +// m_refreshBackButton = FALSE; +// m_refreshForwardButton = FALSE; + + m_panning = FALSE; + maccel_pan = FALSE; +} + +CBrowserView::~CBrowserView() +{ + if (m_pBrowserGlue) delete m_pBrowserGlue; + ASSERT(m_pWindow == NULL); +} + +//* This is a good place to create the embeddable browser +// instance +// + +int CBrowserView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + m_pWindow = new CBrowserWrapper(); + if (!m_pWindow->CreateBrowser(this, mpBrowserFrame->IsDialog())) //XXX + return -1; + + //m_pWindow->SetBrowserFrameGlue(m_pBrowserFrameGlue); + m_pWindow->SetBrowserGlue(m_pBrowserGlue); + + return 0; +} + +void CBrowserView::OnDestroy() +{ + DeleteTempFiles(); + m_pWindow->SetBrowserGlue(NULL); + m_pWindow->DestroyBrowser(); + delete m_pWindow; + m_pWindow = NULL; + if (m_pBrowserGlue) { + delete (CBrowserGlue*)m_pBrowserGlue; + m_pBrowserGlue = NULL; + } +} + +BOOL CBrowserView::PreCreateWindow(CREATESTRUCT& cs) +{ + if (!CWnd::PreCreateWindow(cs)) + return FALSE; + + cs.dwExStyle |= WS_EX_CLIENTEDGE; + cs.style &= ~WS_BORDER; + cs.style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS; + cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS, + ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL); + + return TRUE; +} + +// Adjust the size of the embedded browser +// in response to any container size changes +// +void CBrowserView::OnSize( UINT nType, int cx, int cy) +{ + m_pWindow->SetPositionAndSize(0, 0, cx, cy); +} + +// Called by this object's creator i.e. the CBrowserFrame object +// to pass its pointer to us +// +void CBrowserView::SetBrowserFrame(CBrowserFrame* pBrowserFrame) +{ + mpBrowserFrame = pBrowserFrame; +} + +void CBrowserView::SetBrowserGlue(PBROWSERGLUE pBrowserGlue) +{ + if (m_pBrowserGlue) delete m_pBrowserGlue; + m_pBrowserGlue = pBrowserGlue; + if (m_pWindow) m_pWindow->SetBrowserGlue(m_pBrowserGlue); +} + +void CBrowserView::SetBrowserFrameGlue(PBROWSERFRAMEGLUE pBrowserFrameGlue) +{ + m_pBrowserFrameGlue = pBrowserFrameGlue; + if (m_pWindow) m_pWindow->SetBrowserFrameGlue(m_pBrowserFrameGlue); +} + +void CBrowserView::OnBeginEditURL( NMHDR * pNotifyStruct, LRESULT * result ) +{ + // Send when the url bar get the focus. Deactivate gecko so that it + // can't steal the focus. + m_pWindow->SetActive(FALSE); + *result = 0; +} + +void CBrowserView::OnEndEditURL( NMHDR * pNotifyStruct, LRESULT * result ) +{ + //mpBrowserFrame->m_wndUrlBar.EditChanged(FALSE); + *result = 0; +} + +// A new URL was entered in the URL bar +// Get the URL's text from the Urlbar's (ComboBox's) EditControl +// and navigate to that URL +// +void CBrowserView::OnNewUrlEnteredInUrlBar() +{ + m_pWindow->SetActive(TRUE); + +#ifdef INTERNAL_SITEICONS + GetBrowserGlue()->mIconURI = nsnull; +#endif + + // Ugly hack: needed because I can get an OnCbnEditchange + // and no OnCbenEndedit + TRACE0("EditChanged FALSE in CBrowserView::OnNewUrlEnteredInUrlBar\n"); + mpBrowserFrame->m_wndUrlBar.EditChanged(FALSE); + + //mpBrowserFrame->m_wndUrlBar.EditChanged(FALSE); + + // Get the currently entered URL + CString strUrl = mpBrowserFrame->m_wndUrlBar.GetEnteredURL(); + + + // Add what was just entered into the MRI list + if (theApp.preferences.MRUbehavior == 2) + theApp.m_MRUList->AddURL(strUrl); + + //if(IsViewSourceUrl(strUrl)) +// OpenViewSourceWindow(strUrl.GetBuffer(0)); + //else { + CString urls = NicknameLookup(strUrl); + OpenMultiURL(urls.GetBuffer(0), TRUE); + //} +} + +// A URL has been selected from the UrlBar's dropdown list +void CBrowserView::OnUrlSelectedInUrlBar() +{ + CString strUrl; + + //mpBrowserFrame->m_wndUrlBar.EditChanged(FALSE); + if (!mpBrowserFrame->m_wndUrlBar.GetSelectedURL(strUrl)) + return; + + //m_pWindow->SetActive(TRUE); + +// if(IsViewSourceUrl(strUrl)) +// OpenViewSourceWindow(strUrl.GetBuffer(0)); +// else { + CString urls = NicknameLookup(strUrl); + OpenMultiURL(urls.GetBuffer(0), TRUE); +// } +} + +void CBrowserView::OnViewSource() +{ + OpenViewSourceWindow(); +} + +void CBrowserView::OnViewFrameSource() +{ + USES_CONVERSION; + OpenViewSourceWindow(TRUE); +} + +void CBrowserView::OnViewInfo() +{ + ShowSecurityInfo(); +} + +void CBrowserView::OnNavBack() +{ + m_pWindow->GoBack(); +} + +void CBrowserView::OnUpdateNavBack(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pWindow->CanGoBack()); +/* + PRBool canGoBack = PR_FALSE; + + // Buttons get "stuck" down after selecting + // a menu item, this fixes them + if (m_refreshBackButton) { + pCmdUI->Enable(FALSE); + pCmdUI->Enable(TRUE); + m_refreshBackButton = FALSE; + } + + if (mWebNav) + mWebNav->GetCanGoBack(&canGoBack); + + pCmdUI->Enable(canGoBack);*/ +} + +void CBrowserView::OnNavForward() +{ + m_pWindow->GoForward(); +} + +void CBrowserView::OnUpdateNavForward(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pWindow->CanGoForward()); +} + +void CBrowserView::OnNavHome() +{ + CString homePage = theApp.preferences.GetString("kmeleon.general.homePage", _T("")); + if (!homePage.IsEmpty()) + OpenURL(homePage); + else + OpenURL(_T("about:blank")); +} + +void CBrowserView::_OnNavReload(BOOL force) +{ + // If there is no URI to reload, load the address in the url bar + CString url = m_pWindow->GetURI(); + if (url.IsEmpty() || url.Compare(_T("about:blank")) == 0) + { + CString url = mpBrowserFrame->m_wndUrlBar.GetEnteredURL(); + if (!url.IsEmpty()) + OpenURL(url); + } + else + m_pWindow->Reload(force); +} + +void CBrowserView::OnNavReload() +{ + + _OnNavReload(FALSE); +} + +void CBrowserView::OnNavForceReload() +{ +#ifdef INTERNAL_SITEICONS + if (GetBrowserGlue()->mIconURI) { + theApp.favicons.RefreshIcon(GetBrowserGlue()->mIconURI); + GetBrowserGlue()->mIconURI = nsnull; + } +#endif + _OnNavReload(TRUE); +} + +void CBrowserView::OnNavStop() +{ + m_pWindow->Stop(); +} + +void CBrowserView::OnUpdateNavStop(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pWindow->IsBusy());//m_bDocumentLoading); +} + +void CBrowserView::OnUpdateFileSave(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pWindow->CanSave()); +} + +void CBrowserView::OnCut() +{ + if (::IsChild(m_hWnd, ::GetFocus())) + m_pWindow->Cut(); +} + +void CBrowserView::OnUpdateCut(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pWindow->CanCut()); +} + +void CBrowserView::OnCopy() +{ + if (::IsChild(m_hWnd, ::GetFocus())) + m_pWindow->Copy(); +} + +void CBrowserView::OnUpdateCopy(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pWindow->CanCopy()); +} + +void CBrowserView::OnPaste() +{ + CWnd* focus = GetFocus(); + if (focus && focus->IsKindOf(RUNTIME_CLASS(CEdit))) { + ((CEdit*)focus)->Paste(); + return; + } + + if (::IsChild(m_hWnd, ::GetFocus())) + m_pWindow->Paste(); +} + +void CBrowserView::OnUpdatePaste(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pWindow->CanPaste()); +} + +void CBrowserView::OnUndo() +{ + if (::IsChild(m_hWnd, ::GetFocus())) + m_pWindow->Undo(); +} + +void CBrowserView::OnUpdateUndo(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_pWindow->CanUndo()); +} + +void CBrowserView::OnSelectAll() +{ + m_pWindow->SelectAll(); +} + +void CBrowserView::OnSelectNone() +{ + m_pWindow->SelectNone(); +} + +void CBrowserView::OnFileOpen() +{ + TCHAR lpszFilter[] = + _T("HTML Files Only (*.htm;*.html)|*.htm;*.html|") + _T("All Files (*.*)|*.*||"); + + CFileDialog fileDlg (TRUE, NULL, NULL, 0, lpszFilter, this); + if (fileDlg.DoModal() == IDOK) + { + CString pathName = fileDlg.GetPathName(); + FILE *test = _tfopen(pathName, _T("r")); + if (!test) { + // if the file doesn't exist, they probably typed a url... + // so chop off the path (for some reason GetFileName doesn't work for us... + pathName = pathName.Mid(pathName.ReverseFind('\\')+1); + pathName = NicknameLookup(pathName); + } else { + fclose(test); + } + OpenMultiURL(pathName); + } +} + +void CBrowserView::OnFileSaveAs() +{ + // Prevent the incomplete save of an html document + if (!m_pWindow->CanSave() + && !theApp.preferences.GetBool("kmeleon.download.allowIncompleteSave", FALSE)) + { + AfxMessageBox(IDS_NOT_FINISHED_LOADING, MB_OK|MB_ICONERROR); + } + + if (!m_pWindow->SaveDocument(FALSE)) + AfxMessageBox(IDS_SAVE_FAILED, MB_OK|MB_ICONERROR); +} + +void CBrowserView::OnCopyLinkLocation() +{ + CString href, title; + if (!::GetLinkTitleAndHref(m_contextNode, href, title)) + return; + + if (!OpenClipboard()) + return; + + HGLOBAL hClipData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, href.GetLength() + 1); + + if (hClipData) { + char *pszClipData = (char*)::GlobalLock(hClipData); + if (pszClipData) { + USES_CONVERSION; + strcpy(pszClipData, T2CA(href)); + ::GlobalUnlock(hClipData); + ::EmptyClipboard(); + ::SetClipboardData(CF_TEXT, hClipData); + } + } + CloseClipboard(); +} + +void CBrowserView::OnOpenLink() +{ + CString url, title; + if (!GetLinkTitleAndHref(m_contextNode, url, title)) + return; + + OpenURL(url, GetCurrentURI()); + /* + if (m_ctxData.linkUrl.IsEmpty()) + return; + + OpenURL(m_ctxData.linkUrl, TRUE);*/ +} + +void CBrowserView::OnOpenLinkInNewWindow() +{ + CString url, title; + + if (!GetLinkTitleAndHref(m_contextNode, url, title)) + return; + + + OpenURLInNewWindow(url, GetCurrentURI(), FALSE); + /* + if (m_ctxData.linkUrl.IsEmpty()) + return; + + OpenURLInNewWindow(m_ctxData.linkUrl, FALSE, TRUE);*/ +} + +void CBrowserView::OnOpenLinkInBackground() +{ + CString url, title; + if (!::GetLinkTitleAndHref(m_contextNode, url, title)) + return; + + OpenURLInNewWindow(url, GetCurrentURI(), TRUE); +} + +void CBrowserView::OnViewImageInNewWindow() +{ + CString imgSrc; + if (!::GetImageSrc(m_contextNode, imgSrc)) + if (!::GetBackgroundImageSrc(m_contextNode, imgSrc)) + return; + + OpenURLInNewWindow(imgSrc, GetCurrentURI(), FALSE); +} + +void CBrowserView::OnUpdateViewImage(CCmdUI *pCmdUI) +{ + CString imgSrc; + if (!::GetImageSrc(m_contextNode, imgSrc)) + ::GetBackgroundImageSrc(m_contextNode, imgSrc); + + pCmdUI->Enable(!imgSrc.IsEmpty()); +} + +BOOL CBrowserView::SaveLink(LPCTSTR url) +{ + ASSERT(url); + if (!url || !*url) + return FALSE; + + if (!m_pWindow->SaveURL(url)) { + AfxMessageBox(IDS_SAVE_FAILED, MB_OK|MB_ICONERROR); + return FALSE; + } + + return TRUE; +} + +void CBrowserView::OnSaveLinkAs() +{ + CString url, title; + if (!GetLinkTitleAndHref(m_contextNode, url, title)) + return; + SaveLink(url); +} + +void CBrowserView::OnSaveImageAs() +{ + CString imgUrl; + if (!GetImageSrc(m_contextNode, imgUrl)) + if (!GetBackgroundImageSrc(m_contextNode, imgUrl)) + return; + + SaveLink(imgUrl); + + /* + nsresult rv; + nsCOMPtr imageURI; + rv = NewURI(getter_AddRefs(imageURI), mCtxMenuImgSrc); + NS_ENSURE_SUCCESS(rv, ); + + nsCOMPtr referrer; + mWebNav->GetCurrentURI(getter_AddRefs(referrer)); + + CSaveAsHandler* handler = new CSaveAsHandler(nsnull, nsnull, imageURI, nsnull, nsnull, referrer, mpBrowserFrame); + rv = handler->Save(mCtxImgType.get(), mCtxImgDisposition.get()); + if (NS_FAILED(rv) && rv != NS_ERROR_ABORT) + AfxMessageBox(IDS_SAVE_FAILED, MB_OK|MB_ICONERROR);*/ +} + +void CBrowserView::OnOpenFrame() +{ + CString url = m_pWindow->GetFrameURL(m_contextNode); + if (url.IsEmpty()) return; + OpenURL(url, GetCurrentURI()); +} + +void CBrowserView::OnOpenFrameInNewWindow() +{ + CString url = m_pWindow->GetFrameURL(m_contextNode); + if (url.IsEmpty()) return; + OpenURLInNewWindow(url, GetCurrentURI(), FALSE); +} + +void CBrowserView::OnOpenFrameInBackground() +{ + CString url = m_pWindow->GetFrameURL(m_contextNode); + if (url.IsEmpty()) return; + OpenURLInNewWindow(url, GetCurrentURI(), TRUE); +} + +/* ** */ + +#if 0 +void CBrowserView::OnDropFiles( HDROP drop ) +{ + UINT size = DragQueryFile(drop, 0, NULL, 0) + 1; + char *filename = new char[size]; + DragQueryFile(drop, 0, filename, size); + + if (stricmp(filename + (size-5), _T(".url")) == 0){ + char tempUrl[1024]; + ::GetPrivateProfileString(_T("InternetShortcut"), _T("Url"), filename, tempUrl, 1023, filename); + OpenURL(tempUrl); + }else{ + OpenURL(filename); + } + + delete filename; + DragFinish(drop); +} +#endif + +void CBrowserView::AddURLAndPerformDrag(COleDataSource& datasource) +{ + USES_CONVERSION; + + CString currentURI = GetCurrentURI(); + DWORD currentURISize = currentURI.GetLength()+1; + const DWORD extraFileSize = 26; // size of [InternetShortcut]\r\nURL=...\r\n + + HGLOBAL hURL = GlobalAlloc(GHND, currentURISize); + char *url = (char *)GlobalLock(hURL); + strcpy(url, T2CA(currentURI)); + GlobalUnlock(hURL); + + HGLOBAL hFileDescriptor = GlobalAlloc(GHND, sizeof(FILEGROUPDESCRIPTOR)); + FILEGROUPDESCRIPTOR *fgd = (FILEGROUPDESCRIPTOR *)GlobalLock(hFileDescriptor); + fgd->cItems = 1; + fgd->fgd[0].dwFlags = FD_FILESIZE | FD_LINKUI; + fgd->fgd[0].nFileSizeLow = currentURISize+extraFileSize; + + CString title = GetPageTitle(); + _tcsncpy(fgd->fgd[0].cFileName, title, 250); + _tcscat(fgd->fgd[0].cFileName, _T(".url")); + MakeFilename(fgd->fgd[0].cFileName); + GlobalUnlock(hFileDescriptor); + + HGLOBAL hFileContents = GlobalAlloc(GHND, currentURISize+extraFileSize); + char *contents = (char *)GlobalLock(hFileContents); + strcpy(contents, "[InternetShortcut]\r\nURL="); + strcat(contents, url); + strcat(contents, "\r\n"); + GlobalUnlock(hFileContents); + + UINT cfFileDescriptor = ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR); + UINT cfFileContents = ::RegisterClipboardFormat(CFSTR_FILECONTENTS); + UINT cfShellURL = ::RegisterClipboardFormat(CFSTR_SHELLURL); + + FORMATETC fmetc = { cfFileContents, NULL, DVASPECT_CONTENT, 0, TYMED_FILE }; + + // Note: order is important here! + datasource.CacheGlobalData(cfFileContents, hFileContents, &fmetc); + datasource.CacheGlobalData(cfFileDescriptor, hFileDescriptor); + datasource.CacheGlobalData(cfShellURL, hURL); + datasource.CacheGlobalData(CF_TEXT, hURL); + datasource.DoDragDrop(); + + GlobalFree(hURL); + GlobalFree(hFileDescriptor); + GlobalFree(hFileContents); +} + +void CBrowserView::OnDragURL( NMHDR * pNotifyStruct, LRESULT * result ) +{ + USES_CONVERSION; + *result = 0; + + COleDataSource datasource; + AddURLAndPerformDrag(datasource); +} + +// this should probably go in BrowserViewUtils.cpp, but I don't want to add a function prototype :) +BOOL CALLBACK SearchProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static CString *search = NULL; + + if (uMsg == WM_INITDIALOG) { + if (search) { + EndDialog(hwndDlg, false); + return TRUE; + } + search = (CString *)lParam; + ::SetFocus(::GetDlgItem(hwndDlg, IDC_SEARCH_QUERY)); + return false; + } + + else if (uMsg == WM_COMMAND) { + if (LOWORD(wParam) == IDOK){ + TCHAR buffer[256]; + ::GetDlgItemText(hwndDlg, IDC_SEARCH_QUERY, buffer, 255); + *search = buffer; + search = NULL; + EndDialog(hwndDlg, true); + } + else if (LOWORD(wParam) == IDCANCEL) { + search = NULL; + EndDialog(hwndDlg, false); + } + return true; + } + + return false; +} + +void CBrowserView::OnNavSearch() +{ + CString search; + if (DialogBoxParam(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDD_SEARCH_DIALOG), m_hWnd, SearchProc, (LPARAM)&search)) { + search.Replace(_T("+"), _T("%2b")); + search = theApp.preferences.GetString("kmeleon.general.searchEngine", _T("http://www.google.com/search?q=")) + search; + OpenURL(search); + } +} + +void CBrowserView::OnFileClose() +{ + mpBrowserFrame->PostMessage(WM_CLOSE); +} + +void CBrowserView::OnFileSaveFrameAs() +{ + if (!m_pWindow->SaveDocument(TRUE)) + AfxMessageBox(IDS_SAVE_FAILED, MB_OK|MB_ICONERROR); + //SaveLink(m_ctxData.frameUrl); +} + +void CBrowserView::OnViewPageInfo() +{ + CString uri = m_pWindow->GetURI(); + + // Build the page info url + if (uri.Find(_T("https://")) == -1) + uri.Insert(0, _T("about:cache-entry?client=HTTP&sb=1&key=")); + else + uri.Insert(0, _T("about:cache-entry?client=HTTP-memory-only&sb=1&key=")); + + OpenURLInNewWindow(uri); +} + +void CBrowserView::OnViewFrameInfo() +{ + CString viewFrameInfoUrl = m_pWindow->GetFrameURL(m_contextNode); + if (viewFrameInfoUrl.IsEmpty()) return; + + + if (viewFrameInfoUrl.Find(_T("https://")) == -1) + viewFrameInfoUrl = _T("about:cache-entry?client=HTTP&sb=1&key=") + viewFrameInfoUrl; + else + viewFrameInfoUrl = _T("about:cache-entry?client=HTTP-memory-only&sb=1&key=") + viewFrameInfoUrl; + + OpenURLInNewWindow(viewFrameInfoUrl); +} + +void CBrowserView::OnCopyImageLocation() +{ + CString imgSrc; + if (!::GetImageSrc(m_contextNode, imgSrc)) + if (!::GetBackgroundImageSrc(m_contextNode, imgSrc)) + return; + + if (! OpenClipboard()) + return; + + HGLOBAL hClipData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, imgSrc.GetLength() + 1); + if(hClipData) { + char *pszClipData = (char*)::GlobalLock(hClipData); + if(pszClipData) { + + USES_CONVERSION; + strcpy(pszClipData, T2CA(imgSrc)); + + ::GlobalUnlock(hClipData); + + ::EmptyClipboard(); + ::SetClipboardData(CF_TEXT, hClipData); + } + } + + CloseClipboard(); +} + +void CBrowserView::OnCopyImageContent() +{ + m_pWindow->CopyImage(); +} + + +void CBrowserView::OnUpdateFilePrintPreview(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_InPrintPreview); +} + +void CBrowserView::OnKmeleonHome() +{ + OpenURL(KMELEON_HOMEPAGE_URL); +} + +void CBrowserView::OnKmeleonForum() +{ + OpenURL(KMELEON_FORUM_URL); +} + +void CBrowserView::OnKmeleonFAQ() +{ + OpenURL(KMELEON_FAQ_URL); +} + +void CBrowserView::OnKmeleonManual() +{ + OpenURL(KMELEON_MANUAL_URL); +} + +void CBrowserView::OnAboutPlugins() +{ + OpenURLInNewWindow(ABOUT_PLUGINS_URL); +} + +void CBrowserView::OnMouseAction() +{/* + if (m_pWindow->GetURI().IsEmpty()) + return; + + POINT pt; + ::GetCursorPos(&pt); + + HWND hWnd; + hWnd = ::GetFocus(); + + if (hWnd && ::IsChild(m_hWnd, hWnd)) { + + ::SendMessage(hWnd, WM_CONTEXTMENU, (WPARAM) hWnd, MAKELONG(pt.x, pt.y)); + if ( (maccel_key!=WM_MBUTTONDOWN && mCtxMenuImgSrc.Length()>0) || mCtxMenuLinkUrl.Length() > 0) + ::PostMessage(mpBrowserFrame->m_hWnd, WM_COMMAND, (WPARAM)maccel_cmd, (LPARAM)0); + else if (!m_panning && maccel_key==WM_MBUTTONDOWN) { + maccel_pan=1; + StartPanning(TRUE); + } + } + + maccel_cmd = 0; +*/ +} + +void CBrowserView::OnIncreaseFont() +{ + m_pWindow->ChangeTextSize(1); +} + +void CBrowserView::OnDecreaseFont() +{ + m_pWindow->ChangeTextSize(-1); + +} + +void CBrowserView::OnSecurityStateIcon() +{ + ShowSecurityInfo(); +} + +void CBrowserView::OnPopupBlockedIcon() +{ + CString msg; + int x; + // XXXX + msg.Format(IDS_ALLOW_POPUP, ((CBrowserGlue*)m_pBrowserGlue)->mPopupBlockedHost); + if ( (x =::AfxMessageBox(msg, MB_YESNO|MB_ICONQUESTION)) == IDYES) + { + USES_CONVERSION; + CPermissions permissions("popup"); + permissions.set(T2CA(((CBrowserGlue*)m_pBrowserGlue)->mPopupBlockedHost), 1); + } +} + + +void CBrowserView::OnFilePrint() +{ + theApp.preferences.SetBool("print.use_native_print_dialog", TRUE); + theApp.preferences.SetBool("print.show_print_progress", FALSE); + m_bCurrentlyPrinting = TRUE; + m_pWindow->Print(); + m_bCurrentlyPrinting = FALSE; +} + +void CBrowserView::OnFilePrintPreview() +{ + if (m_pWindow->PrintPreview()) + m_InPrintPreview = ! m_InPrintPreview; +} + +void CBrowserView::OnFilePrintSetup() +{ + m_pWindow->PrintSetup(); +} + +void CBrowserView::OnUpdateFilePrint(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(!m_bCurrentlyPrinting); +} + +void CBrowserView::Activate(BOOL bActive) +{ + m_pWindow->SetActive(bActive); +} + +void CBrowserView::Highlight(const wchar_t* string, BOOL matchCase) +{ + CString str; + str.LoadString(IDS_HIGHLIGHTING); + mpBrowserFrame->UpdateStatus(str); + + //ASSERT(string || m_lastHighlightWord.Length()); + + if (string && string[0]) + { + m_pWindow->Highlight(L"Yellow", string, matchCase); + m_lastHighlightWord = string; + } + else + { + m_pWindow->Highlight(NULL, m_lastHighlightWord.get(), matchCase); + m_lastHighlightWord.SetLength(0); + } + + str.LoadString(AFX_IDS_IDLEMESSAGE); + mpBrowserFrame->UpdateStatus(str); +} + +int CBrowserView::GetSiteIcon() { return theApp.favicons.GetIcon(GetBrowserGlue()->mIconURI); } diff --git a/k-meleon/BrowserView.h b/k-meleon/BrowserView.h new file mode 100644 index 00000000..3c51c02e --- /dev/null +++ b/k-meleon/BrowserView.h @@ -0,0 +1,323 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * Rod Spears + * + * ***** END LICENSE BLOCK ***** */ + +// BrowserView.h : interface of the CBrowserView class +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef _BROWSERVIEW_H +#define _BROWSERVIEW_H + +#if _MSC_VER > 1000 + #pragma once +#endif + +#include "IBrowserFrameGlue.h" +#include "BrowserWindow.h" +#include "MozUtils.h" + +///////////////////////////////////////////////////////////////////////////// +// CBrowserView window + +class CBrowserFrame; +class CBrowserGlue; +class CBrowserImpl; +class CFavIconListener; +class CBrowserWrapper; +class CFindDialog; +class CPrintProgressDialog; + +typedef enum +{ + CONTEXT_NONE = 0, + CONTEXT_LINK = 1, + CONTEXT_IMAGE = 2, + CONTEXT_DOCUMENT = 4, + CONTEXT_TEXT = 8, + CONTEXT_INPUT = 16, + CONTEXT_BACKGROUND_IMAGE = 32, + CONTEXT_FRAME = 64, + CONTEXT_SELECTION = 128 +} ContextFlags; + + struct SContextData + { + PRInt32 flags; + nsCOMPtr node; + //nsCOMPtr event; + + BOOL contextMenu; + CString linkUrl; + CString imageUrl; + CString frameUrl; + + SContextData() : node(nsnull), /*event(nsnull),*/ contextMenu(FALSE), flags(0) {} + }; + + +class CBrowserView : public CWnd +{ + +public: + + DECLARE_DYNAMIC(CBrowserView) + + /*** XXXXXXXXXXXXXXXXX */ + + CString GetCurrentURI() { return m_pWindow->GetURI(); } + CString GetPageTitle() { return m_pWindow->GetTitle(); } + + nsCOMPtr m_contextNode; + CString GetContextLinkUrl() { + CString url, title; + ::GetLinkTitleAndHref(m_contextNode, url, title); + return url; + } + + CString GetContextLinkTitle() { + CString url, title; + ::GetLinkTitleAndHref(m_contextNode, url, title); + return title; + } + + CString GetContextImageUrl() { + CString imgSrc; + if (!::GetImageSrc(m_contextNode, imgSrc)) + ::GetBackgroundImageSrc(m_contextNode, imgSrc); + return imgSrc; + } + + CString GetContextFrameUrl() { + return m_pWindow->GetFrameURL(m_contextNode); + } + + //nsCOMPtr m_IconUri; + int GetSiteIcon(); + + void Highlight(const wchar_t* string, BOOL matchCase); + /**************************/ + +protected: + PBROWSERGLUE m_pBrowserGlue; + CBrowserFrame* mpBrowserFrame; + +public: + PBROWSERFRAMEGLUE m_pBrowserFrameGlue; + + CBrowserView(); + virtual ~CBrowserView(); + + CString NicknameLookup(const CString& typedUrl); + //void OpenURL(LPCTSTR url, BOOL sendRef = FALSE, BOOL allowFixup = FALSE); + void OpenURL(LPCTSTR url, LPCTSTR refferer = NULL, BOOL allowFixup = FALSE); + void OpenMultiURL(LPCTSTR urls, BOOL allowFixup = FALSE); + virtual void OpenURLWithCommand(UINT idCommand, LPCTSTR url, LPCTSTR refferer = NULL, BOOL allowFixup = FALSE); + + //CBrowserFrame* OpenURLInNewWindow(LPCTSTR url, BOOL bBackground=FALSE, BOOL sendRef = FALSE, BOOL allowFixup = FALSE); + CBrowserFrame* OpenURLInNewWindow(LPCTSTR url, LPCTSTR refferer = NULL, BOOL bBackground=FALSE, BOOL allowFixup = FALSE); + void LoadHomePage(); + + CBrowserWrapper* GetBrowserWrapper() { ASSERT(this!=NULL); if (this==NULL) return NULL; return m_pWindow; } + CBrowserGlue* GetBrowserGlue() { ASSERT(this!=NULL); return (CBrowserGlue*)m_pBrowserGlue; } + + + BOOL CloneBrowser(CBrowserView* browserView) { return m_pWindow->CloneSHistory(browserView->m_pWindow); } + + // Called by the CBrowserFrame after it creates the view + // Essentially a back pointer to the BrowserFrame + void SetBrowserFrame(CBrowserFrame* pBrowserFrame); + + // Called by the CBrowserFrame after it creates the view + // The view passes this on to the embedded Browser's Impl + // obj + void SetBrowserFrameGlue(PBROWSERFRAMEGLUE pBrowserFrameGlue); + void SetBrowserGlue(PBROWSERGLUE pBrowserGlue); + + + +// nsIDOMWindow *FindDOMWindow(nsIDOMWindow *window, nsIDOMDocument *document); + +/* void SetCtxMenuLinkUrl(nsEmbedString& strLinkUrl); + nsEmbedString mCtxMenuLinkUrl; + + void SetCtxMenuImageSrc(nsEmbedString& strImgSrc); + nsEmbedString mCtxMenuImgSrc; + + void SetCurrentFrameURL(nsEmbedString& strcCurrentFrameURL); + nsEmbedString mCtxMenuCurrentFrameURL;*/ + + void Activate(BOOL bActive); + + //BOOL OpenViewSourceWindow(const PRUnichar* pUrl); + BOOL OpenViewSourceWindow(BOOL frame = FALSE); + BOOL IsViewSourceUrl(CString& strUrl); + BOOL SaveLink(LPCTSTR url); + +/* enum _securityState { + SECURITY_STATE_SECURE, + SECURITY_STATE_INSECURE, + SECURITY_STATE_BROKEN + };*/ + + void ShowSecurityInfo(); + void StartPanning(BOOL accel); + void StopPanning(); + + //afx_msg LRESULT RefreshToolBarItem(WPARAM ItemID, LPARAM unused); + + TCHAR * GetTempFile(); + void DeleteTempFiles(); + + // inline void ClearFindDialog() { m_pFindDlg = NULL; } + void AddURLAndPerformDrag(COleDataSource& datasource); + +protected: + void _OnNavReload(BOOL force = FALSE); + + virtual void PostNcDestroy() { + delete this; + } + + + CBrowserWrapper* m_pWindow; + nsEmbedString m_lastHighlightWord; +// BOOL m_refreshBackButton; +// BOOL m_refreshForwardButton; + BOOL m_InPrintPreview; + TCHAR **m_tempFileList; + int m_tempFileCount; + + BOOL maccel_pan; + BOOL m_panning; + BOOL m_panningQuick; + CPoint m_panningPoint; + + + + // CFindDialog* m_pFindDlg; + // CPrintProgressDialog* m_pPrintProgressDlg; + + // Indicates whether we are currently printing + BOOL m_bCurrentlyPrinting; + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CBrowserView) +protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL PreTranslateMessage(MSG* pMsg); + //}}AFX_VIRTUAL + // Generated message map functions + //{{AFX_MSG(CBrowserView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnSize( UINT, int, int ); + afx_msg void OnTimer(UINT nIDEvent); + afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message); + afx_msg void OnUrlSelectedInUrlBar(); + afx_msg void OnUrlSelectedInUrlBarOk(); + afx_msg void OnUrlSelectedInUrlBarCancel(); + afx_msg void OnUrlBarDropDown(); + afx_msg void OnNewUrlEnteredInUrlBar(); + afx_msg void OnUrlKillFocus(); + afx_msg void OnUrlSetFocus(); + afx_msg void OnUrlEditChange(); + afx_msg void OnFileOpen(); + afx_msg void OnFileSaveAs(); + afx_msg void OnFileSaveFrameAs(); + afx_msg void OnFileClose(); + afx_msg void OnViewSource(); + afx_msg void OnViewInfo(); + afx_msg void OnNavBack(); + afx_msg void OnNavForward(); + afx_msg void OnNavSearch(); + afx_msg void OnNavHome(); + afx_msg void OnNavReload(); + afx_msg void OnNavForceReload(); + afx_msg void OnNavStop(); + afx_msg void OnCut(); + afx_msg void OnCopy(); + afx_msg void OnPaste(); + afx_msg void OnUndo(); + afx_msg void OnSelectAll(); + afx_msg void OnSelectNone(); + afx_msg void OnCopyLinkLocation(); + afx_msg void OnCopyImageLocation(); + afx_msg void OnCopyImageContent(); + afx_msg void OnOpenLink(); + afx_msg void OnOpenLinkInNewWindow(); + afx_msg void OnOpenLinkInBackground(); + afx_msg void OnViewImageInNewWindow(); + afx_msg void OnSaveLinkAs(); + afx_msg void OnSaveImageAs(); + afx_msg void OnViewPageInfo(); + afx_msg void OnViewFrameInfo(); + //afx_msg void OnShowFindDlg(); + afx_msg void OnFilePrint(); + afx_msg void OnFilePrintPreview(); + afx_msg void OnFilePrintSetup(); + afx_msg void OnUpdateFilePrint(CCmdUI* pCmdUI); + afx_msg void OnUpdateFilePrintPreview(CCmdUI* pCmdUI); + //afx_msg LRESULT OnFindMsg(WPARAM wParam, LPARAM lParam); + afx_msg void OnKmeleonHome(); + afx_msg void OnKmeleonForum(); + afx_msg void OnKmeleonFAQ(); + afx_msg void OnKmeleonManual(); + afx_msg void OnAboutPlugins(); + afx_msg void OnUpdateNavBack(CCmdUI* pCmdUI); + afx_msg void OnUpdateNavForward(CCmdUI* pCmdUI); + afx_msg void OnUpdateNavStop(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI); + afx_msg void OnUpdateCut(CCmdUI* pCmdUI); + afx_msg void OnUpdateCopy(CCmdUI* pCmdUI); + afx_msg void OnUpdatePaste(CCmdUI* pCmdUI); + afx_msg void OnUpdateUndo(CCmdUI* pCmdUI); + afx_msg void OnUpdateViewImage(CCmdUI* pCmdUI); + afx_msg void OnViewFrameSource(); + afx_msg void OnOpenFrame(); + afx_msg void OnOpenFrameInBackground(); + afx_msg void OnOpenFrameInNewWindow(); + afx_msg void OnMouseAction(); + afx_msg void OnSecurityStateIcon(); + afx_msg void OnPopupBlockedIcon(); + afx_msg void OnIncreaseFont(); + afx_msg void OnDecreaseFont(); + afx_msg void OnBeginEditURL( NMHDR * pNotifyStruct, LRESULT * result ); + afx_msg void OnEndEditURL( NMHDR * pNotifyStruct, LRESULT * result ); + afx_msg void OnDragURL( NMHDR * pNotifyStruct, LRESULT * result ); + //afx_msg void OnDropFiles( HDROP ); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +#endif //_BROWSERVIEW_H diff --git a/k-meleon/BrowserViewFind.cpp b/k-meleon/BrowserViewFind.cpp new file mode 100644 index 00000000..ff66b079 --- /dev/null +++ b/k-meleon/BrowserViewFind.cpp @@ -0,0 +1,220 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* + This code handles the Findbar +*/ + +#include "stdafx.h" + +#include "MfcEmbed.h" +extern CMfcEmbedApp theApp; + +#include "Dialogs.h" +#include "BrowserFrm.h" +#include "BrowserView.h" +#include "BrowserWindow.h" + +// A new handler for WM_FINDMSG, if a plugin want to use it. +// At first I wanted to put the findbar in a plugin but... +// wParam (char*) Text to search for in UTF8 +// lParam flags + +#define FM_WRAPAROUND 0x1 +#define FM_MATCHCASE 0x2 +#define FM_SEARCHBACKWARD 0x4 + +/*LRESULT CBrowserView::OnFindMsg(WPARAM wParam, LPARAM lParam) +{ + nsCOMPtr finder(do_GetInterface(mWebBrowser)); + if(!finder) + return 0; + + nsEmbedString searchStrUTF16; + NS_CStringToUTF16(nsEmbedCString((char*)wParam), NS_CSTRING_ENCODING_UTF8, searchStrUTF16); + + finder->SetFindBackwards( lParam & FM_SEARCHBACKWARD ? PR_TRUE : PR_FALSE); + finder->SetMatchCase( lParam & FM_MATCHCASE ? PR_TRUE : PR_FALSE); + finder->SetWrapFind( lParam & FM_WRAPAROUND ? PR_TRUE : PR_FALSE); + finder->SetSearchString(searchStrUTF16.get()); + + PRBool didFind; + finder->FindNext(&didFind); + + return (didFind == PR_TRUE ? 1 : 0); +}*/ + +void CBrowserView::OnFindNext() { + + if(!mpBrowserFrame->m_wndFindBar) { + WCHAR* searchString = m_pWindow->GetSearchString(); + if (!searchString || !*searchString) { + mpBrowserFrame->OnShowFindBar(); + mpBrowserFrame->m_wndFindBar->OnFound(); + } + else { + BOOL didFind = m_pWindow->FindNext(FALSE); + if (!didFind) { + mpBrowserFrame->OnShowFindBar(); + mpBrowserFrame->m_wndFindBar->OnNotFound(); + } + } + free(searchString); + } + else + { + const WCHAR* searchString = mpBrowserFrame->m_wndFindBar->GetUFindString(); + if (searchString) { +#ifndef FINDBAR_USE_TYPEAHEAD + BOOL didFind = m_pWindow->Find(searchString, mpBrowserFrame->m_wndFindBar->StartSel()); +#else + BOOL didFind = m_pWindow->Find(searchString); +#endif + if (*searchString && !didFind) { + mpBrowserFrame->m_wndFindBar->OnNotFound(); + } + else { + mpBrowserFrame->m_wndFindBar->OnFound(); + } + } + } +/* + + nsCOMPtr finder(do_GetInterface(mWebBrowser)); + if(!finder) return; + USES_CONVERSION; + + + if(mpBrowserFrame->m_wndFindBar) + { + BOOL didFind; + WCHAR* searchString = mpBrowserFrame->m_wndFindBar->GetUFindString(); + + if (searchString) { +#ifndef FINDBAR_USE_TYPEAHEAD + didFind = m_Finder->Find(searchString, mpBrowserFrame->m_wndFindBar->StartSel()); +#else + didFind = m_Finder->Find(searchString); +#endif + if (didfind) { + + + if(mpBrowserFrame->m_wndFindBar) + { + finder->SetSearchString(mpBrowserFrame->m_wndFindBar->GetUFindString()); + //finder->SetMatchCase(mpBrowserFrame->m_wndFindBar->MatchCase() ? PR_TRUE : PR_FALSE); + //finder->SetWrapFind(mpBrowserFrame->m_wndFindBar->WrapAround() ? PR_TRUE : PR_FALSE); + + // HACK because not use typeahead + // The problem with the autosearch feature is that + // webbrowserfind start to search at the end of the + // current selection. But with autosearch it should + // start at the beginning. So I collapse the selection. + if (mpBrowserFrame->m_wndFindBar->StartSel()) + { + nsCOMPtr dom(do_GetInterface(mWebBrowser)); + if (dom) + { + // Have to look if we have frames. It's a little violent + // currently. The observer is also passing the root and + // not the frame so it's useless. + + CollapseSelToStartInFrame(dom); + } + } + } +#endif + PRUnichar *stringBuf = nsnull; + finder->GetSearchString(&stringBuf); + + if (stringBuf[0]) + { + PRBool didFind; + finder->FindNext(&didFind); + if (!didFind) + { + if (!mpBrowserFrame->m_wndFindBar) + mpBrowserFrame->OnShowFindBar(); + mpBrowserFrame->m_wndFindBar->OnNotFound(); + } + else + if (mpBrowserFrame->m_wndFindBar) + mpBrowserFrame->m_wndFindBar->OnFound(); + } + else { + mpBrowserFrame->OnShowFindBar(); + mpBrowserFrame->m_wndFindBar->OnFound(); + } + + nsMemory::Free(stringBuf); + */ +} + +void CBrowserView::OnFindPrev() +{ + BOOL didFind = m_pWindow->FindNext(TRUE); + if (!didFind) { + mpBrowserFrame->OnShowFindBar(); + mpBrowserFrame->m_wndFindBar->OnNotFound(); + } + else + mpBrowserFrame->m_wndFindBar->OnFound(); + /* + nsCOMPtr finder(do_GetInterface(mWebBrowser)); + if(!finder) return; + + finder->SetFindBackwards(PR_TRUE); + OnFindNext(); + finder->SetFindBackwards(PR_FALSE);*/ +} + + + +void CBrowserView::OnMatchCase() +{ + if (theApp.preferences.bFindHighlight) + Highlight(FALSE); + + if (!mpBrowserFrame->m_wndFindBar) + theApp.preferences.bFindMatchCase = !theApp.preferences.bFindMatchCase; + else + theApp.preferences.bFindMatchCase = mpBrowserFrame->m_wndFindBar->MatchCase(); + + if (theApp.preferences.bFindHighlight) + Highlight(TRUE); + + m_pWindow->SetMatchCase(theApp.preferences.bFindMatchCase ? PR_TRUE : PR_FALSE); +} + +void CBrowserView::OnWrapAround() +{ + if (!mpBrowserFrame->m_wndFindBar) + theApp.preferences.bFindWrapAround = !theApp.preferences.bFindWrapAround; + else + theApp.preferences.bFindWrapAround = mpBrowserFrame->m_wndFindBar->WrapAround(); + + m_pWindow->SetWrapAround(theApp.preferences.bFindWrapAround ? PR_TRUE : PR_FALSE); +} + +void CBrowserView::OnHighlight() +{ + theApp.preferences.bFindHighlight = mpBrowserFrame->m_wndFindBar->Highlight(); + Highlight(FALSE); + if (theApp.preferences.bFindHighlight) + Highlight(TRUE); +} diff --git a/k-meleon/BrowserViewPanning.cpp b/k-meleon/BrowserViewPanning.cpp new file mode 100644 index 00000000..4b50f842 --- /dev/null +++ b/k-meleon/BrowserViewPanning.cpp @@ -0,0 +1,216 @@ +/* +* Copyright (C) 2000 Christophe Thibault, Brian Harris, Jeff Doozan +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" + +#include "MfcEmbed.h" +extern CMfcEmbedApp theApp; + +#include "BrowserView.h" +#include "BrowserFrm.h" + +#include "nsIDOMWindowInternal.h" +#include "nsIDOMWindowCollection.h" +#include "nsIDOMEventTarget.h" +/* +** Middle button panning shit +*/ +int CBrowserView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) +{ + // Give the focus to the browser if it don't have it. + if (!::IsChild(m_hWnd, ::GetFocus())) { + m_pWindow->SetActive(TRUE); + mpBrowserFrame->m_wndLastFocused = NULL; + } + +/* + int id; + id = theApp.accel.CheckMouse(message); + + if (message==WM_LBUTTONDOWN || message==WM_RBUTTONDOWN) + mpBrowserFrame->m_wndUrlBar.EditChanged(FALSE); + + if (m_panning) { + if (message==WM_LBUTTONDOWN || + message==WM_RBUTTONDOWN || + message==WM_MBUTTONDOWN) { + StopPanning(); + return MA_ACTIVATE; + } + } + else { + if (id) { + maccel_cmd = id; + maccel_key = message; + PostMessage(WM_COMMAND, (WPARAM)ID_MOUSE_ACTION, 0); + return MA_ACTIVATE; + } + else { + if (message==WM_MBUTTONDOWN) { + StartPanning(); + return MA_ACTIVATE; + } + } + } +*/ + return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); +} +/* +nsIDOMWindow *CBrowserView::FindDOMWindow(nsIDOMWindow *window, nsIDOMDocument *document) { + nsCOMPtr windoc; + window->GetDocument(getter_AddRefs(windoc)); + if (windoc == document) + return window; + + nsCOMPtr frameset; + window->GetFrames(getter_AddRefs(frameset)); + + if (frameset) { + PRUint32 length; + frameset->GetLength(&length); + + if (length) { + for (unsigned i=0; i tmpwin; + frameset->Item(i, getter_AddRefs(tmpwin)); + tmpwin = FindDOMWindow(tmpwin, document); + if (tmpwin) + return tmpwin; + } + } + } + + return NULL; +} +*/ +void CBrowserView::OnTimer(UINT nIDEvent) +{ + switch(nIDEvent){ + case 0x1: + if(m_panning) { + //if (!s) return; + + POINT p; + GetCursorPos(&p); + + //int scroll_x,scroll_y; + + //s->GetScrollX(&scroll_x); + //s->GetScrollY(&scroll_y); + + int dx = (p.x-m_panningPoint.x)/10; + int dy = (p.y-m_panningPoint.y)/10; + m_pWindow->ScrollBy(dx, dy); +/* + if(dy!=0) { + if(dy>0) scroll_y += dy*dy; + else scroll_y -= dy*dy; + s->ScrollTo(scroll_x,scroll_y); + } + + if(dx!=0) { + if(dx>0) scroll_x += dx*dx; + else scroll_x -= dx*dx; + s->ScrollTo(scroll_x,scroll_y); + }*/ + /* cursor flickering : https://bugzilla.mozilla.org/show_bug.cgi?id=316352 */ + int cursor; + if (dx < 0) { + if (dy < 0) cursor = IDC_PAN_UPLEFT; + else if (dy > 0) cursor = IDC_PAN_DOWNLEFT; + else cursor = IDC_PAN_LEFT; + } + else if (dx > 0) { + if (dy < 0) cursor = IDC_PAN_UPRIGHT; + else if (dy > 0) cursor = IDC_PAN_DOWNRIGHT; + else cursor = IDC_PAN_RIGHT; + } + else { + if (dy < 0) cursor = IDC_PAN_UP; + else if (dy > 0) cursor = IDC_PAN_DOWN; + else cursor = IDC_PAN; + } + + HCURSOR c=LoadCursor(theApp.m_hInstance,MAKEINTRESOURCE(cursor)); + SetCursor(c); + } + return; + } + + CWnd::OnTimer(nIDEvent); +} + +void CBrowserView::StartPanning(BOOL accel) +{ + if (accel) maccel_pan = 1; + + m_panning = 1; + m_panningQuick = theApp.preferences.GetBool("kmeleon.general.quickAutoscroll", FALSE); + GetCursorPos(&m_panningPoint); +/* + nsCOMPtr browser = m_pWindow->GetWebBrowser(); + browser->GetContentDOMWindow(getter_AddRefs(s)); + if(!s) return; + + nsCOMPtr frameset; + s->GetFrames(getter_AddRefs(frameset)); + + if (frameset) { + PRUint32 length; + frameset->GetLength(&length); + + if (length) { + // get the DOMNode at the point + // nsCOMPtr aNode; + // GetNodeAtPoint(m_panningPoint.x, m_panningPoint.y, TRUE); + if (m_contextNode) { + nsCOMPtr ownerdoc; + m_contextNode->GetOwnerDocument(getter_AddRefs(ownerdoc)); + + if (ownerdoc) + s = FindDOMWindow(s, ownerdoc); + } + + if(!s) return; + } + } +*/ + SetCapture(); + SetTimer(0x1,20,NULL); + //SetFocus(); +} + +void CBrowserView::StopPanning() +{ + SetCursor(LoadCursor(NULL,IDC_ARROW)); // return to the normal cursor + ReleaseCapture(); + KillTimer(0x1); + m_panning = 0; + maccel_pan = 0; +} + +BOOL CBrowserView::PreTranslateMessage(MSG* pMsg) +{/* + if(m_panning && (pMsg->message==WM_SETCURSOR || pMsg->message==WM_MOUSEMOVE)) + return 1; +*/ + if(m_panning && (pMsg->message==WM_LBUTTONDOWN || (pMsg->message==WM_MBUTTONDOWN && maccel_pan) || (pMsg->message==WM_MBUTTONUP && m_panningQuick) || pMsg->message==WM_RBUTTONDOWN || pMsg->message==WM_MOUSEWHEEL)) + StopPanning(); + + return CWnd::PreTranslateMessage(pMsg); +} diff --git a/k-meleon/BrowserViewUtils.cpp b/k-meleon/BrowserViewUtils.cpp new file mode 100644 index 00000000..e4f9a84a --- /dev/null +++ b/k-meleon/BrowserViewUtils.cpp @@ -0,0 +1,535 @@ +/* +* Copyright (C) 2000 Christophe Thibault, Brian Harris, Jeff Doozan +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* + These are little utils and stuff for the CBrowserView + it's mainly here to get it out of BrowserView.cpp which should + theoretically just contain overridden functions and message handlers +*/ + +#include "stdafx.h" +#include +#include "Utils.h" + +#include "MfcEmbed.h" +extern CMfcEmbedApp theApp; + +#include "BrowserFrm.h" +#include "BrowserView.h" +#include "MozUtils.h" +#include "nsIWebPageDescriptor.h" +#include "nsCWebBrowserPersist.h" +#include "UnknownContentTypeHandler.h" + +// Remove when it stops sucking. +//#define MOZILLA_MIMETYPE_SUCKS +#ifdef MOZILLA_MIMETYPE_SUCKS +extern BOOL GetFromTypeAndExtension(LPCTSTR contentType, LPCTSTR ext, CString& resultExt, CString& desc); +#endif + +extern int ParsePluginCommand(char *pszCommand, char** plugin, char **parameter); + +BOOL CBrowserView::IsViewSourceUrl(CString& strUrl) +{ + return (strUrl.Find(_T("view-source:"), 0) != -1) ? TRUE : FALSE; +} + +void OpenFileExternal(const char* uri, LPCTSTR file, nsresult status, void* param) +{ + + LPTSTR viewer = (TCHAR*)param; + if (NS_SUCCEEDED(status)) + { + TCHAR *command = new TCHAR[_tcsclen(viewer) + _tcsclen(file) +4]; + + _tcscpy(command, viewer); + _tcscat(command, _T(" \"")); //append " filename" to the viewer command + _tcscat(command, file); + _tcscat(command, _T("\"")); + + STARTUPINFO si = { 0 }; + PROCESS_INFORMATION pi; + si.cb = sizeof STARTUPINFO; + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOW; + + CreateProcess(0,command,0,0,0,0,0,0,&si,&pi); // launch external viewer + + delete command; + } + free(viewer); + // Have to show an error message +} + +BOOL CBrowserView::OpenViewSourceWindow(BOOL frame) +{ + nsCOMPtr browser; + m_pWindow->GetWebBrowser(getter_AddRefs(browser)); + NS_ENSURE_TRUE(browser, FALSE); + + nsresult rv; + CString url = !frame ? m_pWindow->GetURI(TRUE) : m_pWindow->GetFrameURL(); + + // Use external viewer + if (theApp.preferences.bSourceUseExternalCommand && + theApp.preferences.sourceCommand) { + + CString tempfile; + tempfile = GetTempFile(); + + // We want to show the source of a local file. Just open this file. + if (_tcsncmp(url, _T("file:///"), 8) == 0) + { + url.Replace(_T('/'), _T('\\')); + url.ReleaseBuffer(url.ReverseFind('#')); // Truncate + url.ReleaseBuffer(url.ReverseFind('?')); // Truncate + OpenFileExternal("", url.Mid(8), NS_OK, + _tcsdup((CString)theApp.preferences.sourceCommand)); + return TRUE; + } + + nsCOMPtr persist(do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID)); + NS_ENSURE_TRUE(persist, FALSE); + + nsCOMPtr webNav = do_QueryInterface(browser, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr referrer; + webNav->GetReferringURI(getter_AddRefs(referrer)); + + nsCOMPtr srcURI; + rv = NewURI(getter_AddRefs(srcURI), CStringToNSString(url)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr cacheDescriptor = m_pWindow->GetPageDescriptor(frame); + + nsCOMPtr file; +#ifdef _UNICODE + rv = NS_NewLocalFile(nsDependentString(tempfile.GetBuffer(0)), TRUE, getter_AddRefs(file)); +#else + rv = NS_NewNativeLocalFile(nsDependentCString(tempfile.GetBuffer(0)), TRUE, getter_AddRefs(file)); +#endif + + CProgressDialog *progress = new CProgressDialog(FALSE); + progress->SetCallBack((ProgressDialogCallback)OpenFileExternal, + _tcsdup(theApp.preferences.sourceCommand)); + progress->InitPersist(srcURI, file, persist, FALSE); + // progress->InitViewer(persist, theApp.preferences.sourceCommand.GetBuffer(0), tempfile.GetBuffer(0)); + persist->SetPersistFlags( + nsIWebBrowserPersist::PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION| + nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES); + rv = persist->SaveURI(srcURI, cacheDescriptor, referrer, nsnull, nsnull, file); + if (NS_FAILED(rv)) { + persist->SetProgressListener(nsnull); + return FALSE; + } + + return TRUE; + } + + // use the internal viewer + + // Create a new browser frame in which we'll show the document source + // Note that we're getting rid of the toolbars etc. by specifying + // the appropriate chromeFlags + PRUint32 chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_BORDERS | + nsIWebBrowserChrome::CHROME_TITLEBAR | + nsIWebBrowserChrome::CHROME_WINDOW_RESIZE | + nsIWebBrowserChrome::CHROME_WINDOW_CLOSE | + nsIWebBrowserChrome::CHROME_WINDOW_MIN | + nsIWebBrowserChrome::CHROME_SCROLLBARS ; + + RECT screen; + SystemParametersInfo(SPI_GETWORKAREA, NULL, &screen, 0); + + int screenWidth = screen.right - screen.left; + int screenHeight = screen.bottom - screen.top; + + int x = screen.left + screenWidth / 20; + int y = screen.top + screenHeight / 20; + int w = 15*screenWidth / 20; + int h = 18*screenHeight/20; + + nsCOMPtr cacheDescriptor = m_pWindow->GetPageDescriptor(frame); + + CBrowserFrame* pFrm = theApp.CreateNewBrowserFrame(chromeFlags); + if(!pFrm) return FALSE; + pFrm->SetWindowPos(NULL, x, y, w, h, SWP_NOZORDER|SWP_SHOWWINDOW); + + // Finally, load this URI into the newly created frame + if (cacheDescriptor) { + pFrm->GetActiveView()->GetBrowserWrapper()->GetWebBrowser(getter_AddRefs(browser)); + NS_ENSURE_TRUE(browser, FALSE); + + nsCOMPtr docShell = do_GetInterface(browser); + NS_ENSURE_TRUE(docShell, FALSE); + + nsCOMPtr wpd = do_QueryInterface(docShell); + NS_ENSURE_TRUE(wpd, FALSE); + wpd->LoadPage(cacheDescriptor, nsIWebPageDescriptor::DISPLAY_AS_SOURCE); + } + else { + url = _T("view-source://") + url; + pFrm->OpenURL(url); + } + + pFrm->BringWindowToTop(); + + return TRUE; +} + +void CBrowserView::OpenURLWithCommand(UINT idCommand, LPCTSTR url, LPCTSTR refferer, BOOL allowFixup) +{ + switch (idCommand) + { + case ID_OPEN_LINK: + OpenURL(url, refferer, allowFixup); + break; + case ID_OPEN_LINK_IN_BACKGROUND: + OpenURLInNewWindow(url, refferer, TRUE, allowFixup); + break; + case ID_OPEN_LINK_IN_NEW_WINDOW: + OpenURLInNewWindow(url, refferer, FALSE, allowFixup); + break; + default: + OpenURL(url, refferer, allowFixup); + return; + } +} + +void CBrowserView::OpenMultiURL(LPCTSTR urls, BOOL allowFixup) +{ + char szOpenURLcmd[80]; + int idOpen = 0, idOpenX = 0; + const char* pref; + + if (_tcschr(urls, '\t')) + pref = "kmeleon.general.opengroup"; + else + pref = "kmeleon.general.openurl"; + + theApp.preferences.GetString(pref, szOpenURLcmd, ""); + + if (*szOpenURLcmd) + { + char *altCommand = strchr(szOpenURLcmd, '|'); + if (altCommand) + *altCommand = 0; + + idOpen = theApp.GetID(szOpenURLcmd); + + if (!idOpen) { + char *plugin = NULL, *parameter = NULL; + if (ParsePluginCommand(szOpenURLcmd, &plugin, ¶meter)) { + USES_CONVERSION; + if (theApp.plugins.SendMessage(plugin, "* kmeleon.exe", parameter, (long)T2CA(urls), 0)) + return; + else + theApp.plugins.SendMessage(plugin, "* kmeleon.exe", "DoAccel", (long) parameter, (long)&idOpen); + } + } + + if (altCommand) + idOpenX = theApp.GetID(altCommand+1); + } + + TCHAR* p = (TCHAR*)urls; + while (p) { + TCHAR *q = _tcschr(p, '\t'); + if (q) *q = 0; + if (!*p) break; + OpenURLWithCommand(idOpen, p, GetCurrentURI(), allowFixup); + + idOpen = idOpenX==0 ? idOpen : idOpenX; + + if (q) + p = q+1; + else + break; + } +} + +CString CBrowserView::NicknameLookup(const CString& typedUrl) +{ + CString retUrl = typedUrl; + retUrl.TrimRight(); + retUrl.TrimLeft(); + int word = retUrl.Find(' '); + + if (word!=-1) { + retUrl.GetBuffer(0); + retUrl.ReleaseBuffer(word); // Truncate + } + + char *nickUrl = NULL; + USES_CONVERSION; + theApp.plugins.SendMessage("*", "* FindNick", "FindNick", (long)T2CA(retUrl), (long)&nickUrl); + + if (!nickUrl) return typedUrl; + + retUrl = A2T(nickUrl); + free(nickUrl); + + if (word!=-1) + if (!retUrl.Replace(_T("%s"), typedUrl.Mid(word+1))) + return typedUrl; // See Bug #849 + + return retUrl; +} +/* +LRESULT CBrowserView::RefreshToolBarItem(WPARAM ItemID, LPARAM unused) +{ + switch (ItemID) { + case ID_NAV_BACK: + m_refreshBackButton = TRUE; + break; + case ID_NAV_FORWARD: + m_refreshForwardButton = TRUE; + break; + } + + return 0; +} + +void CBrowserView::OpenURL(const char* pUrl, nsIURI *refURI, BOOL allowFixup) +{ + nsEmbedString str; + NS_CStringToUTF16(nsEmbedCString(pUrl), NS_CSTRING_ENCODING_ASCII, str); + OpenURL(str.get(), refURI, allowFixup); +}*/ + +void CBrowserView::OpenURL(LPCTSTR url, LPCTSTR referrer, BOOL allowFixup) +{ + if (!url) return; + //mpBrowserFrame->UpdateLocation(url, TRUE); + + if ( GetActiveWindow() == mpBrowserFrame && + !::IsChild(m_hWnd, ::GetFocus())) + m_pWindow->SetActive(TRUE); + + ((CBrowserGlue*)m_pBrowserGlue)->mPendingLocation = url; // XXXX + if (!m_pWindow->LoadURL(url, referrer, allowFixup) && m_pBrowserGlue) + ((CBrowserGlue*)m_pBrowserGlue)->mPendingLocation = _T(""); + +} +/* +void CBrowserView::OpenURL(LPCTSTR url, BOOL sendRef, BOOL allowFixup) +{ + mpBrowserFrame->UpdateLocation(url, TRUE); + + if ( GetActiveWindow() == mpBrowserFrame && + !::IsChild(m_hWnd, ::GetFocus())) + m_pWindow->SetActive(TRUE); + + m_pWindow->LoadURL(url, sendRef, allowFixup); +}*/ + +/* +CBrowserFrame* CBrowserView::OpenURLInNewWindow(const char* pUrl, BOOL bBackground, nsIURI *refURI, BOOL allowFixup) +{ + nsEmbedString str; + NS_CStringToUTF16(nsEmbedCString(pUrl), NS_CSTRING_ENCODING_UTF8, str); + return OpenURLInNewWindow(str.get(), bBackground, refURI, allowFixup); +}*/ + +CBrowserFrame* CBrowserView::OpenURLInNewWindow(LPCTSTR pUrl, LPCTSTR referrer, BOOL bBackground, BOOL allowFixup) +{ + if ( !((CBrowserGlue*)m_pBrowserGlue)->mLoading && + GetCurrentURI() == "about:blank" ) { + OpenURL(pUrl, referrer, allowFixup); + return mpBrowserFrame; + } + + return theApp.CreateNewBrowserFrameWithUrl(pUrl, referrer, bBackground); +} +/* +CBrowserFrame* CBrowserView::OpenURLInNewWindow(LPCTSTR pUrl, BOOL bBackground, BOOL sendRef, BOOL allowFixup) +{ + const TCHAR* ext = _tcschr(pUrl, L'.'); + CBrowserFrame* pFrm; + PRUint32 chromeFlags; + + CWnd* lastBgWindow = (CWnd*)theApp.m_FrameWndLst.GetHead(); + + if ( !bBackground && ext && + (_tcsncmp(pUrl, _T("chrome:"), 7) == 0) && + (_tcsstr(ext, _T(".xul")) == ext) ) + chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_RESIZE | + nsIWebBrowserChrome::CHROME_WINDOW_CLOSE | + nsIWebBrowserChrome::CHROME_TITLEBAR | + nsIWebBrowserChrome::CHROME_OPENAS_CHROME| + nsIWebBrowserChrome::CHROME_WINDOW_MIN; + else + chromeFlags = nsIWebBrowserChrome::CHROME_ALL; + + // create hidden window + pFrm = CreateNewBrowserFrame(chromeFlags, -1, -1, -1, -1, PR_FALSE); + + if(!pFrm) + return NULL; + + // Load the URL into it... + + // Note that OpenURL() is overloaded - one takes a "char *" + // and the other a "PRUniChar *". We're using the "PRUnichar *" + // version here + + pFrm->OpenURL(pUrl, m_pWindow->GetURI(), allowFixup); + + if (bBackground) + pFrm->SetWindowPos(lastBgWindow, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW); + else if (!(chromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) + { + pFrm->ShowWindow(SW_SHOW); + pFrm->SetFocus(); + } + + return pFrm; +}*/ + +void CBrowserView::LoadHomePage() +{ + if (theApp.preferences.bStartHome) + OnNavHome(); + else + OpenURL(_T("about:blank")); +} + +// Called from the busy state related methods in the +// BrowserFrameGlue object +// +// When aBusy is TRUE it means that browser is busy loading a URL +// When aBusy is FALSE, it's done loading +// We use this to update our STOP tool bar button +// +// We basically note this state into a member variable +// The actual toolbar state will be updated in response to the +// ON_UPDATE_COMMAND_UI method - OnUpdateNavStop() being called +// + +void CBrowserView::ShowSecurityInfo() +{ + CString title, msg; + title.LoadString(IDS_SECURITY_INFORMATION); + if (!m_pWindow->ShowCertificate()) { + msg.LoadString(IDS_NOT_SECURE); + ::MessageBox(m_hWnd, msg, title, MB_OK); + } +/* + if(m_pBrowserGlue->m_SecurityState == SECURITY_STATE_INSECURE) { + msg.LoadString(IDS_NOT_SECURE); + ::MessageBox(m_hWnd, msg, title, MB_OK); + } else { + if (!m_pWindow->ShowCertificate()) { + msg.LoadString(IDS_SECURITY_FAILED); + ::MessageBox(GetParentFrame()->m_hWnd, msg, title, MB_OK); + } + }*/ +} + +TCHAR * CBrowserView::GetTempFile() +{ + m_tempFileCount++; + + TCHAR ** newFileList = new TCHAR*[m_tempFileCount]; // create new index + + memcpy(newFileList, m_tempFileList, ((m_tempFileCount-1)*sizeof(TCHAR**)) ); // copy old index + + if (m_tempFileCount>1) delete m_tempFileList; // delete old index + m_tempFileList = newFileList; + + TCHAR *newFile = new TCHAR[MAX_PATH]; + + TCHAR temppath[MAX_PATH]; + GetTempPath(MAX_PATH, temppath); + GetTempFileName(temppath, _T("kme"), 0, newFile); // create tempfile name + + m_tempFileList[m_tempFileCount-1] = newFile; + + return newFile; +} + +void CBrowserView::DeleteTempFiles() +{ + for (int x=0;x 0) delete m_tempFileList; +} + +/* + + The GetNodeAtPoint function is a really gross hack. + Essentially, Mozilla doesn't expose any way for us to + get information about the DOM given a specific point. + As a workaround, we simply tell mozilla to post a context + menu, and then trap it right before the menu pops up. + + This becomes even worse when we find that mozilla ignores + the coordinates specified in the window message and, instead, + calls GetMessagePos, which means that we need to call + SetCursorPos() so that windows will attach the coordinates we + want to the message we send to mozilla. + + Even worse, windows doesn't seem to immediately process the + SetCursorPos() function, so we muck about with the message + queue for a bit to let windows figure out that the cursor + has changed positions. + + The bPrepareMenu flag determines whether or not the global + variables that get set in preparation for use by identifiers + like ID_OPEN_LINK_IN_NEW_WINDOW + +*/ + +/*nsIDOMNode *CBrowserView::GetNodeAtPoint(int x, int y, BOOL bPrepareMenu) +{ + // Make sure a page is actually being displayed + if (m_pWindow->GetURI().IsEmpty()) + return NULL; + + HWND hWnd = ::GetFocus(); + if (!::IsChild(m_hWnd, hWnd)) { + SetFocus(); + hWnd = ::GetFocus(); + } + + POINT pt; + ::GetCursorPos(&pt); + ::ShowCursor(FALSE); + ::SetCursorPos(x, y); + + // swing throught the message pump a bit, so that windows can process + // the cursor movement (important, because mozilla uses GetMessagePos to + // determine where the mouse was clicked) + MSG msg; + while (::PeekMessage(&msg,0,0,0,PM_NOREMOVE)) { + if (!theApp.PumpMessage()) { + ::PostQuitMessage(0); break; + } + } + + m_iGetNodeHack = bPrepareMenu ? 2 : 1; + + ::SendMessage(hWnd, WM_CONTEXTMENU, (WPARAM) hWnd, MAKELONG(x, y)); + ::SetCursorPos(pt.x, pt.y); + ::ShowCursor(TRUE); + + return m_pGetNode; +}*/ \ No newline at end of file diff --git a/k-meleon/BrowserWindow.cpp b/k-meleon/BrowserWindow.cpp new file mode 100644 index 00000000..ef3b0399 --- /dev/null +++ b/k-meleon/BrowserWindow.cpp @@ -0,0 +1,1797 @@ +/* + * Copyright (C) 2006 Dorian Boissonnade + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "stdafx.h" +#include "BrowserWindow.h" +#include "BrowserImpl.h" +#include "MozUtils.h" +#include "PrintSetupDialog.h" +#include "PrintProgressDialog.h" +#include "SaveAsHandler.h" +#include "mfcembed.h" +#include "Utils.h" + +#include "nsIWidget.h" +#include "nsISHistory.h" +#include "nsISHEntry.h" +#include "nsIDOMHTMLFrameSetElement.h" +#include "nsIDocShellTreeItem.h" +#include "nsIDOMBarProp.h" +#include "nsIContentViewer.h" +#include "nsIMarkupDocumentViewer.h" +#include "nsIDocCharset.h" +#include "nsISelection.h" +#include "nsISHistoryInternal.h" +#include "nsIDOMText.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMHTMLScriptElement.h" +#include "nsIDOMWindowCollection.h" +#include "nsIWebPageDescriptor.h" + +#include "nsIDOMNSDocument.h" +#include "nsIDOMEventTarget.h" +#include "nsIScriptGlobalObject.h" + +#include "nsISecureBrowserUI.h" +#include "nsISSLStatus.h" +#include "nsISSLStatusProvider.h" +#include "nsICertificateDialogs.h" + +#include "nsIDOMNSHTMLTextAreaElement.h" +#include "nsIDOMHTMLTextAreaElement.h" +#include "nsIDOMNSHTMLInputElement.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLEmbedElement.h" +#include "nsIDOMHTMLObjectElement.h" +#include "nsITypeAheadFind.h" + + +#include "nsIPrintSettingsService.h" +#include "nsCWebBrowserPersist.h" +#include "nsIDomLocation.h" + +#include "nsIX509Cert.h" + +/* For highlight only x_x */ +#include "nsIFind.h" +#include "nsIDOMText.h" +#include "nsIDOMRange.h" +#include "nsISelection.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMDocumentRange.h" +#include "nsIDOMDocumentFragment.h" +#include "nsIDOMWindowCollection.h" +#include "nsPIDOMWindow.h" + +static const PRUnichar kSpan[] = NS_LL("span"); +static const PRUnichar kStyle[] = NS_LL("style"); +static const PRUnichar kClass[] = NS_LL("class"); +static const PRUnichar kHighlighClassName[] = NS_LL("km_hightlight_class"); +static const PRUnichar kDefaultHighlightStyle[] = NS_LL("display: inline;font-size: inherit;padding: 0;color: black;background-color: yellow;"); +/* */ + +#if GECKO_VERSION > 18 +#define nsITypeAheadFind nsISuiteTypeAheadFind +#endif + +CBrowserWrapper::CBrowserWrapper(void) +{ + //mDomEventListener = nsnull; + mpBrowserImpl = nsnull; + mLastMouseActionNode = nsnull; + + mpBrowserImpl = NULL; + mpBrowserFrameGlue = NULL; + mpBrowserGlue = NULL; + mChromeContent = FALSE; + mWndOwner = NULL; + BOOL mIsDocumentLoading = FALSE; + BOOL mIsDOMLoaded = FALSE; +} + +CBrowserWrapper::~CBrowserWrapper(void) +{ +} + +void CBrowserWrapper::SetBrowserGlue(PBROWSERGLUE pBrowserGlue) +{ + mpBrowserGlue = pBrowserGlue; + if (mpBrowserImpl) + mpBrowserImpl->Init(mpBrowserGlue, mWebBrowser); +} + +void CBrowserWrapper::SetBrowserFrameGlue(PBROWSERFRAMEGLUE pBrowserFrameGlue) +{ + mpBrowserFrameGlue = pBrowserFrameGlue; +// if (mpBrowserImpl) +// mpBrowserImpl->Init(pBrowserFrameGlue, mWebBrowser); +} + +BOOL CBrowserWrapper::CreateBrowser(CWnd* parent, BOOL chromeContent) +{ + mChromeContent = chromeContent; + mWndOwner = parent; + + // Create web shell + nsresult rv; + mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + + // Save off the nsIWebNavigation interface pointer + // in the mWebNav member variable which we'll use + // later for web page navigation + mWebNav = do_QueryInterface(mWebBrowser, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + + // Get the focus object + mWebBrowserFocus = do_QueryInterface(mWebBrowser, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + + // Create the CBrowserImpl object - this is the object + // which implements the interfaces which are required + // by an app embedding mozilla i.e. these are the interfaces + // thru' which the *embedded* browser communicates with the + // *embedding* app + // + // The CBrowserImpl object will be passed in to the + // SetContainerWindow() call below + // + // Also note that we're passing the BrowserFrameGlue pointer + // and also the mWebBrowser interface pointer via CBrowserImpl::Init() + // of CBrowserImpl object. + // These pointers will be saved by the CBrowserImpl object. + // The CBrowserImpl object uses the BrowserFrameGlue pointer to + // call the methods on that interface to update the status/progress bars + // etc. + mpBrowserImpl = new CBrowserImpl(); + NS_ENSURE_TRUE(mpBrowserImpl, FALSE); + + // Pass along the mpBrowserFrameGlue pointer to the BrowserImpl object + // This is the interface thru' which the XP BrowserImpl code communicates + // with the platform specific code to update status bars etc. + mpBrowserImpl->Init(mpBrowserGlue, mWebBrowser); + mpBrowserImpl->AddRef(); + mWebBrowser->SetContainerWindow(static_cast(mpBrowserImpl)); + + + nsCOMPtr dsti = do_QueryInterface(mWebBrowser, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + + // XXX Content and chrome dialog are currently the same type of window. + // Set the correct type depending if this window will host chrome or content. + dsti->SetItemType( chromeContent ? + //m_chromeMask & nsIWebBrowserChrome::CHROME_OPENAS_CHROME ? + nsIDocShellTreeItem::typeChromeWrapper : + nsIDocShellTreeItem::typeContentWrapper); + + // Create the real webbrowser window + + // Note that we're passing the m_hWnd in the call below to InitWindow() + // (CBrowserView inherits the m_hWnd from CWnd) + // This m_hWnd will be used as the parent window by the embeddable browser + + mBaseWindow = do_QueryInterface(mWebBrowser, &rv); + if (NS_FAILED(rv)) { + DestroyBrowser(); + return FALSE; + } + + CRect rect; + parent->GetClientRect(rect); + rv = mBaseWindow->InitWindow(nsNativeWidget(parent->GetSafeHwnd()), nsnull, 0, 0, rect.Width(), rect.Height()); + rv = mBaseWindow->Create(); + + // Register the BrowserImpl object to receive progress messages + // These callbacks will be used to update the status/progress bars + nsCOMPtr weak = do_GetWeakReference(static_cast(mpBrowserImpl)); + mWebBrowser->AddWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener)); + + // Add listeners for various events like popup-blocking, link added ... + if (!chromeContent) AddListeners(); + + // Find again observer to know when a new search was triggered + /* nsCOMPtr observerService = + do_GetService("@mozilla.org/observer-service;1", &rv); + if (NS_SUCCEEDED(rv)) + observerService->AddObserver(mpBrowserImpl, "nsWebBrowserFind_FindAgain", PR_TRUE);*/ + + //History listener + /* nsWeakPtr weakling2( + do_GetWeakReference(NS_STATIC_CAST(nsISHistoryListener*, mpBrowserImpl))); + (void)mWebBrowser->AddWebBrowserListener(weakling2, + NS_GET_IID(nsISHistoryListener));*/ + + /* + nsCOMPtr piWin; + + // get the content DOM window for that web browser + nsCOMPtr domWindow; + mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (!domWindow) + return NS_ERROR_FAILURE; + + // get the private DOM window + nsCOMPtr domWindowPrivate = do_QueryInterface(domWindow); + // and the root window for that DOM window + piWin = domWindowPrivate->GetPrivateRoot(); + + nsCOMPtr mEventReceiver = do_QueryInterface(piWin->GetChromeEventHandler()); + rv = mEventReceiver->AddEventListenerByIID(mpBrowserImpl, + NS_GET_IID(nsIDOMMouseListener)); + */ + + // Finally, show the web browser window + mBaseWindow->SetVisibility(PR_TRUE); + return TRUE; +} + +void CBrowserWrapper::ShowScrollbars(BOOL visible) +{ + nsCOMPtr dom; + mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + NS_ENSURE_TRUE(dom, ); + + nsCOMPtr scrollbars; + dom->GetScrollbars(getter_AddRefs(scrollbars)); + if (scrollbars) + scrollbars->SetVisible(visible); +} + +BOOL CBrowserWrapper::DestroyBrowser() +{ +/* nsresult rv; + nsCOMPtr observerService = + do_GetService("@mozilla.org/observer-service;1", &rv); + if (NS_SUCCEEDED(rv)) + observerService->RemoveObserver(mpBrowserImpl, "nsWebBrowserFind_FindAgain");*/ + + if (!mChromeContent) RemoveListeners(); + + if (mWebNav) + { + mWebNav->Stop(nsIWebNavigation::STOP_ALL); + mWebNav = nsnull; + } + + if (mBaseWindow) + { + mBaseWindow->Destroy(); + mBaseWindow = nsnull; + } + + if (mpBrowserImpl) + { + mpBrowserImpl->Init(NULL, mWebBrowser); + mpBrowserImpl->Release(); + mpBrowserImpl = nsnull; + } + + return TRUE; +} + + +BOOL CBrowserWrapper::AddListeners(void) +{ + nsresult rv; + rv = GetDOMEventTarget(mWebBrowser, (getter_AddRefs(mEventTarget))); + NS_ENSURE_SUCCESS(rv, FALSE); + + mWebNav = do_QueryInterface(mWebBrowser); + NS_ENSURE_TRUE(mWebNav, FALSE); + + mWebBrowserFocus = do_QueryInterface(mWebBrowser); + NS_ENSURE_TRUE(mWebBrowserFocus, FALSE); + + /*mDomEventListener = new CDomEventListener(); + if(mDomEventListener == nsnull) return FALSE; + mDomEventListener->Init(mpBrowserFrameGlue); +*/ + rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("click"), + mpBrowserImpl, PR_TRUE); + rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), + mpBrowserImpl, PR_TRUE); + rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("DOMPopupBlocked"), + mpBrowserImpl, PR_FALSE); + rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("DOMLinkAdded"), + mpBrowserImpl, PR_FALSE); + rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("DOMContentLoaded"), + mpBrowserImpl, PR_FALSE); + + return TRUE; +} + +void CBrowserWrapper::RemoveListeners(void) +{ + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("click"), + mpBrowserImpl, PR_FALSE); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"), + mpBrowserImpl, PR_TRUE); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("DOMPopupBlocked"), + mpBrowserImpl, PR_FALSE); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("DOMLinkAdded"), + mpBrowserImpl, PR_FALSE); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("DOMContentLoaded"), + mpBrowserImpl, PR_FALSE); +} + +BOOL CBrowserWrapper::LoadURL(LPCTSTR url, LPCTSTR referrer, BOOL allowFixup) +{ + //ASSERT(url); + ASSERT(mWebNav); + NS_ENSURE_TRUE(url, FALSE); + NS_ENSURE_TRUE(mWebNav, FALSE); + + nsCOMPtr referrerURI; + if (referrer) +#ifdef _UNICODE + NewURI(getter_AddRefs(referrerURI), nsDependentString(referrer)); +#else + NewURI(getter_AddRefs(referrerURI), nsDependentCString(referrer)); +#endif + + nsresult rv = mWebNav->LoadURI(CStringToPRUnichar(url), + allowFixup ? + nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP : + nsIWebNavigation::LOAD_FLAGS_NONE, + referrerURI, + nsnull, + nsnull); + return NS_SUCCEEDED(rv); +} + +BOOL CBrowserWrapper::LoadURL(LPCTSTR url, BOOL currentForRef, BOOL allowFixup) +{ + ASSERT(url); + ASSERT(mWebNav); + NS_ENSURE_TRUE(url, FALSE); + NS_ENSURE_TRUE(mWebNav, FALSE); + + nsCOMPtr referrerURI; + if (currentForRef) mWebNav->GetCurrentURI(getter_AddRefs(referrerURI)); + + nsresult rv = mWebNav->LoadURI(CStringToPRUnichar(url), + allowFixup ? + nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP : + nsIWebNavigation::LOAD_FLAGS_NONE, + referrerURI, + nsnull, + nsnull); + return NS_SUCCEEDED(rv); +} + +CString CBrowserWrapper::GetTitle() +{ + NS_ENSURE_TRUE(mBaseWindow, _T("")); + PRUnichar *idlStrTitle = nsnull; + + mBaseWindow->GetTitle(&idlStrTitle); + NS_ENSURE_TRUE(idlStrTitle, _T("")); + + CString title = PRUnicharToCString(idlStrTitle); + nsMemory::Free(idlStrTitle); + return title; +} + +CString CBrowserWrapper::GetURI(BOOL unescape) +{ + NS_ENSURE_TRUE(mWebNav, _T("")); + nsCOMPtr currentURI; + nsresult rv = mWebNav->GetCurrentURI(getter_AddRefs(currentURI)); + if(NS_FAILED(rv) || !currentURI) + return _T(""); + + // Get the uri string associated with the nsIURI object + nsEmbedCString uriString; + rv = currentURI->GetSpec(uriString); + NS_ENSURE_SUCCESS(rv, _T("")); + + if (unescape) { + char* temp = strdup(uriString.get()); + uriString.Assign(nsUnescape(temp)); + free(temp); + } + + return NSUTF8StringToCString(uriString); +} + +BOOL CBrowserWrapper::GetCharset(char* aCharset) +{ + NS_ENSURE_TRUE(mWebBrowser, FALSE); + + // Look for the forced charset + nsresult result; + nsCOMPtr DocShell = do_GetInterface (mWebBrowser); + NS_ENSURE_TRUE(DocShell, FALSE); + + nsCOMPtr contentViewer; + result = DocShell->GetContentViewer (getter_AddRefs(contentViewer)); + if (NS_FAILED(result) || !contentViewer) + return FALSE; + + nsCOMPtr mdv = do_QueryInterface(contentViewer,&result); + if (NS_FAILED(result) || !mdv) + return FALSE; + + nsCString mCharset; + result = mdv->GetForceCharacterSet(mCharset); + + if (NS_FAILED(result) || mCharset.IsEmpty() ) + { + // If no forced charset look for the document charset + nsCOMPtr docCharset = do_GetInterface(mWebBrowser); + NS_ENSURE_TRUE(docCharset, FALSE); + + char *charset; + result = docCharset->GetCharset (&charset); + if (!charset) + { + // If no document charset use default + result = mdv->GetDefaultCharacterSet(mCharset); + } + else + { + mCharset = charset; + nsMemory::Free (charset); + } + } + + strncpy(aCharset, mCharset.get(), 63); + aCharset[63] = 0; + return NS_SUCCEEDED(result); +} + +BOOL CBrowserWrapper::ForceCharset(const char *aCharSet) +{ + nsresult result; + nsCOMPtr DocShell = do_GetInterface (mWebBrowser); + NS_ENSURE_TRUE(DocShell, FALSE); + + nsCOMPtr contentViewer; + result = DocShell->GetContentViewer (getter_AddRefs(contentViewer)); + if (NS_FAILED(result) || !contentViewer) + return FALSE; + + nsCOMPtr mdv = do_QueryInterface(contentViewer,&result); + if (NS_FAILED(result) || !mdv) + return FALSE; + + nsCString mCharset; + mCharset = aCharSet; + result = mdv->SetForceCharacterSet(mCharset); + + if (NS_SUCCEEDED(result)) + mWebNav->Reload(nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE); + + return NS_SUCCEEDED(result); +} + +BOOL CBrowserWrapper::ScrollBy(INT dx, INT dy) +{ + nsCOMPtr dom; + mWebBrowserFocus->GetFocusedWindow(getter_AddRefs(dom)); + if (!dom) { + nsCOMPtr element; + mWebBrowserFocus->GetFocusedElement(getter_AddRefs(element)); + if (element) { + nsCOMPtr node(do_QueryInterface(element)); + } + mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + } + NS_ENSURE_TRUE(dom, FALSE); + + return dom->ScrollBy (dx, dy); +} + +BOOL CBrowserWrapper::SetTextSize(float textzoom) +{ + nsresult rv; + + nsCOMPtr domWindow; + rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + NS_ENSURE_SUCCESS(rv, FALSE); + + rv = domWindow->SetTextZoom(textzoom); + return NS_SUCCEEDED(rv); +} + +float CBrowserWrapper::GetTextSize() +{ + nsresult rv; + + nsCOMPtr domWindow; + rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + NS_ENSURE_SUCCESS(rv, -1); + + float textzoom; + rv = domWindow->GetTextZoom(&textzoom); + return NS_SUCCEEDED(rv) ? textzoom : -1; +} + +BOOL CBrowserWrapper::ChangeTextSize(int change) +{ + float textzoom = GetTextSize(); + if (textzoom == -1) + return FALSE; + + textzoom = (textzoom*10 + (float)change) / 10; + if (textzoom <=0 || textzoom > 4) + return FALSE; + + SetTextSize(textzoom); + + CString status; + status.Format(IDS_TEXT_ZOOM, textzoom*10); + mpBrowserImpl->SetStatus(0, CStringToPRUnichar(status)); + return TRUE; +} + +BOOL CBrowserWrapper::GetSHistory(nsISHistory **aSHistory) +{ + nsCOMPtr sHistory; + mWebNav->GetSessionHistory(getter_AddRefs(sHistory)); + NS_ENSURE_TRUE(sHistory, FALSE); + + *aSHistory = sHistory.get(); + NS_IF_ADDREF(*aSHistory); + + return TRUE; +} + +BOOL CBrowserWrapper::CloneSHistory(CBrowserWrapper* newWebBrowser) +{ + nsCOMPtr oldSH; + GetSHistory(getter_AddRefs(oldSH)); + NS_ENSURE_TRUE(oldSH, FALSE); + + PRInt32 count; + oldSH->GetCount(&count); + if (!count) { + newWebBrowser->LoadURL(_T("about:blank")); + return TRUE; + } + + nsCOMPtr newSH; + newWebBrowser->GetSHistory(getter_AddRefs(newSH)); + NS_ENSURE_TRUE(newSH, FALSE); + + nsCOMPtr newSHInternal(do_QueryInterface(newSH)); + NS_ENSURE_TRUE(newSHInternal, FALSE); + + nsCOMPtr she; + nsCOMPtr he; + + for (int i=0;iGetEntryAtIndex(i, PR_FALSE, getter_AddRefs(he)); + + she = do_QueryInterface(he); + if (she) { + nsCOMPtr newSHEntry; + she->Clone(getter_AddRefs(newSHEntry)); + if (newSHEntry) newSHInternal->AddEntry(newSHEntry, PR_TRUE); + } + } + + PRInt32 index; + oldSH->GetIndex(&index); + newWebBrowser->GotoHistoryIndex(index); + + + return TRUE; +} + +BOOL CBrowserWrapper::GotoHistoryIndex(UINT index) +{ + NS_ENSURE_TRUE(mWebNav, FALSE); + return mWebNav->GotoIndex (index); +} + +BOOL CBrowserWrapper::GetSHistoryState(int& index, int& count) +{ + NS_ENSURE_TRUE (mWebBrowser, FALSE); + + nsCOMPtr sHistory; + mWebNav->GetSessionHistory(getter_AddRefs(sHistory)); + NS_ENSURE_TRUE(sHistory, FALSE); + + sHistory->GetCount(&count); + sHistory->GetIndex(&index); + + return TRUE; +} + +BOOL CBrowserWrapper::GetSHistoryInfoAt(PRInt32 index, CString& title, CString& url) +{ + NS_ENSURE_TRUE(mWebBrowser, FALSE); + + nsCOMPtr sHistory; + mWebNav->GetSessionHistory(getter_AddRefs(sHistory)); + NS_ENSURE_TRUE(sHistory, FALSE); + + nsCOMPtr he; + sHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(he)); + NS_ENSURE_TRUE(he, FALSE); + + nsresult rv; + nsEmbedCString nsUrl; + PRUnichar* nsTitle; + + rv = he->GetTitle(&nsTitle); + NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && title, FALSE); + + title = PRUnicharToCString(nsTitle); + nsMemory::Free(nsTitle); + + nsCOMPtr uri; + he->GetURI(getter_AddRefs(uri)); + NS_ENSURE_TRUE(uri, FALSE); + + rv = uri->GetSpec(nsUrl); + url = NSUTF8StringToCString(nsUrl); + + NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && url.GetLength(), FALSE); + + return TRUE; +} + +void CBrowserWrapper::PrintSetup() +{ + if (!mPrintSettings) InitPrintSettings(); + + CPrintSetupDialog dlg(mWndOwner); + + dlg.SetPrintSettings(mPrintSettings); + if (dlg.DoModal() != IDOK) return; + dlg.GetPrintSettings(mPrintSettings); + + nsCOMPtr psService = + do_GetService("@mozilla.org/gfx/printsettings-service;1"); + NS_ENSURE_TRUE(psService, ); + + psService->SavePrintSettingsToPrefs(mPrintSettings, PR_FALSE, nsIPrintSettings::kInitSaveAll); + + nsCOMPtr print(do_GetInterface(mWebBrowser)); + NS_ENSURE_TRUE(print, ); + + PRBool isPreview = PR_FALSE; + nsresult rv = print->GetDoingPrintPreview(&isPreview); + NS_ENSURE_SUCCESS(rv, ); + + if (isPreview) + { + if (NS_SUCCEEDED(print->PrintPreview(mPrintSettings, nsnull, nsnull))) + { + // WORKAROUND - FIX ME: Why the print preview doesn't use all the width? + // So I'm forcing the window to reposition itself. + CRect rect; + mWndOwner->GetClientRect(rect); + mBaseWindow->SetPositionAndSize(0, 0, rect.right, rect.bottom, PR_TRUE); + } + } + +} + +BOOL CBrowserWrapper::Print() +{ + NS_ENSURE_TRUE(mWebBrowser, FALSE); + + nsCOMPtr print(do_GetInterface(mWebBrowser)); + NS_ENSURE_TRUE(print, FALSE); + + if (!mPrintSettings) InitPrintSettings(); + + CPrintProgressDialog dlg(mWndOwner); + nsresult rv = print->Print(mPrintSettings, static_cast(dlg.m_PrintListener.get())); + NS_ENSURE_SUCCESS(rv, FALSE); + + if (dlg.DoModal() != IDOK) { + print->Cancel(); + return FALSE; + } + return TRUE; +} + +BOOL CBrowserWrapper::InitPrintSettings() +{ + nsCOMPtr psService = + do_GetService("@mozilla.org/gfx/printsettings-service;1"); + NS_ENSURE_TRUE(psService, FALSE); + + psService->GetGlobalPrintSettings(getter_AddRefs(mPrintSettings)); + NS_ENSURE_TRUE(mPrintSettings, FALSE); + + nsresult rv = psService->InitPrintSettingsFromPrefs(mPrintSettings, PR_FALSE, nsIPrintSettings::kInitSaveAll); + return NS_SUCCEEDED(rv); +} + +BOOL CBrowserWrapper::PrintPreview() +{ + nsCOMPtr print(do_GetInterface(mWebBrowser)); + NS_ENSURE_TRUE(print, FALSE); + + if (!mPrintSettings) InitPrintSettings(); + + PRBool isPreview = PR_FALSE; + nsresult rv = print->GetDoingPrintPreview(&isPreview); + NS_ENSURE_SUCCESS(rv, FALSE); + + if (isPreview) + rv = print->ExitPrintPreview(); + else { + rv = print->PrintPreview(mPrintSettings, nsnull, nsnull); + // WORKAROUND - FIX ME: Why the print preview doesn't use all the width? + // So I'm forcing the window to reposition itself. + CRect rect; + mWndOwner->GetClientRect(rect); + mBaseWindow->SetPositionAndSize(0, 0, rect.right, rect.bottom, PR_TRUE); + } + + return NS_SUCCEEDED(rv); +} + +BOOL CBrowserWrapper::_InjectCSS(nsIDOMWindow* dom, const wchar_t* userStyleSheet) +{ + if (!dom) return FALSE; + + nsresult rv; + + nsCOMPtr document; + rv = dom->GetDocument(getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr styleElement; + rv = document->CreateElement(nsDependentString(L"style"), getter_AddRefs(styleElement)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr textStyle; + rv = document->CreateTextNode(nsDependentString(userStyleSheet), getter_AddRefs(textStyle)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr notused; + rv = styleElement->AppendChild(textStyle, getter_AddRefs(notused)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr headList; + rv = document->GetElementsByTagName(nsDependentString(L"head"), getter_AddRefs(headList)); + if (headList) + { + nsCOMPtr headNode; + rv = headList->Item(0, getter_AddRefs(headNode)); + NS_ENSURE_SUCCESS(rv, FALSE); + + rv = headNode->AppendChild(styleElement, getter_AddRefs(notused)); + } + else + { + nsCOMPtr documentElement; + document->GetDocumentElement(getter_AddRefs(documentElement)); + rv = documentElement->AppendChild(styleElement, getter_AddRefs(notused)); + } + + BOOL b = TRUE; + nsCOMPtr frames; + dom->GetFrames(getter_AddRefs(frames)); + if (frames) + { + PRUint32 nbframes; + frames->GetLength(&nbframes); + if (nbframes>0) + { + nsCOMPtr frame; + for (PRUint32 i = 0; iItem(i, getter_AddRefs(frame)); + if (NS_FAILED(rv)) return FALSE; + b = b && _InjectCSS(frame, userStyleSheet); + } + } + } + + return b && NS_SUCCEEDED(rv); +} + +BOOL CBrowserWrapper::InjectCSS(const wchar_t* userStyleSheet) +{ + nsresult rv; + nsCOMPtr dom; + + rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + NS_ENSURE_SUCCESS(rv, FALSE); + + // Use a recursive function to inject the CSS in all frames. + return _InjectCSS(dom, userStyleSheet); +} + +BOOL CBrowserWrapper::InjectJS(const wchar_t* userScript, bool bTopWindow) +{ + nsresult rv; + nsCOMPtr document; + + PRBool jsEnabled = PR_TRUE; + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID, &rv); + if (prefs) { + prefs->GetBoolPref("javascript.enabled", &jsEnabled); + prefs->SetBoolPref("javascript.enabled", PR_TRUE); + } + + if (!bTopWindow) + { + if (mLastMouseActionNode) + rv = mLastMouseActionNode->GetOwnerDocument(getter_AddRefs(document)); + else + { + nsCOMPtr dom; + mWebBrowserFocus->GetFocusedWindow(getter_AddRefs(dom)); + if (dom) + rv = dom->GetDocument(getter_AddRefs(document)); + } + + } + + if (!document) + { + nsCOMPtr dom; + rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + NS_ENSURE_SUCCESS(rv, FALSE); + + rv = dom->GetDocument(getter_AddRefs(document)); + } + + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr body; + nsCOMPtr htmlDoc(do_QueryInterface(document)); + /*if (htmlDoc) + { + nsCOMPtr htmlBody; + htmlDoc->GetBody (getter_AddRefs(htmlBody)); + body = do_QueryInterface(htmlBody); + NS_ENSURE_TRUE(body, FALSE); + } + else*/ + { + rv = document->GetDocumentElement (getter_AddRefs(body)); + NS_ENSURE_SUCCESS(rv, FALSE); + } + + nsCOMPtr scriptElement; + rv = document->CreateElement(nsDependentString(L"script"), getter_AddRefs(scriptElement)); + NS_ENSURE_SUCCESS(rv, FALSE); +/* + nsCOMPtr textScript; + rv = document->CreateTextNode(nsDependentString(userScript), getter_AddRefs(textScript)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr notused; + rv = scriptElement->AppendChild(textScript, getter_AddRefs(notused)); + NS_ENSURE_SUCCESS(rv, FALSE);*/ + + nsCOMPtr scriptTag = do_QueryInterface(scriptElement); + NS_ENSURE_TRUE(scriptTag, FALSE); + + scriptTag->SetText(nsDependentString(userScript)); + scriptTag->SetType(nsDependentString(L"text/javascript")); + + nsCOMPtr notused; + rv = body->AppendChild(scriptTag, getter_AddRefs(notused)); + NS_ENSURE_SUCCESS(rv, FALSE); + + rv = body->RemoveChild(scriptTag, getter_AddRefs(notused)); + + if (prefs) prefs->SetBoolPref("javascript.enabled", jsEnabled); + + return TRUE; +} + +BOOL CBrowserWrapper::_GetSelection(nsIDOMWindow* dom, nsAString &aSelText) +{ + nsCOMPtr sel; + dom->GetSelection(getter_AddRefs(sel)); + if (sel) { + PRUnichar* selText; + nsresult rv = sel->ToString(&selText); + NS_ENSURE_SUCCESS(rv, FALSE); + + aSelText = selText; + nsMemory::Free(selText); + if (aSelText.Length()>0) + return TRUE; + } + + BOOL ret = FALSE; + + nsCOMPtr frames; + dom->GetFrames(getter_AddRefs(frames)); + NS_ENSURE_TRUE(frames, FALSE); + + PRUint32 nbframes; + frames->GetLength(&nbframes); + if (nbframes>0) + { + nsCOMPtr frame; + for (PRUint32 i = 0; iItem(i, getter_AddRefs(frame)); + ret = ret || _GetSelection(frame, aSelText); + } + } + return ret; +} + +BOOL CBrowserWrapper::GetSelectionInsideForm(nsIDOMElement *element, nsEmbedString &aSelText) +{ + nsCOMPtr domnsinput = do_QueryInterface(element); + if (domnsinput) + { + PRInt32 start, end; + nsresult rv; + rv = domnsinput->GetSelectionStart(&start); + rv |= domnsinput->GetSelectionEnd(&end); + NS_ENSURE_SUCCESS(rv, FALSE); + + if (start >= end) return FALSE; + + nsCOMPtr dominput = do_QueryInterface(element); + if (!dominput) return FALSE; + + nsEmbedString value; + dominput->GetValue(value); + value.Cut(end,-1); + if (start>value.Length()) + return FALSE; + + aSelText = value.get()+start; + return TRUE; + } + + nsCOMPtr tansinput = do_QueryInterface(element); + if (tansinput) + { + PRInt32 start, end; + nsresult rv; + rv = tansinput->GetSelectionStart(&start); + rv |= tansinput->GetSelectionEnd(&end); + NS_ENSURE_SUCCESS(rv, FALSE); + if (start >= end) return FALSE; + + nsCOMPtr tainput = do_QueryInterface(element); + if (!tansinput) return FALSE; + + nsEmbedString value; + tainput->GetValue(value); + value.Cut(end,-1); + if (start>value.Length()) + return FALSE; + + aSelText = value.get()+start; + return TRUE; + } + + return FALSE; +} + +BOOL CBrowserWrapper::GetUSelection(nsEmbedString& aSelText) +{ + nsCOMPtr dom(do_GetInterface(mWebBrowser)); + NS_ENSURE_TRUE(dom, FALSE); + + // Check selection inside the focused element if it's an + // input text or a textarea element. + nsCOMPtr element; + mWebBrowserFocus->GetFocusedElement(getter_AddRefs(element)); + if (element) + { + if (GetSelectionInsideForm(element, aSelText)) + return TRUE; + } + + // Check normal selection inside the document + if (_GetSelection(dom, aSelText)) + return TRUE; + + return FALSE; +} + +BOOL CBrowserWrapper::GetSelection(CString& aSelText) +{ + nsEmbedString selText; + if (!GetUSelection(selText)) + return FALSE; + + aSelText = NSStringToCString(selText); + return TRUE; +} + +BOOL CBrowserWrapper::GetCertificate(nsIX509Cert** certificate) +{ + nsresult rv; + + nsCOMPtr docShell(do_GetInterface(mWebBrowser, &rv)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr securityInfo; + rv = docShell->GetSecurityUI(getter_AddRefs(securityInfo)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr SSLProvider = do_QueryInterface(securityInfo,&rv); + if (!SSLProvider) return FALSE; + + nsCOMPtr SSLStatus; + SSLProvider->GetSSLStatus(getter_AddRefs(SSLStatus)); + if (!SSLStatus) return FALSE; + + nsCOMPtr cert; + SSLStatus->GetServerCert(getter_AddRefs (cert)); + if (!cert) return FALSE; + + *certificate = cert; + NS_ADDREF(*certificate); + + return TRUE; +} + +BOOL CBrowserWrapper::GetSecurityInfo(CString &sign) +{ + nsresult rv; + + nsCOMPtr docShell (do_GetInterface (mWebBrowser, &rv)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr securityInfo; + rv = docShell->GetSecurityUI (getter_AddRefs (securityInfo)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsEmbedString tooltip; + rv = securityInfo->GetTooltipText (tooltip); + NS_ENSURE_SUCCESS(rv, FALSE); + + sign = NSStringToCString(tooltip); + + return TRUE; +} + +int CBrowserWrapper::GetSecurityState() +{ + nsCOMPtr docShell(do_GetInterface(mWebBrowser)); + NS_ENSURE_TRUE(docShell, nsIWebProgressListener::STATE_IS_INSECURE); + + nsCOMPtr securityInfo; + docShell->GetSecurityUI(getter_AddRefs(securityInfo)); + NS_ENSURE_TRUE(securityInfo, nsIWebProgressListener::STATE_IS_INSECURE); + + PRUint32 s; + securityInfo->GetState(&s); + return s & 0xffff; +} + +BOOL CBrowserWrapper::ShowCertificate() +{ + nsresult rv; + nsCOMPtr docShell (do_GetInterface (mWebBrowser, &rv)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr cert; + nsCOMPtr securityInfo; + rv = docShell->GetSecurityUI (getter_AddRefs (securityInfo)); + if (NS_FAILED(rv) || !(GetCertificate(getter_AddRefs(cert)))) + return FALSE; + + nsCOMPtr certDialogs = do_GetService (NS_CERTIFICATEDIALOGS_CONTRACTID, &rv); + NS_ENSURE_TRUE(certDialogs, FALSE); + + rv = certDialogs->ViewCert(NULL, cert); + return NS_SUCCEEDED(rv); +} + +BOOL CBrowserWrapper::ViewContentContainsFrames() +{ + nsresult rv = NS_OK; + + // Get nsIDOMDocument from nsIWebNavigation + nsCOMPtr domDoc; + rv = mWebNav->GetDocument(getter_AddRefs(domDoc)); + if(NS_FAILED(rv)) + return FALSE; + + // QI nsIDOMDocument for nsIDOMHTMLDocument + nsCOMPtr htmlDoc = do_QueryInterface(domDoc); + if (!htmlDoc) + return FALSE; + + // Get the element of the doc + nsCOMPtr body; + rv = htmlDoc->GetBody(getter_AddRefs(body)); + if(NS_FAILED(rv)) + return FALSE; + + // Is it of type nsIDOMHTMLFrameSetElement? + nsCOMPtr frameset = do_QueryInterface(body); + + return (frameset != nsnull); +} + + +PRBool CBrowserWrapper::CheckNode(nsIDOMElement* elem) +{ + if (elem) + { + nsEmbedString className; + elem->GetAttribute(nsEmbedString(kClass), className); + if (className.Equals(nsEmbedString(kHighlighClassName))) + return PR_TRUE; + } + return PR_FALSE; +} + +BOOL CBrowserWrapper::Highlight(const PRUnichar* backcolor, const PRUnichar* word, BOOL matchCase) +{ + nsCOMPtr dom; + nsresult rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + NS_ENSURE_SUCCESS(rv, FALSE); + + return _Highlight(dom, backcolor, word, matchCase); +} + +BOOL CBrowserWrapper::_Highlight(nsIDOMWindow* dom, const PRUnichar* backcolor, const PRUnichar* word, BOOL matchCase) +{ + nsCOMPtr document; + nsresult rv = dom->GetDocument(getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr frames; + dom->GetFrames(getter_AddRefs(frames)); + if (frames) + { + PRUint32 nbframes; + nsCOMPtr frame; + frames->GetLength(&nbframes); + for (PRUint32 i = 0; iItem(i, getter_AddRefs(frame)); + _Highlight(frame, backcolor, word, matchCase); + } + } + + nsCOMPtr find = do_CreateInstance("@mozilla.org/embedcomp/rangefind;1", &rv); + if (NS_FAILED(rv)) return FALSE; + + find->SetCaseSensitive(matchCase); + find->SetFindBackwards(PR_FALSE); + + nsCOMPtr docrange = do_QueryInterface(document); + if (!docrange) return FALSE; + + nsCOMPtr searchRange, startPt, endPt; + docrange->CreateRange(getter_AddRefs(searchRange)); + docrange->CreateRange(getter_AddRefs(startPt)); + docrange->CreateRange(getter_AddRefs(endPt)); + + nsCOMPtr body; + nsCOMPtr htmlDoc(do_QueryInterface(document)); + NS_ENSURE_TRUE(htmlDoc, FALSE); + + htmlDoc->GetBody(getter_AddRefs(body)); + NS_ENSURE_TRUE(body, FALSE); + + nsCOMPtr nodelist; + rv = body->GetChildNodes(getter_AddRefs(nodelist)); + NS_ENSURE_SUCCESS(rv, FALSE); + + PRUint32 count; + nodelist->GetLength(&count); + + searchRange->SetStart(body, 0); + searchRange->SetEnd(body, count); + startPt->SetStart(body, 0); + startPt->SetEnd(body, 0); + endPt->SetStart(body, count); + endPt->SetEnd(body, count); + + if(!backcolor) + { + // To optimize + + while (1) + { + nsCOMPtr retRange; + rv = find->Find(word, searchRange, startPt, endPt, getter_AddRefs(retRange)); + if (NS_FAILED(rv) || !retRange) break; + + nsCOMPtr startContainer; + retRange->GetStartContainer(getter_AddRefs(startContainer)); + if (!startContainer) break; + + nsCOMPtr node; + rv = startContainer->GetParentNode(getter_AddRefs(node)); + nsCOMPtr elem = do_QueryInterface(node); + + PRBool bFound = CheckNode(elem); + + if (!bFound && elem) + { + nsCOMPtr node; + retRange->GetEndContainer(getter_AddRefs(node)); + if (!node) break; + + while (1) + { + rv = elem->GetParentNode(getter_AddRefs(node)); + elem = do_QueryInterface(node); + if (NS_FAILED(rv) || !elem) break; + + if (CheckNode(elem)) { + bFound = PR_TRUE; + break; + } + } + } + + if (bFound) + { + nsCOMPtr fragment; + document->CreateDocumentFragment(getter_AddRefs(fragment)); + nsCOMPtr next, parent, child, notused; + rv = elem->GetNextSibling(getter_AddRefs(next)); + if (NS_FAILED(rv) || !retRange) break; + rv = elem->GetParentNode(getter_AddRefs(parent)); + if (NS_FAILED(rv) || !retRange) break; + while(1) + { + elem->GetFirstChild(getter_AddRefs(child)); + if (NS_FAILED(rv) || !child) break; + fragment->AppendChild(child, getter_AddRefs(notused)); + } + docrange->CreateRange(getter_AddRefs(startPt)); + startPt->SetStartAfter(elem); + parent->RemoveChild(elem, getter_AddRefs(notused)); + parent->InsertBefore(fragment, next, getter_AddRefs(notused)); + parent->Normalize(); + } + else + { + nsCOMPtr ec; + retRange->GetEndContainer(getter_AddRefs(ec)); + if (!ec) break; + + PRInt32 startOffset, endOffset; + retRange->GetStartOffset(&startOffset); + retRange->GetEndOffset(&endOffset); + + docrange->CreateRange(getter_AddRefs(startPt)); + startPt->SetStart(ec, endOffset); + } + startPt->Collapse(PR_TRUE); + } + return TRUE; + } + + nsCOMPtr baseElement; + rv = document->CreateElement(nsEmbedString(kSpan), getter_AddRefs(baseElement)); + NS_ENSURE_SUCCESS(rv, FALSE); + + baseElement->SetAttribute(nsEmbedString(kStyle), nsEmbedString(kDefaultHighlightStyle)); + baseElement->SetAttribute(nsEmbedString(kClass), nsEmbedString(kHighlighClassName)); + + while (1) + { + nsCOMPtr retRange; + rv = find->Find(word, searchRange, startPt, endPt, getter_AddRefs(retRange)); + if (NS_FAILED(rv) || !retRange) break; + + nsCOMPtr tNode; + baseElement->CloneNode(PR_FALSE, getter_AddRefs(tNode)); + nsCOMPtr hNode = do_QueryInterface(tNode); + if (!hNode) break; + + nsCOMPtr sc; + retRange->GetStartContainer(getter_AddRefs(sc)); + + nsCOMPtr ec; + retRange->GetEndContainer(getter_AddRefs(ec)); + + PRInt32 startOffset, endOffset; + retRange->GetStartOffset(&startOffset); + retRange->GetEndOffset(&endOffset); + + nsCOMPtr fragment; + rv = retRange->ExtractContents(getter_AddRefs(fragment)); + if (NS_FAILED(rv)) break; + + nsCOMPtr fchild,lchild; + fragment->GetFirstChild(getter_AddRefs(fchild)); + fragment->GetLastChild(getter_AddRefs(lchild)); + if (!fchild || !lchild) break; + + PRUint16 ftype, ltype; + fchild->GetNodeType(&ftype); + lchild->GetNodeType(<ype); + + nsCOMPtr before; + if (ftype==nsIDOMNode::ELEMENT_NODE && ltype==nsIDOMNode::ELEMENT_NODE) + { + rv = ec->GetParentNode(getter_AddRefs(before)); + if (NS_FAILED(rv)||!before) break; + } + else + { + nsCOMPtr container = do_QueryInterface(sc); + PRInt32 offset = startOffset; + if (ftype==nsIDOMNode::ELEMENT_NODE) + { + container = do_QueryInterface(ec); + offset = 0; + } + + if (!container) break; + + nsCOMPtr beforeText; + rv = container->SplitText(offset, getter_AddRefs(beforeText)); + before = do_QueryInterface(beforeText); + if (NS_FAILED(rv)||!before) break; + } + + nsCOMPtr parent; + rv = before->GetParentNode(getter_AddRefs(parent)); + if (NS_FAILED(rv)) break; + + nsCOMPtr notused; + rv = hNode->AppendChild(fragment, getter_AddRefs(notused)); + if (NS_FAILED(rv)) break; + + rv = parent->InsertBefore(hNode, before, getter_AddRefs(notused)); + if (NS_FAILED(rv)) break; + + nsCOMPtr docowner; + rv = hNode->GetOwnerDocument(getter_AddRefs(docowner)); + if (NS_FAILED(rv)) break; + + nsCOMPtr docOwnerRange = do_QueryInterface(document); + if (!docOwnerRange) break; + + rv = docOwnerRange->CreateRange(getter_AddRefs(startPt)); + if (NS_FAILED(rv)) break; + + nsCOMPtr nodelist; + rv = hNode->GetChildNodes(getter_AddRefs(nodelist)); + if (NS_FAILED(rv) || !nodelist) break; + + PRUint32 count; + nodelist->GetLength(&count); + + startPt->SetStart(hNode, count); + startPt->SetEnd(hNode, count); + } + + return TRUE; +} + +already_AddRefed CBrowserWrapper::GetPageDescriptor(BOOL focus) +{ + nsCOMPtr docShell; + if (!focus) { + docShell = do_GetInterface(mWebBrowser); + if (!docShell) return NULL; + } else { + nsCOMPtr domWindow; + mWebBrowserFocus->GetFocusedWindow(getter_AddRefs(domWindow)); + + if (!domWindow) + mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + + if (!domWindow) return NULL; +#if GECKO_VERSION > 18 + nsCOMPtr privWin(do_QueryInterface(domWindow)); + if (!domWindow) return NULL; + docShell = privWin->GetDocShell(); +#else + nsCOMPtr global(do_QueryInterface(domWindow)); + if (!global) return NULL; + docShell = global->GetDocShell(); +#endif + } + + nsCOMPtr wpd = do_QueryInterface(docShell); + if (!wpd) return NULL; + + nsISupports* descriptor; + wpd->GetCurrentDescriptor(&descriptor); + return descriptor; +} + +BOOL CBrowserWrapper::CanSave() +{ + nsEmbedCString contentType; + nsCOMPtr document; + nsCOMPtr dom; + + nsresult rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + NS_ENSURE_SUCCESS(rv, FALSE); + + rv = dom->GetDocument(getter_AddRefs(document)); + + nsCOMPtr nsdoc = do_QueryInterface(document); + NS_ENSURE_TRUE (nsdoc, FALSE); + + nsEmbedString type; + rv = nsdoc->GetContentType(type); + NS_UTF16ToCString(type, NS_CSTRING_ENCODING_ASCII, contentType); + + const char* ctype = contentType.get(); + PRBool isHTML = + (strcmp(ctype, "text/html") == 0) || + (strcmp(ctype, "text/xml") == 0) || + (strcmp(ctype, "application/xhtml+xml") == 0) ; + + return (!IsBusy() || mIsDOMLoaded || !isHTML); +} + +BOOL CBrowserWrapper::SaveDocument(BOOL frame, LPCTSTR filename) +{ + nsCOMPtr dom; + if (frame) mWebBrowserFocus->GetFocusedWindow(getter_AddRefs(dom)); + if (!dom) mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + NS_ENSURE_TRUE(dom, FALSE); + + nsCOMPtr document; + nsresult rv = dom->GetDocument(getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr nsURI; + nsCOMPtr cacheDescriptor; + if (!frame) + { + rv = mWebNav->GetCurrentURI(getter_AddRefs(nsURI)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr docShell = do_GetInterface(mWebBrowser, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr descriptor; + descriptor = do_QueryInterface(docShell); + if (descriptor) + descriptor->GetCurrentDescriptor(getter_AddRefs(cacheDescriptor)); + } + else + { + nsCOMPtr nsDocument(do_QueryInterface(document)); + NS_ENSURE_TRUE(document, FALSE); + + nsCOMPtr location; + nsDocument->GetLocation(getter_AddRefs(location)); + NS_ENSURE_TRUE(location, FALSE); + + nsEmbedString nsURL; + location->GetHref(nsURL); + nsresult rv = NewURI(getter_AddRefs(nsURI), nsURL); + NS_ENSURE_SUCCESS(rv, FALSE); + } + + nsCOMPtr referrer; + mWebNav->GetReferringURI(getter_AddRefs(referrer)); + + return _Save(nsURI, document, filename, referrer, cacheDescriptor); +} + +BOOL CBrowserWrapper::SaveURL(LPCTSTR url, LPCTSTR filename) +{ + ASSERT(url); + NS_ENSURE_TRUE(url, FALSE); + + nsCOMPtr nsURI; +#ifdef _UNICODE + nsresult rv = NewURI(getter_AddRefs(nsURI), nsEmbedString((WCHAR*)url)); +#else + nsresult rv = NewURI(getter_AddRefs(nsURI), nsEmbedCString((char*)url)); +#endif + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr referrer; + mWebNav->GetCurrentURI(getter_AddRefs(referrer)); + + return _Save(nsURI, nsnull, filename, referrer, nsnull); +} + +BOOL CBrowserWrapper::_Save(nsIURI* aURI, + nsIDOMDocument* aDocument, + LPCTSTR filename, + nsIURI* aReferrer, + nsISupports* aDescriptor) +{ + // NEED better error handling + nsresult rv; + + nsEmbedCString contentType; + BOOL isHTML = FALSE; + + if (aDocument) + { + nsCOMPtr nsdoc = do_QueryInterface(aDocument); + NS_ENSURE_TRUE (nsdoc, NULL); + + nsEmbedString type; + rv = nsdoc->GetContentType(type); + NS_UTF16ToCString(type, NS_CSTRING_ENCODING_ASCII, contentType); + + const char* ctype = contentType.get(); + isHTML = + (strcmp(ctype, "text/html") == 0) || + (strcmp(ctype, "text/xml") == 0) || + (strcmp(ctype, "application/xhtml+xml") == 0) ; + } + + nsCOMPtr persist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID); + if (!persist) return FALSE; + + CSaveAsHandler* handler = new CSaveAsHandler(persist, aURI, aDocument, aDescriptor, aReferrer); + + if (filename) + { + // We have a filename. No need to ask the user for one. + rv = handler->DownloadTo(CStringToNSString(filename), FALSE); + } + else if (isHTML || + theApp.preferences.GetBool("kmeleon.download.disableContentSniffingOnSave", false)) + { + // No need to check the content type for an html document. + // The user may want to skip this step too. + rv = handler->Save(contentType.get()); + delete handler; + } + else + { + // Initiate a download only to get the content type. + // XXX Need to merge this with the standard download so that we can download + // in the background and ask for the location as soon as we have the content type. + + TCHAR tempFile[MAX_PATH]; + ::GetTempPath(MAX_PATH, tempFile); + ::GetTempFileName(tempFile, _T("kme"), 0, tempFile); + + nsCOMPtr file; +#ifdef _UNICODE + NS_NewLocalFile(nsDependentString(tempFile), TRUE, getter_AddRefs(file)); +#else + NS_NewNativeLocalFile(nsDependentCString(tempFile), TRUE, getter_AddRefs(file)); +#endif + + handler->SetTempFile(file); + persist->SetProgressListener(handler); + rv = persist->SaveURI(aURI, aDescriptor, aReferrer, nsnull, nsnull, file); + if (NS_FAILED(rv)) + persist->SetProgressListener(nsnull); + } + + // The user may have cancelled the download, in that case + // don't show an error. + return (NS_SUCCEEDED(rv) || rv == NS_ERROR_ABORT); +} + +BOOL CBrowserWrapper::InputHasFocus() +{ + nsCOMPtr element; + mWebBrowserFocus->GetFocusedElement(getter_AddRefs(element)); + if (!element) return FALSE; + + nsCOMPtr domnsinput = do_QueryInterface(element); + if (domnsinput) return TRUE; + + nsCOMPtr tansinput = do_QueryInterface(element); + if (tansinput) return TRUE; + + nsCOMPtr embed = do_QueryInterface(element); + if (embed) return TRUE; + + nsCOMPtr object = do_QueryInterface(element); + if (object) return TRUE; + + nsCOMPtr taFinder = do_GetService(NS_TYPEAHEADFIND_CONTRACTID); + if (taFinder) { + PRBool active = PR_FALSE; + taFinder->GetIsActive(&active); + if (active) return TRUE; + } + + return FALSE; +} + +CString CBrowserWrapper::GetFrameURL(nsIDOMNode* aNode) +{ + nsresult rv; + nsCOMPtr contextDocument; + + if (aNode) { + rv = aNode->GetOwnerDocument(getter_AddRefs(contextDocument)); + if (NS_FAILED(rv) || !contextDocument) return _T(""); + } + else { + nsCOMPtr dom; + mWebBrowserFocus->GetFocusedWindow(getter_AddRefs(dom)); + NS_ENSURE_TRUE(dom, _T("")); + + rv = dom->GetDocument(getter_AddRefs(contextDocument)); + NS_ENSURE_TRUE(contextDocument, _T("")); + } + + nsCOMPtr domWindow; + mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (NS_FAILED(rv) || !domWindow) + return _T(""); + + nsCOMPtr document; + rv = domWindow->GetDocument(getter_AddRefs(document)); + if (NS_FAILED(rv)) return _T(""); + + if(document == contextDocument) + return _T(""); + + nsCOMPtr nsDoc = do_QueryInterface(contextDocument); + NS_ENSURE_TRUE(nsDoc, _T("")); + + nsCOMPtr location; + nsDoc->GetLocation(getter_AddRefs(location)); + NS_ENSURE_TRUE(location, _T("")); + + nsEmbedString strFrameURL; + rv = location->GetHref(strFrameURL); + NS_ENSURE_SUCCESS(rv, _T("")); + + return NSStringToCString(strFrameURL); +} + +#ifndef FINDBAR_USE_TYPEAHEAD + +// This function collapse the current selection in +// the window and in frames. See below for its purpose. +// Have to look if we have frames. It's a little violent +// currently. The observer is also passing the root and +// not the frame so it's useless. + +void CBrowserWrapper::CollapseSelToStartInFrame(nsIDOMWindow* dom) +{ + NS_ENSURE_TRUE(dom, ); + + nsCOMPtr sel; + dom->GetSelection(getter_AddRefs(sel)); + if (sel) sel->CollapseToStart(); + + nsCOMPtr frames; + dom->GetFrames(getter_AddRefs(frames)); + if (frames) + { + PRUint32 nbframes; + frames->GetLength(&nbframes); + if (nbframes>0) + { + nsCOMPtr frame; + for (PRUint32 i = 0; iItem(i, getter_AddRefs(frame)); + CollapseSelToStartInFrame(frame); + } + } + } +} + +BOOL CBrowserWrapper::Find(const wchar_t* searchString, + BOOL matchCase, + BOOL wrapAround, + BOOL backwards, + BOOL ahead) +{ + nsCOMPtr finder = do_GetInterface(mWebBrowser); + NS_ENSURE_TRUE(finder, FALSE); + + // Not setting the search parameter when no searchString so that + // if a typeahead search is active, it will be used. + if (searchString) { + finder->SetSearchString(searchString); + finder->SetWrapFind(wrapAround); + finder->SetMatchCase(matchCase); + } + + finder->SetFindBackwards(backwards); + + // HACK because not use typeahead + // The problem with the autosearch feature is that + // webbrowserfind start to search at the end of the + // current selection. But with autosearch it should + // start at the beginning. So I collapse the selection. + if (ahead) { + nsCOMPtr dom; + mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + CollapseSelToStartInFrame(dom); + } + + PRBool didFind = PR_FALSE; + + finder->FindNext(&didFind); + return didFind; +} + +/* +BOOL CBrowserWrapper::Find(const wchar_t* searchString, BOOL ahead) +{ + nsCOMPTtr finder = do_GetInterface(mWebBrowser); + NS_ENSURE_TRUE(finder, FALSE); + + finder->SetSearchString(searchString); + + // HACK because not use typeahead + // The problem with the autosearch feature is that + // webbrowserfind start to search at the end of the + // current selection. But with autosearch it should + // start at the beginning. So I collapse the selection. + if (ahead) { + nsCOMPtr dom; + mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); + CollapseSelToStartInFrame(dom); + } + + return FindNext(FALSE); +} + +#else + +BOOL CBrowserWrapper::Find(const wchar_t* searchString, BOOL ahead) +{ + NS_ENSURE_TRUE(mFinder, FALSE); + mFinder->SetSearchString(searchString); + return FindNext(FALSE); +} +*/ +#endif +/* +BOOL CBrowserWrapper::FindNext(BOOL backward) +{ + NS_ENSURE_TRUE(mFinder, FALSE); + + PRBool didFind; + if (!backward) + mFinder->FindNext(&didFind); + else + { + mFinder->SetFindBackwards(PR_TRUE); + mFinder->FindNext(&didFind); + mFinder->SetFindBackwards(PR_FALSE); + } + + return didFind; +} + +void CBrowserWrapper::SetMatchCase(BOOL match) +{ + NS_ENSURE_TRUE(mFinder, ); + mFinder->SetMatchCase(match ? PR_TRUE : PR_FALSE); +} + +void CBrowserWrapper::SetWrapAround(BOOL wrap) +{ + NS_ENSURE_TRUE(mFinder, ); + mFinder->SetWrapFind(wrap ? PR_TRUE : PR_FALSE); +} + +// XXX +wchar_t* CBrowserWrapper::GetSearchString() +{ + NS_ENSURE_TRUE(mFinder, NULL); + nsEmbedString stringBuf; + mFinder->GetSearchString(getter_Copies(stringBuf)); + return wcsdup(stringBuf.get()); +} +*/ \ No newline at end of file diff --git a/k-meleon/BrowserWindow.h b/k-meleon/BrowserWindow.h new file mode 100644 index 00000000..963096ca --- /dev/null +++ b/k-meleon/BrowserWindow.h @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2006 Dorian Boissonnade + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#pragma once + +class nsIX509Cert; +#include "IBrowserFrameGlue.h" + +#include "nsICommandManager.h" +#include "nsIPrintSettings.h" +#include "nsIWebBrowserFind.h" +#include "nsIWebNavigation.h" +#include "nsIWebBrowserFocus.h" + +class CBrowserImpl; + +class CBrowserWrapper +{ +private: + nsCOMPtr mWebBrowser; + nsCOMPtr mBaseWindow; + nsCOMPtr mWebNav; + nsCOMPtr mWebBrowserFocus; + + nsCOMPtr mEventTarget; + //nsCOMPtr mDomEventListener; + nsCOMPtr mPrintSettings; + nsCOMPtr mLastMouseActionNode; + + + PRInt32 mChromeMask; + PBROWSERFRAMEGLUE mpBrowserFrameGlue; + PBROWSERGLUE mpBrowserGlue; + + BOOL mChromeContent; + CWnd* mWndOwner; + + BOOL mIsDocumentLoading; + BOOL mIsDOMLoaded; + +public: + CBrowserImpl* mpBrowserImpl; + CBrowserWrapper(void); + ~CBrowserWrapper(void); + + BOOL CreateBrowser(CWnd* parent, BOOL chromeContent = FALSE); + BOOL DestroyBrowser(); + CString GetTitle(); + CString GetURI(BOOL unescape = FALSE); + BOOL LoadURL(LPCTSTR url, BOOL currentForRef = FALSE, BOOL allowFixup = FALSE); + BOOL LoadURL(LPCTSTR url, LPCTSTR referrer, BOOL allowFixup = FALSE); + + CBrowserImpl *GetBrowserImpl() { return mpBrowserImpl; } + void SetBrowserFrameGlue(PBROWSERFRAMEGLUE pBrowserFrameGlue); + void SetBrowserGlue(PBROWSERGLUE pBrowserGlue); + void SetChromeMask(INT mask) { mChromeMask = mask; } + void SetPositionAndSize(int x, int y, int cx, int cy) { + if (mBaseWindow) mBaseWindow->SetPositionAndSize(0, 0, cx, cy, PR_TRUE); + } + void ShowScrollbars(BOOL visible); + BOOL ScrollBy(INT dx, INT dy); + + void GoBack() { if (mWebNav) mWebNav->GoBack(); } + void GoForward() { if (mWebNav) mWebNav->GoForward(); } + void Stop() { if(mWebNav) mWebNav->Stop(nsIWebNavigation::STOP_ALL); } + + BOOL Reload(BOOL force) + { + PRUint32 loadFlags = nsIWebNavigation::LOAD_FLAGS_NONE; + if (force) loadFlags = nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | + nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY; + nsresult rv = mWebNav->Reload(loadFlags); + return NS_SUCCEEDED(rv); + } + + BOOL CanGoBack() + { + PRBool ret = PR_FALSE; + if (mWebNav) mWebNav->GetCanGoBack(&ret); + return ret; + } + + BOOL CanGoForward() + { + PRBool ret = PR_FALSE; + if (mWebNav) mWebNav->GetCanGoForward(&ret); + return ret; + } + + BOOL CanCut() + { + PRBool ret = PR_FALSE; + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->CanCutSelection(&ret); + return ret; + } + + BOOL CanCopy() + { + PRBool ret = PR_FALSE; + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->CanCopySelection(&ret); + return ret; + } + + BOOL CanPaste() + { + PRBool ret = PR_FALSE; + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->CanPaste(&ret); + return ret; + } + + BOOL CanCopyImage() + { + PRBool ret = PR_FALSE; + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->CanCopyImageContents(&ret); + return ret; + } + + void Cut() + { + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->CutSelection(); + } + + void Copy() + { + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->CopySelection(); + } + + void Paste() + { + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->Paste(); + } + + void CopyImage() + { + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->CopyImageContents(); + } + + void SelectAll() + { + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->SelectAll(); + } + + void SelectNone() + { + nsCOMPtr clipCmds = do_GetInterface(mWebBrowser); + if (clipCmds) clipCmds->SelectNone(); + } + + void Undo() + { + nsCOMPtr commandMgr(do_GetInterface(mWebBrowser)); + if (commandMgr) commandMgr->DoCommand("cmd_undo", nsnull, nsnull); + } + + BOOL CanUndo() + { + PRBool ret = PR_FALSE; + nsCOMPtr commandMgr(do_GetInterface(mWebBrowser)); + if (commandMgr)commandMgr->IsCommandEnabled("cmd_undo", nsnull, &ret); + return ret; + } + + void GetCurrentURI(nsIURI** aURI) + { + nsCOMPtr uri; + mWebNav->GetCurrentURI(getter_AddRefs(uri)); + NS_IF_ADDREF(*aURI = uri); + } + + void GetReferringURI(nsIURI** aURI) + { + nsCOMPtr uri; + mWebNav->GetReferringURI(getter_AddRefs(uri)); + NS_IF_ADDREF(*aURI = uri); + } + + BOOL IsBusy() + { + nsCOMPtr docShell(do_GetInterface(mWebBrowser)); + NS_ENSURE_TRUE(docShell, FALSE); + + PRUint32 flags; + docShell->GetBusyFlags(&flags); + return flags != nsIDocShell::BUSY_FLAGS_NONE; + } + + void SetActive(BOOL aActive) + { + NS_ENSURE_TRUE(mWebBrowserFocus, ); + if (aActive) mWebBrowserFocus->Activate(); else mWebBrowserFocus->Deactivate(); + } + + void FocusFirstElement() + { + NS_ENSURE_TRUE(mWebBrowserFocus, ); + mWebBrowserFocus->Activate(); + mWebBrowserFocus->SetFocusAtFirstElement(); + } + + void FocusLastElement() + { + NS_ENSURE_TRUE(mWebBrowserFocus, ); + mWebBrowserFocus->Activate(); + mWebBrowserFocus->SetFocusAtLastElement(); + } + + already_AddRefed GetWebBrowser() + { + nsIWebBrowser* browser; + NS_IF_ADDREF(browser = mWebBrowser); + return browser; + } + + already_AddRefed GetContentWindow() + { + nsIDOMWindow* dom = nsnull; + if (mWebBrowser) mWebBrowser->GetContentDOMWindow(&dom); + return dom; + } + + NS_IMETHODIMP GetWebBrowser(nsIWebBrowser **aWebBrowser) + { + *aWebBrowser = mWebBrowser; + NS_IF_ADDREF(*aWebBrowser); + return NS_OK; + } + + int GetSecurityState(); + + BOOL GetCharset(char* aCharset); + BOOL ForceCharset(const char *aCharSet); + + BOOL Print(); + BOOL PrintPreview(); + BOOL InitPrintSettings(); + void PrintSetup(); + + BOOL IsPrintPreview() { + nsCOMPtr print(do_GetInterface(mWebBrowser)); + NS_ENSURE_TRUE(print, FALSE); + + PRBool isPreview = PR_FALSE; + nsresult rv = print->GetDoingPrintPreview(&isPreview); + return isPreview; + } + + BOOL SetTextSize(float textzoom); + float GetTextSize(); + BOOL ChangeTextSize(int change); + BOOL GetSHistory(nsISHistory **aSHistory); + BOOL CloneSHistory(CBrowserWrapper* newWebBrowser); + BOOL GotoHistoryIndex(UINT index); + BOOL GetSHistoryState(int& index, int& count); + BOOL GetSHistoryInfoAt(PRInt32 index, CString& title, CString& url); + + BOOL GetSelectionInsideForm(nsIDOMElement *element, nsEmbedString &aSelText); + BOOL GetSelection(CString&); + BOOL GetUSelection(nsEmbedString&); + BOOL InjectCSS(const wchar_t* userStyleSheet); + BOOL InjectJS(const wchar_t* userJS, bool bTopWindow = true); + BOOL GetSecurityInfo(CString &sign); + BOOL ShowCertificate(); + BOOL ViewContentContainsFrames(); + BOOL Highlight(const PRUnichar* backcolor, const PRUnichar* word, BOOL matchCase); + BOOL InputHasFocus(); + CString GetFrameURL(nsIDOMNode* aNode = NULL); + + already_AddRefed GetPageDescriptor(BOOL focus = FALSE); + BOOL CanSave(); + BOOL SaveURL(LPCTSTR url, LPCTSTR filename = NULL); + BOOL SaveDocument(BOOL frame, LPCTSTR filename = NULL); + BOOL Find(const wchar_t* searchString, + BOOL matchCase, + BOOL wrapAround, + BOOL backwards, + BOOL ahead); + +/* void SetMatchCase(BOOL); + void SetWrapAround(BOOL); + wchar_t* GetSearchString(); +#ifdef FINDBAR_USE_TYPEAHEAD +// BOOL Find(const wchar_t* searchString); +#else +// BOOL Find(const wchar_t* searchString, BOOL ahead); +#endif + //BOOL FindNext(BOOL backward);*/ + + +private: + BOOL AddListeners(void); + void RemoveListeners(void); + BOOL _GetSelection(nsIDOMWindow* dom, nsAString& aSelText); + BOOL _InjectCSS(nsIDOMWindow* dom, const wchar_t* userStyleSheet); + BOOL _Highlight(nsIDOMWindow* dom, const PRUnichar* backcolor, const PRUnichar* word, BOOL matchCase); + BOOL _Save(nsIURI* aURI, nsIDOMDocument* aDocument, LPCTSTR filename, nsIURI* aReferrer, nsISupports* aDescriptor); + BOOL GetCertificate(nsIX509Cert** certificate); + PRBool CheckNode(nsIDOMElement* elem); + +#ifndef FINDBAR_USE_TYPEAHEAD + void CollapseSelToStartInFrame(nsIDOMWindow* dom); +#endif +}; diff --git a/k-meleon/CmdLine.cpp b/k-meleon/CmdLine.cpp new file mode 100644 index 00000000..843c9555 --- /dev/null +++ b/k-meleon/CmdLine.cpp @@ -0,0 +1,187 @@ +// search for a switch in the command line +// return -1 if the switch is not found +// for separation purposes, we make the assumption that flags begin with a dash "-", +// but the "-" is still required in the pSwitch parameter +// otherwise return the number of characters in the argument after the flag +// if pArgs is a valid pointer, copy the argument data into it +// if bRemove is set, the flag (and it's argument, if pArgs is valid) will be removed + +#include "StdAfx.h" +#include "CmdLine.h" +#include "Utils.h" + +CCmdLine::CCmdLine() { + m_sProfilesDir = NULL; + m_bChrome = FALSE; +} + +CCmdLine::~CCmdLine() { + if (m_sProfilesDir) + delete m_sProfilesDir; +} + +void CCmdLine::Initialize(char *cmdLine) { + int len; + + m_sCmdLine = cmdLine; + + + if (GetSwitch("-chrome", NULL, true) > 0) + m_bChrome = TRUE; + + // -profilesDir + // or -profilesDir $appdata + len = GetSwitch("-profilesDir", NULL, false); + if (len == 0) // no arguments, invalid + GetSwitch("-profilesDir", NULL, true); // remove from command line + else if (len > 0) { + m_sProfilesDir = new char[len+1]; + GetSwitch("-profilesDir", m_sProfilesDir, true); + + if (!stricmp(m_sProfilesDir, "$appdata")) { + delete m_sProfilesDir; + m_sProfilesDir = new char[MAX_PATH]; + + ITEMIDLIST *idl; + if (SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &idl) == NOERROR) { + IMalloc *malloc; + SHGetPathFromIDListA(idl, m_sProfilesDir); + SHGetMalloc(&malloc); + malloc->Free(idl); + malloc->Release(); + } + else + GetWindowsDirectoryA(m_sProfilesDir, MAX_PATH); + int len = strlen(m_sProfilesDir); + if (m_sProfilesDir[len-1] != '\\') { + m_sProfilesDir[len] = '\\'; + m_sProfilesDir[len+1] = 0; + } + strcat(m_sProfilesDir, "K-Meleon"); + } + } +} + +int CCmdLine::GetSwitch(const char *pSwitch, char *pArgs, BOOL bRemove) { + + char *p, *c; + char *pQuote; + char *pSwitchPos; + char *pCmdLine; + char *pArgStart, *pArgEnd; + int iQuoteCount; + BOOL bIsValidSwitch; + int iSwitchLen, iArgLen=0; + + if ( !pSwitch || !*pSwitch ) + return -1; + else + iSwitchLen = strlen(pSwitch); + + p = pCmdLine = SkipWhiteSpace(m_sCmdLine); + do { + bIsValidSwitch = FALSE; + + if ( ((!p) || (!*p)) || !(pSwitchPos = strstr(p, pSwitch)) ) { + if (pArgs) *pArgs = 0; + return -1; + } + p = SkipWhiteSpace(pSwitchPos + iSwitchLen); + + // if this happens to be the first character on the command line, + // then we don't need to do any error checking + if (pSwitchPos == pCmdLine) + bIsValidSwitch = TRUE; + + // make sure the flag is preceeded by whitespace + else if ( (*(pSwitchPos-1) != ' ') && (*(pSwitchPos-1) != '\t') ) + continue; + + // make sure the character after the flag is whitespace or null + else if ( (*(pSwitchPos+iSwitchLen) != ' ') && (*(pSwitchPos+iSwitchLen) != '\t') && (*(pSwitchPos+iSwitchLen) != 0) ) + continue; + + // if the "argument" starts with a dash, it's another switch, and this + // switch has no argument + else if (*p == '-') { + *pArgs = 0; + return 0; + } + + // make sure the switch we've found isn't inside quotation marks + else { + c = pCmdLine; + iQuoteCount = 0; + do { + pQuote = strchr(c, '\"'); + if (pQuote) { + if ( !( *(pQuote-1) == '\\') ) + iQuoteCount++; + c = pQuote+1; + } + } while ( pQuote && (pQuote < pSwitchPos) ); + + // there are 3 cases when the switch found will be valid + // 1) if there are the no quotes found before the switch + // 2) if there an odd number of quotes found, and the last quote is found after the switch + // 3) if there are an even number of quotes found, and no quotes after the switch + + if ( (iQuoteCount == 0) || \ + ((pQuote) && (iQuoteCount%2)) || \ + ((!pQuote) && (!(iQuoteCount%2))) ) + bIsValidSwitch = TRUE; + } + } while (pSwitchPos && !bIsValidSwitch); + + if (pSwitchPos && bIsValidSwitch) { + pArgStart = SkipWhiteSpace(p); + + // check if the argument is inside quotes + if (*pArgStart == '\"') { + pArgStart++; + pArgEnd = strchr(pArgStart, '\"'); + } + + // find the first whitespace + else { + char *pTab = strchr(pArgStart, '\t'); + char *pSpace = strchr(pArgStart, ' '); + + if (pTab && pSpace) + pArgEnd = ( pTab > pSpace ? pSpace : pTab ); + else + pArgEnd = ( pTab ? pTab : pSpace ); + } + + if (pArgEnd) + iArgLen = pArgEnd-pArgStart; + else + iArgLen = strlen(pArgStart); + + if (pArgs) { + if (iArgLen) { + memcpy(pArgs, pArgStart, iArgLen); + pArgs[iArgLen] = 0; + } + else + *pArgs = 0; + } + + if (bRemove) { + char *pNewData; + if (pArgs) + pNewData = pArgEnd ? pArgEnd+1 : pArgStart + iArgLen; + else + pNewData = pSwitchPos + iSwitchLen; + + pNewData = SkipWhiteSpace(pNewData); + while (*pNewData) + *pSwitchPos++ = *pNewData++; + *pSwitchPos = 0; + } + + } + + return iArgLen; +} + diff --git a/k-meleon/CmdLine.h b/k-meleon/CmdLine.h new file mode 100644 index 00000000..152d512e --- /dev/null +++ b/k-meleon/CmdLine.h @@ -0,0 +1,12 @@ +class CCmdLine { + +public: + CCmdLine(); + ~CCmdLine(); + void Initialize(char *cmdLine); + int GetSwitch(const char *pSwitch, char *pArgs, BOOL bRemove); + + char *m_sProfilesDir; + char *m_sCmdLine; + BOOL m_bChrome; +}; \ No newline at end of file diff --git a/k-meleon/Components.cpp b/k-meleon/Components.cpp new file mode 100644 index 00000000..dcff23cc --- /dev/null +++ b/k-meleon/Components.cpp @@ -0,0 +1,174 @@ +/* Some Gecko interfaces are implemented as components, automatically +registered at application initialization. nsIPrompt is an example: +the default implementation uses XUL, not native windows. Embedding +apps can override the default implementation by implementing the +nsIPromptService interface and registering a factory for it with +the same CID and Contract ID as the default's. +*/ + +#include "stdafx.h" +#include "mfcembed.h" +#include "UnknownContentTypeHandler.h" +#include "PromptService.h" +#include "CookiePromptService.h" +//#include "TooltipsProvider.h" +#include "NSSDialogs.h" +#if GECKO_VERSION < 19 +#include "FontPackageHandler.h" +#endif +#include "GenKeyPairDialogs.h" +//#include "SideBarComp.h" + +#include "nsIComponentRegistrar.h" +#include "nsICategoryManager.h" +#include "nsIComponentManager.h" + +//#include "nsEmbedCID.h" //NS_PROMPTSERVICE_CONTRACTID +//#include "nsICookiePromptService.h" ////NS_COOKIEPROMPTSERVICE_CONTRACTID +//#include "nsIHelperAppLauncherDialog.h" //NS_IHELPERAPPLAUNCHERDLG_CONTRACTID +//#include "nsICertificateDialogs.h" //NS_CERTIFICATEDIALOGS_CONTRACTID +//#include "nsIBadCertListener.h" //NS_BADCERTLISTENER_CONTRACTID +//#include "nsCTooltipTextProvider.h" //NS_TOOLTIPTEXTPROVIDER_CONTRACTID + +NS_GENERIC_FACTORY_CONSTRUCTOR(CPromptService) +NS_GENERIC_FACTORY_CONSTRUCTOR(CCookiePromptService) +NS_GENERIC_FACTORY_CONSTRUCTOR(CUnknownContentTypeHandler) +//NS_GENERIC_FACTORY_CONSTRUCTOR(CTooltipTextProvider) +NS_GENERIC_FACTORY_CONSTRUCTOR(CNSSDialogs) +NS_GENERIC_FACTORY_CONSTRUCTOR(CProgressDialog) +#if GECKO_VERSION < 19 +NS_GENERIC_FACTORY_CONSTRUCTOR(CFontPackageHandler) +#endif +NS_GENERIC_FACTORY_CONSTRUCTOR(CGenKeyPairDialogs) +//NS_GENERIC_FACTORY_CONSTRUCTOR(CSideBarComp) + +/*NS_DECL_CLASSINFO(CSideBarComp) + +static NS_METHOD +RegisterSidebar(nsIComponentManager *aCompMgr, nsIFile *aPath, + const char *registryLocation, const char *componentType, + const nsModuleComponentInfo *info) +{ + nsCOMPtr cm = + do_GetService(NS_CATEGORYMANAGER_CONTRACTID); + NS_ENSURE_TRUE (cm, NS_ERROR_FAILURE); + + return cm->AddCategoryEntry("JavaScript global property", + "sidebar", NS_SIDEBAR_CONTRACTID, + PR_FALSE, PR_TRUE, nsnull); +}*/ + +static const nsModuleComponentInfo sAppComps[] = { + { + "Prompt Service", + NS_PROMPTSERVICE_CID, + NS_PROMPTSERVICE_CONTRACTID, + CPromptServiceConstructor + }, + { + "Nonblocking Alert Service", + NS_PROMPTSERVICE_CID, + NS_NONBLOCKINGALERTSERVICE_CONTRACTID, + CPromptServiceConstructor + }, + { + "Helper App Launcher Dialog", + NS_UNKNOWNCONTENTTYPEHANDLER_CID, + NS_IHELPERAPPLAUNCHERDLG_CONTRACTID, + CUnknownContentTypeHandlerConstructor + }, + /*{ + "Tooltip Text Provider", + NS_TOOLTIPTEXTPROVIDER_CID, + NS_TOOLTIPTEXTPROVIDER_CONTRACTID, + CTooltipTextProviderConstructor + },*/ + { + "Cookie Prompt Service", + NS_COOKIEPROMPTSERVICE_CID, + NS_COOKIEPROMPTSERVICE_CONTRACTID, + CCookiePromptServiceConstructor + }, +#if GECKO_VERSION < 19 + { + "PSM Dialog Impl", + NS_NSSDIALOGS_CID, + NS_BADCERTLISTENER_CONTRACTID, + CNSSDialogsConstructor + }, + { "nsFontPackageHandler", + NS_FONTPACKAGEHANDLER_CID, + "@mozilla.org/locale/default-font-package-handler;1", + CFontPackageHandlerConstructor + }, +#endif + { + "PSM Dialog Impl", + NS_NSSDIALOGS_CID, + NS_CERTIFICATEDIALOGS_CONTRACTID, + CNSSDialogsConstructor + }, + { + GTK_NSSKEYPAIRDIALOGS_CLASSNAME, + NS_NSSKEYPAIRDIALOGS_CID, + NS_GENERATINGKEYPAIRINFODIALOGS_CONTRACTID, + CGenKeyPairDialogsConstructor + }, + { + "Download", + NS_DOWNLOAD_CID, + NS_TRANSFER_CONTRACTID, + CProgressDialogConstructor + } + /*, + { + "nsSideBar", + NS_SIDEBAR_CID, + NS_SIDEBAR_CONTRACTID, + CSideBarCompConstructor, + RegisterSidebar, + nsnull, + nsnull, + NS_CI_INTERFACE_GETTER_NAME(CSideBarComp), + nsnull, + &NS_CLASSINFO_NAME(CSideBarComp), + nsIClassInfo::DOM_OBJECT + }*/ +}; + +#define NB_COMPONENTS sizeof(sAppComps)/sizeof(nsModuleComponentInfo) + +extern NS_COM_GLUE nsresult NS_NewGenericFactory(nsIGenericFactory* *result, + const nsModuleComponentInfo *info); + +nsresult CMfcEmbedApp::OverrideComponents() +{ + nsCOMPtr compReg; + nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(compReg)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr compManager; + rv = NS_GetComponentManager(getter_AddRefs(compManager)); + NS_ENSURE_SUCCESS(rv, rv); + + for (int i=0; i componentFactory; + rv = NS_NewGenericFactory(getter_AddRefs(componentFactory), &(sAppComps[i])); + if (NS_FAILED(rv) || !componentFactory) + { + AfxMessageBox(IDS_UNABLE_REGISTER_FACTORY, MB_OK, 0); + continue; + } + + rv = compReg->RegisterFactory(sAppComps[i].mCID, + sAppComps[i].mDescription, + sAppComps[i].mContractID, + componentFactory); + + if (sAppComps[i].mRegisterSelfProc) + rv = sAppComps[i].mRegisterSelfProc(compManager, nsnull, nsnull, nsnull, &sAppComps[i]); + } + + return rv; +} diff --git a/k-meleon/CookiePromptService.cpp b/k-meleon/CookiePromptService.cpp new file mode 100644 index 00000000..282407f5 --- /dev/null +++ b/k-meleon/CookiePromptService.cpp @@ -0,0 +1,149 @@ +/* +* +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* +*/ + +#include "stdafx.h" +#include "CookiePromptService.h" +#include "nsICookieAcceptDialog.h" +#include "nsICookie.h" +#include "Cookies.h" +#include "MozUtils.h" + + +extern CWnd* CWndForDOMWindow(nsIDOMWindow *aWindow); + +NS_IMPL_ISUPPORTS1(CCookiePromptService, nsICookiePromptService) + +CCookiePromptService::CCookiePromptService(){ +} + +CCookiePromptService::~CCookiePromptService() { +} + +NS_IMETHODIMP CCookiePromptService::CookieDialog(nsIDOMWindow *parent, nsICookie *aCookie, const nsACString & hostname, PRInt32 cookiesFromHost, PRBool changingCookie, PRBool *rememberDecision, PRInt32 *_retval) +{ + NS_ENSURE_ARG_POINTER(aCookie); + + CString q; + static BOOL accept = TRUE; + CString host = NSUTF8StringToCString(nsEmbedCString(hostname)); + + if (changingCookie) + q.Format(IDS_COOKIE_MODIFY, host); + else if (cookiesFromHost == 0) + q.Format(IDS_COOKIE_SET, host); + else if (cookiesFromHost == 1) + q.Format(IDS_COOKIE_SET2, host); + else + q.Format(IDS_COOKIE_ANOTHER, host, cookiesFromHost); + + HWND activeWnd = GetActiveWindow(); + CWnd *wnd = CWndForDOMWindow(parent); + CConfirmCookieDialog dlg(wnd, q, accept); + + CCookie* cookie = new CCookie(aCookie); + dlg.m_csName = cookie->m_csName; + dlg.m_csValue = cookie->m_csValue; + dlg.m_csHost = cookie->m_csHost; + dlg.m_csPath = cookie->m_csPath; + dlg.m_csExpires = cookie->m_csExpire; + + if (cookie->m_secure) + dlg.m_csSendFor.LoadString(IDS_FOR_SECURE); + else + dlg.m_csSendFor.LoadString(IDS_FOR_ANY); + + *_retval = dlg.DoModal(); + accept = *rememberDecision = dlg.m_bCheckBoxValue; + delete cookie; + + SetForegroundWindow(activeWnd); + return NS_OK; +} + +// Boîte de dialogue CConfimCookieDialog + +//IMPLEMENT_DYNAMIC(CConfirmCookieDialog, CDialog) +CConfirmCookieDialog::CConfirmCookieDialog(CWnd* pParent, const TCHAR* pText, BOOL bAcceptSite) +: CDialog(CConfirmCookieDialog::IDD, pParent) +{ + if(pText) + m_csText = pText; + m_bCheckBoxValue = bAcceptSite; +} + +CConfirmCookieDialog::~CConfirmCookieDialog() +{ +} + +void CConfirmCookieDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAlertCheckDialog) + DDX_Check(pDX, IDC_CHECK_REMEMBER, m_bCheckBoxValue); + DDX_Text(pDX, IDC_COOKIE_TEXT, m_csText); + DDX_Text(pDX, IDC_COOKIE_NAME, m_csName); + DDX_Text(pDX, IDC_COOKIE_HOST, m_csHost); + DDX_Text(pDX, IDC_COOKIE_PATH, m_csPath); + DDX_Text(pDX, IDC_COOKIE_SENDFOR, m_csSendFor); + DDX_Text(pDX, IDC_COOKIE_EXPIRES, m_csExpires); + DDX_Text(pDX, IDC_COOKIE_VALUE, m_csValue); + DDX_Control(pDX, IDC_COOKIE_ICON, m_bIcon); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CConfirmCookieDialog, CDialog) + ON_BN_CLICKED(IDALLOWSESSION, OnBnClickedAllowsession) + ON_BN_CLICKED(IDDENY, OnBnClickedDeny) + ON_BN_CLICKED(IDALLOW, OnBnClickedAllow) + ON_WM_CLOSE() +END_MESSAGE_MAP() + +BOOL CConfirmCookieDialog::OnInitDialog() +{ + CDialog::OnInitDialog(); + HICON icon = (HICON)LoadImage(0,MAKEINTRESOURCE(32514),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED); + m_bIcon.SetIcon(icon); + return TRUE; +} + +void CConfirmCookieDialog::OnBnClickedAllowsession() +{ + UpdateData(); + EndDialog(nsICookiePromptService::ACCEPT_SESSION_COOKIE); +} + +void CConfirmCookieDialog::OnBnClickedDeny() +{ + UpdateData(); + EndDialog(nsICookiePromptService::DENY_COOKIE); +} + +void CConfirmCookieDialog::OnBnClickedAllow() +{ + UpdateData(); + EndDialog(nsICookiePromptService::ACCEPT_COOKIE); +} + +void CConfirmCookieDialog::OnClose() +{ + m_bCheckBoxValue = false; + EndDialog(nsICookiePromptService::DENY_COOKIE); +} diff --git a/k-meleon/CookiePromptService.h b/k-meleon/CookiePromptService.h new file mode 100644 index 00000000..2b98e857 --- /dev/null +++ b/k-meleon/CookiePromptService.h @@ -0,0 +1,81 @@ +/* +* +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* +*/ +#pragma once + +#include "nsICookiePromptService.h" +#include "resource.h" +#include "DialogEx.h" + +#ifndef XP_WIN +#define XP_WIN +#endif + +#define NS_COOKIEPROMPTSERVICE_CID \ + {0xCE002B28, 0x92B7, 0x4701, {0x86, 0x21, 0xCC, 0x92, 0x58, 0x66, 0xFB, 0x87}} +static NS_DEFINE_CID(kPromptCookieServiceCID, NS_COOKIEPROMPTSERVICE_CID); + + +class CCookiePromptService: public nsICookiePromptService + +{ +public: + CCookiePromptService(); + virtual ~CCookiePromptService(); + + NS_DECL_ISUPPORTS + NS_DECL_NSICOOKIEPROMPTSERVICE + + }; + + +// Boîte de dialogue CConfirmCookieDialog + +class CConfirmCookieDialog : public CDialog +{ + //DECLARE_DYNAMIC(CConfirmCookieDialog) + +public: + CConfirmCookieDialog::CConfirmCookieDialog(CWnd* pParent, const TCHAR* pText, BOOL bAcceptSite); + virtual ~CConfirmCookieDialog(); + int m_bCheckBoxValue; + CString m_csMsg, + m_csName, + m_csValue, + m_csHost, + m_csPath, + m_csExpires, + m_csSendFor; + CStatic m_bIcon; + +// Données de boîte de dialogue + enum { IDD = IDD_CONFIRM_COOKIE }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // Prise en charge DDX/DDV + CString m_csText; + + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); + afx_msg void OnBnClickedAllowsession(); + afx_msg void OnBnClickedDeny(); + afx_msg void OnBnClickedAllow(); + afx_msg void OnClose(); +}; diff --git a/k-meleon/Cookies.h b/k-meleon/Cookies.h new file mode 100644 index 00000000..a9c3baff --- /dev/null +++ b/k-meleon/Cookies.h @@ -0,0 +1,88 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include "nsICookie.h" +#include "nsEmbedString.h" +#include "resource.h" + +class CCookie { + +public: + nsEmbedCString m_host; + nsEmbedCString m_name; + nsEmbedCString m_path; + CString m_csHost; + CString m_csName; + CString m_csValue; + CString m_csPath; + CString m_csExpire; + BOOL m_secure; + + + CCookie(nsICookie* cookie) + { + if (cookie) { + + USES_CONVERSION; + + cookie->GetName(m_name); + m_csName = A2CT(m_name.get()); + + nsEmbedCString str; + cookie->GetValue(str); + m_csValue = A2CT(str.get()); + + cookie->GetHost(m_host); + nsEmbedString _str; + NS_CStringToUTF16(m_host, NS_CSTRING_ENCODING_UTF8, _str); + m_csHost = W2CT(_str.get()); + + cookie->GetPath(m_path); + m_csPath = A2CT(m_path.get()); + + PRBool bIsSecure; + cookie->GetIsSecure(&bIsSecure); + m_secure = (bIsSecure == PR_TRUE); + + /*if (bIsSecure == PR_TRUE) + dlg.m_csSendFor.LoadString(IDS_FOR_SECURE); + else + dlg.m_csSendFor.LoadString(IDS_FOR_ANY);*/ + + PRUint64 expires; + cookie->GetExpires(&expires); + if (expires>0){ + char fDate[128]; + tm* tmTime = localtime ((time_t*)&expires); + if (tmTime) + { + strftime (fDate, sizeof(fDate)-1, "%a %d %b %Y %H:%M", tmTime); + m_csExpire = fDate; + } + } + else + m_csExpire.LoadString(IDS_ESPIRES_EOS); + } + } + + ~CCookie() + { + } + +}; diff --git a/k-meleon/CookiesViewerDlg.cpp b/k-meleon/CookiesViewerDlg.cpp new file mode 100644 index 00000000..b12016d7 --- /dev/null +++ b/k-meleon/CookiesViewerDlg.cpp @@ -0,0 +1,249 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include "stdafx.h" +#include "CookiesViewerDlg.h" +#include "Cookies.h" + +// Boîte de dialogue CCookiesViewerDlg + +//IMPLEMENT_DYNAMIC(CCookiesViewerDlg, CDialog) +CCookiesViewerDlg::CCookiesViewerDlg(CWnd* pParent /*=NULL*/) + : CDialog(CCookiesViewerDlg::IDD, pParent) +{ + m_cookieManager = do_GetService(NS_COOKIEMANAGER_CONTRACTID); +} + +CCookiesViewerDlg::~CCookiesViewerDlg() +{ +} + +void CCookiesViewerDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST_COOKIES, m_cCookiesList); +} + + +BEGIN_MESSAGE_MAP(CCookiesViewerDlg, CDialog) + ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_COOKIES, OnLvnItemchangedListCookies) + ON_BN_CLICKED(IDC_DELETE_ALL_COOKIES, OnBnClickedDeleteAllCookies) + ON_BN_CLICKED(IDC_DELETE_COOKIES, OnBnClickedDeleteCookies) + ON_EN_CHANGE(IDC_COOKIE_SEARCH, OnEnChangeCookieSearch) + ON_WM_DESTROY() +END_MESSAGE_MAP() + + +// Gestionnaires de messages CCookiesViewerDlg +int CALLBACK CCookiesViewerDlg::SortCookiesList(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + //CListCtrl* pListCtrl = (CListCtrl*) lParamSort; + CCookieList* pCookieList = (CCookieList*) lParamSort; + + CCookie* cookie1 = pCookieList->GetAt((POSITION)lParam1); + CCookie* cookie2 = pCookieList->GetAt((POSITION)lParam2); + + return cookie1->m_csHost.Compare(cookie2->m_csHost); +} + +BOOL CCookiesViewerDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + nsresult rv; + + nsCOMPtr enumCookie; + rv = m_cookieManager->GetEnumerator(getter_AddRefs(enumCookie)); + if (NS_FAILED(rv)) + { + AfxMessageBox(_T("Failed to get the cookie manager")); + return TRUE; + } + + CString header; + header.LoadString(IDS_HEADER_SITE); + m_cCookiesList.InsertColumn(0, header, LVCFMT_LEFT, 0, 0); + header.LoadString(IDS_HEADER_NAME); + m_cCookiesList.InsertColumn(1, header, LVCFMT_LEFT, 0, 1); + + m_cCookiesList.SetExtendedStyle(LVS_EX_FULLROWSELECT); + + PRBool ret; + LVITEM lvItem; + lvItem.mask = LVIF_PARAM; + lvItem.iSubItem = 0; + lvItem.state = 0; + lvItem.stateMask = 0; + lvItem.pszText = 0; + lvItem.iItem = 0xffff; + + enumCookie->HasMoreElements(&ret); + while (ret) + { + nsCOMPtr nsCookie; + rv = enumCookie->GetNext(getter_AddRefs(nsCookie)); + if (NS_FAILED(rv)) break; + + CCookie* cookie = new CCookie(nsCookie); + POSITION p = m_CookiesList.AddHead(cookie); + + lvItem.lParam = (LPARAM)p; + int index = m_cCookiesList.InsertItem(&lvItem); + + if (index==-1) continue; + + ListView_SetItemText(m_cCookiesList.GetSafeHwnd(), index, 0, cookie->m_csHost.GetBuffer(0)) + ListView_SetItemText(m_cCookiesList.GetSafeHwnd(), index, 1, cookie->m_csName.GetBuffer(0)) + + enumCookie->HasMoreElements(&ret); + } + + // Set the column width, I'm doing it after inserting cookies in the list + // because of the scrollbar + RECT rect; + m_cCookiesList.GetClientRect(&rect); + int width = (rect.right - rect.left)/2; + m_cCookiesList.SetColumnWidth(0, width); + m_cCookiesList.SetColumnWidth(1, width); + + m_cCookiesList.SortItems(SortCookiesList, (LPARAM) &m_CookiesList); + + return TRUE; // return TRUE unless you set the focus to a control +} + + +void CCookiesViewerDlg::OnLvnItemchangedListCookies(NMHDR *pNMHDR, LRESULT *pResult) +{ + LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + if (m_cCookiesList.GetSelectedCount()!=1) + { + SetDlgItemText(IDC_COOKIE_TEXT, _T("")); + SetDlgItemText(IDC_COOKIE_NAME, _T("")); + SetDlgItemText(IDC_COOKIE_HOST, _T("")); + SetDlgItemText(IDC_COOKIE_PATH, _T("")); + SetDlgItemText(IDC_COOKIE_SENDFOR, _T("")); + SetDlgItemText(IDC_COOKIE_EXPIRES, _T("")); + SetDlgItemText(IDC_COOKIE_VALUE, _T("")); + } + else + { + int nItem = m_cCookiesList.GetNextItem(-1, LVNI_SELECTED); + LPARAM lp = m_cCookiesList.GetItemData(nItem); + if (lp == -1) return; + + POSITION p = (POSITION)lp; + CCookie* cookie = m_CookiesList.GetAt(p); + + SetDlgItemText(IDC_COOKIE_NAME, cookie->m_csName); + SetDlgItemText(IDC_COOKIE_HOST, cookie->m_csHost); + SetDlgItemText(IDC_COOKIE_PATH, cookie->m_csPath); + SetDlgItemText(IDC_COOKIE_EXPIRES, cookie->m_csExpire); + SetDlgItemText(IDC_COOKIE_VALUE, cookie->m_csValue); + + CString str; + if (cookie->m_secure) + str.LoadString(IDS_FOR_SECURE); + else + str.LoadString(IDS_FOR_ANY); + + SetDlgItemText(IDC_COOKIE_SENDFOR, str); + } + + // TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle + *pResult = 0; +} + +void CCookiesViewerDlg::OnBnClickedDeleteAllCookies() +{ + if (AfxMessageBox(IDS_CONFIRM_DELETEALLCOOKIES, MB_OKCANCEL | MB_ICONWARNING) == IDOK) + { + nsresult rv = m_cookieManager->RemoveAll(); + if (NS_FAILED(rv)) + { + AfxMessageBox(IDS_FAILED_DELETE_COOKIE,MB_OK|MB_ICONERROR); + return; + } + + m_cCookiesList.DeleteAllItems(); + + while (!m_CookiesList.IsEmpty()) + { + delete(m_CookiesList.GetHead()); + m_CookiesList.RemoveHead(); + } + } +} + +void CCookiesViewerDlg::OnBnClickedDeleteCookies() +{ + UINT uSelectedCount = m_cCookiesList.GetSelectedCount(); + int nItem = -1; + nsresult rv; + + if (uSelectedCount>0) + { + UINT i; + for (i=0;i < uSelectedCount;i++) + { + nItem = m_cCookiesList.GetNextItem(nItem, LVNI_SELECTED); + ASSERT(nItem != -1); + POSITION p = (POSITION)m_cCookiesList.GetItemData(nItem); + CCookie* cookie = m_CookiesList.GetAt(p); + + PRBool blocked = IsDlgButtonChecked(IDC_ALLOW_DELETED) ? PR_TRUE : PR_FALSE; + rv = m_cookieManager->Remove(cookie->m_host, cookie->m_name, cookie->m_path, blocked); + if (NS_FAILED(rv)) + { + AfxMessageBox(IDS_FAILED_DELETE_COOKIE,MB_OK|MB_ICONERROR); + return; + } + + m_CookiesList.RemoveAt(p); + delete cookie; + } + + for (i=0;i < uSelectedCount;i++) + { + nItem = m_cCookiesList.GetNextItem(-1, LVNI_SELECTED); + m_cCookiesList.DeleteItem(nItem); + } + } +} + +void CCookiesViewerDlg::OnEnChangeCookieSearch() +{ + LVFINDINFO info = {0}; + info.flags = LVFI_PARTIAL; + + CString csSearch; + GetDlgItemText(IDC_COOKIE_SEARCH, csSearch); + info.psz = csSearch.GetBuffer(0); + + int nIndex = m_cCookiesList.FindItem(&info, -1); + m_cCookiesList.EnsureVisible(nIndex, FALSE); +} + +void CCookiesViewerDlg::OnDestroy() +{ + CDialog::OnDestroy(); + while (!m_CookiesList.IsEmpty()) + { + delete(m_CookiesList.GetHead()); + m_CookiesList.RemoveHead(); + } +} diff --git a/k-meleon/CookiesViewerDlg.h b/k-meleon/CookiesViewerDlg.h new file mode 100644 index 00000000..fc4f63fe --- /dev/null +++ b/k-meleon/CookiesViewerDlg.h @@ -0,0 +1,63 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#pragma once + +#include "resource.h" +#include "afxtempl.h" +#include "DialogEx.h" + +#include "nsICookieManager.h" +#include "nsICookie.h" + +class CCookie; + +typedef CList CCookieList; + +// Boîte de dialogue CCookiesViewerDlg + +class CCookiesViewerDlg : public CDialog +{ + //DECLARE_DYNAMIC(CCookiesViewerDlg) + +public: + CCookiesViewerDlg(CWnd* pParent = NULL); // constructeur standard + virtual ~CCookiesViewerDlg(); + + static int CALLBACK SortCookiesList(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); + +// Données de boîte de dialogue + enum { IDD = IDD_COOKIES_VIEWER }; + +protected: + CCookieList m_CookiesList; + nsCOMPtr m_cookieManager; + + virtual void DoDataExchange(CDataExchange* pDX); // Prise en charge DDX/DDV + DECLARE_MESSAGE_MAP() + +public: + CListCtrl m_cCookiesList; + virtual BOOL OnInitDialog(); + afx_msg void OnLvnItemchangedListCookies(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedDeleteAllCookies(); + afx_msg void OnBnClickedDeleteCookies(); + afx_msg void OnEnChangeCookieSearch(); + afx_msg void OnDestroy(); +}; diff --git a/k-meleon/DialogEx.h b/k-meleon/DialogEx.h new file mode 100644 index 00000000..eaa792c7 --- /dev/null +++ b/k-meleon/DialogEx.h @@ -0,0 +1,126 @@ +// This class is just here so I can change some settings +// in the template, using the font set in the control +// panel for the dialogs + +#ifndef _DIALOGS_EX_H_ +#define _DIALOGS_EX_H_ + +#include "afxpriv.h" + +class CDialogTemplateEx: public CDialogTemplate +{ +public: + int SetTemplate(const DLGTEMPLATE *pTemplate) { + return CDialogTemplate::SetTemplate(pTemplate, GetTemplateSize(pTemplate)); + } +}; + +class CDialogEx: public CDialog +{ +public: + + CDialogEx() : CDialog() {}; + CDialogEx(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL) + : CDialog(lpszTemplateName, pParentWnd) {}; + CDialogEx(UINT nIDTemplate, CWnd* pParentWnd = NULL) + : CDialog(nIDTemplate, pParentWnd) {}; + ~CDialogEx() {}; + + INT DoModal() + { + //CMfcEmbedApp *pApp = (CMfcEmbedApp *)AfxGetApp(); + //if (pApp->preferences.GetBool("kmeleon.display.dialogs.useUserDialogFont", true)) { + // return CDialog::DoModal(); + //} + + ASSERT(m_lpszTemplateName != NULL || m_lpDialogTemplate != NULL); + if (m_lpszTemplateName != NULL) { + if (!m_dlt.Load(m_lpszTemplateName)) + return -1; + } + else + if (!m_dlt.SetTemplate(m_lpDialogTemplate)) + return -1; + + struct font_info font; + if (GetMessageFont(font)) + m_dlt.SetFont(font.lpFaceName, (WORD)font.nPointSize); + + LPSTR pdata = (LPSTR)GlobalLock(m_dlt.m_hTemplate); + + m_lpszTemplateName = NULL; + m_lpDialogTemplate = NULL; + InitModalIndirect(pdata); + + INT result = CDialog::DoModal(); + + GlobalUnlock(m_dlt.m_hTemplate); + + return result; + } + + BOOL Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd) + { + ASSERT(m_lpszTemplateName == NULL); + if (!m_dlt.Load(lpszTemplateName)) return FALSE; + struct font_info font; + if ( + //pApp->preferences.GetBool("kmeleon.display.dialogs.useUserFont", true) && + GetMessageFont(font)) + m_dlt.SetFont(font.lpFaceName, (WORD)font.nPointSize); + + HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG); + + return CDialog::CreateIndirect(m_dlt.m_hTemplate, pParentWnd, hInst); + } + + BOOL Create(UINT nIDTemplate, CWnd* pParentWnd) + { + return Create(MAKEINTRESOURCE(nIDTemplate), pParentWnd); + } + + BOOL CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd = NULL) + { + if (!m_dlt.SetTemplate(lpDialogTemplate)) + return FALSE; + + struct font_info font; + if (GetMessageFont(font)) + m_dlt.SetFont(font.lpFaceName, (WORD)font.nPointSize); + + return CDialog::CreateIndirect(m_dlt.m_hTemplate, pParentWnd); + } + +protected: + CDialogTemplateEx m_dlt; + + struct font_info { + int nPointSize; + CString lpFaceName; + }; + + BOOL GetMessageFont(struct font_info &fi) + { + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&ncm,0)) + return FALSE; + + LOGFONT &lf = ncm.lfMessageFont; + + if (lf.lfHeight < 0) + lf.lfHeight = -lf.lfHeight; + + HDC hDC = ::GetDC(NULL); + fi.nPointSize = MulDiv(lf.lfHeight,72,GetDeviceCaps(hDC, LOGPIXELSY)); + ::ReleaseDC(NULL,hDC); + + fi.lpFaceName = lf.lfFaceName; + + return TRUE; + } +}; + +#define CDialog CDialogEx + +#endif \ No newline at end of file diff --git a/k-meleon/DialogUtils.cpp b/k-meleon/DialogUtils.cpp new file mode 100644 index 00000000..06342ef3 --- /dev/null +++ b/k-meleon/DialogUtils.cpp @@ -0,0 +1,186 @@ +#include +#include "DialogUtils.h" + +inline BOOL IsDialogEx(const DLGTEMPLATE* pTemplate) +{ + return ((DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF; +} + +inline int FontAttrSize(BOOL bDialogEx) +{ + return (int)sizeof(WORD) * (bDialogEx ? 3 : 1); +} + +inline BOOL HasFont(const DLGTEMPLATE* pTemplate) +{ + return (DS_SETFONT & + (IsDialogEx(pTemplate) ? ((DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style)); +} + +BYTE* GetFontSizeField(const DLGTEMPLATE* pTemplate) +{ + BOOL bDialogEx = IsDialogEx(pTemplate); + WORD* pw; + + if (bDialogEx) + pw = (WORD*)((DLGTEMPLATEEX*)pTemplate + 1); + else + pw = (WORD*)(pTemplate + 1); + + // Skip menu name string or ordinal + if (*pw == (WORD)-1) + pw += 2; + else + while(*pw++); + + // Skip class name string or ordinal + if (*pw == (WORD)-1) + pw += 2; + else + while(*pw++); + + // Skip caption string + while (*pw++); + + return (BYTE*)pw; +} + +BOOL GetMessageFont(WORD *nPointSize, TCHAR* lpFaceName) +{ + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&ncm,0)) + return FALSE; + + LOGFONT &lf = ncm.lfMessageFont; + + if (lf.lfHeight < 0) + lf.lfHeight = -lf.lfHeight; + + HDC hDC = ::GetDC(NULL); + *nPointSize = MulDiv(lf.lfHeight,72,GetDeviceCaps(hDC, LOGPIXELSY)); + ::ReleaseDC(NULL,hDC); + + _tcscpy(lpFaceName, lf.lfFaceName); + + return TRUE; +} + +BOOL CALLBACK _EnumTranslate(HWND hWnd, LPARAM lParam) +{ + TCHAR text[1024]; + TranslateProc tp = (TranslateProc)lParam; + if (GetDlgCtrlID(hWnd)>0) { + GetWindowText(hWnd, text, sizeof(text)/sizeof(TCHAR)); + SetWindowText(hWnd, tp(text)); + } + return TRUE; +} + +BOOL TranslateDialog(HWND hWnd, TranslateProc tp) +{ + TCHAR text[1024]; + GetWindowText(hWnd, text, sizeof(text)/sizeof(TCHAR)); + SetWindowText(hWnd, tp(text)); + +/* HWND child = GetWindow(hWnd, GW_CHILD | GW_HWNDFIRST); + if (!child) return FALSE; + + do { + GetDlgCtrlID + + } while (child = GetWindow(child, GW_HWNDNEXT)); +*/ + return EnumChildWindows(hWnd, _EnumTranslate, (LPARAM)tp); +} + + +HGLOBAL GetTemplate(HINSTANCE hInst, LPCTSTR lpTemplate) +{ + HGLOBAL hTemplate; + + HRSRC hRsrc = FindResource(hInst, lpTemplate, RT_DIALOG); + HGLOBAL tTemplate = LoadResource(hInst, hRsrc); + DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)LockResource(tTemplate); + UINT dwTemplateSize = SizeofResource(hInst, hRsrc); + if ((hTemplate = GlobalAlloc(GPTR, dwTemplateSize + LF_FACESIZE * 2)) == NULL) + return NULL; + DLGTEMPLATE* pNew = (DLGTEMPLATE*)GlobalLock(hTemplate); + memcpy((BYTE*)pNew, pTemplate, (size_t)dwTemplateSize); + + GlobalUnlock(hTemplate); + UnlockResource(tTemplate); + FreeResource(tTemplate); + + TCHAR lpFaceName[128]; + WORD nFontSize; + if (GetMessageFont(&nFontSize, lpFaceName)) + { + pTemplate = (DLGTEMPLATE*)GlobalLock(hTemplate); + + BOOL bDialogEx = IsDialogEx(pTemplate); + BOOL bHasFont = HasFont(pTemplate); + int cbFontAttr = FontAttrSize(bDialogEx); + + if (bDialogEx) + ((DLGTEMPLATEEX*)pTemplate)->style |= DS_SETFONT; + else + pTemplate->style |= DS_SETFONT; + + int nFaceNameLen = lstrlen(lpFaceName); + if( nFaceNameLen < LF_FACESIZE ) + { +#ifdef _UNICODE + int cbNew = cbFontAttr + ((nFaceNameLen + 1) * sizeof(TCHAR)); + BYTE* pbNew = (BYTE*)lpFaceName; +#else + WCHAR wszFaceName [LF_FACESIZE]; + int cbNew = cbFontAttr + 2 * MultiByteToWideChar(CP_ACP, 0, lpFaceName, -1, wszFaceName, LF_FACESIZE); + BYTE* pbNew = (BYTE*)wszFaceName; +#endif + + BYTE* pb = GetFontSizeField(pTemplate); + int cbOld = (int)(bHasFont ? cbFontAttr + 2 * (wcslen((WCHAR*)(pb + cbFontAttr)) + 1) : 0); + + BYTE* pOldControls = (BYTE*)(((DWORD_PTR)pb + cbOld + 3) & ~DWORD_PTR(3)); + BYTE* pNewControls = (BYTE*)(((DWORD_PTR)pb + cbNew + 3) & ~DWORD_PTR(3)); + + WORD nCtrl = bDialogEx ? (WORD)((DLGTEMPLATEEX*)pTemplate)->cDlgItems : + (WORD)pTemplate->cdit; + + if (cbNew != cbOld && nCtrl > 0) + memmove(pNewControls, pOldControls, (size_t)(dwTemplateSize - (pOldControls - (BYTE*)pTemplate))); + + *(WORD*)pb = nFontSize; + memmove(pb + cbFontAttr, pbNew, cbNew - cbFontAttr); + + dwTemplateSize += ULONG(pNewControls - pOldControls); + } + GlobalUnlock(hTemplate); + } + + return hTemplate; +} + +HWND CreateDialogEx(HINSTANCE hInst, LPCTSTR lpTemplate, HWND hwndParent, DLGPROC lpDialogProc, LPARAM lParam) +{ + HGLOBAL hTemplate = GetTemplate(hInst, lpTemplate); + LPCDLGTEMPLATE lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hTemplate); + HWND hWnd = ::CreateDialogIndirectParam(hInst, lpDialogTemplate, + hwndParent, lpDialogProc, lParam); + + UnlockResource(hTemplate); + GlobalFree(hTemplate); + return hWnd; +} + +INT_PTR DialogBoxEx(HINSTANCE hInst, LPCTSTR lpTemplate, HWND hwndParent, DLGPROC lpDialogProc, LPARAM lParam) +{ + HGLOBAL hTemplate = GetTemplate(hInst, lpTemplate); + LPCDLGTEMPLATE lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hTemplate); + INT_PTR result = DialogBoxIndirectParam(hInst, lpDialogTemplate, hwndParent, lpDialogProc, lParam); + + UnlockResource(hTemplate); + GlobalFree(hTemplate); + return result; +} \ No newline at end of file diff --git a/k-meleon/DialogUtils.h b/k-meleon/DialogUtils.h new file mode 100644 index 00000000..76abc11d --- /dev/null +++ b/k-meleon/DialogUtils.h @@ -0,0 +1,39 @@ +#ifndef __DIALOG_UTILS_H__ +#define __DIALOG_UTILS_H__ + +#include + +inline LPTSTR _LoadString(HINSTANCE hInst, UINT id, LPTSTR buffer, int bufferSize) +{ + if (!LoadString(hInst, id, buffer, bufferSize)) + return NULL; + return buffer; +} + +#define LOAD_STRING(id) _LoadString(kPlugin.hDllInstance, id, (LPTSTR)_alloca(512*sizeof(TCHAR)), 512) +#define LOAD_STRING_SIZE(id, size) _LoadString(kPlugin.hDllInstance, id, (LPTSTR)_alloca(size*sizeof(TCHAR)), size) + +#pragma pack(push, 1) + +typedef struct { + WORD dlgVer; + WORD signature; + DWORD helpID; + DWORD exStyle; + DWORD style; + WORD cDlgItems; + short x; + short y; + short cx; + short cy; +} DLGTEMPLATEEX; + +#pragma pack(pop) + +typedef TCHAR* (*TranslateProc)(const TCHAR*); +BOOL TranslateDialog(HWND hWnd, TranslateProc tp); + +HWND CreateDialogEx(HINSTANCE hInst, LPCTSTR lpTemplate, HWND hwndParent, DLGPROC lpDialogProc, LPARAM lParam = NULL); +INT_PTR DialogBoxEx(HINSTANCE hInst, LPCTSTR lpTemplate, HWND hwndParent, DLGPROC lpDialogProc, LPARAM lParam = NULL); + +#endif // __DIALOG_UTILS_H__ \ No newline at end of file diff --git a/k-meleon/Dialogs.cpp b/k-meleon/Dialogs.cpp new file mode 100644 index 00000000..69186083 --- /dev/null +++ b/k-meleon/Dialogs.cpp @@ -0,0 +1,526 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chak Nanga + * + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "stdafx.h" +#include "Dialogs.h" +#include "BrowserFrm.h" +#include "BrowserView.h" +#include "MfcEmbed.h" +#include "resource.h" +extern CMfcEmbedApp theApp; + +//--------------------------------------------------------------------------// +// CFindReBar +//--------------------------------------------------------------------------// + +#ifndef _UNICODE +CFindRebar::CFindRebar(WCHAR* szSearch, PRBool bMatchCase, + PRBool bMatchWholeWord, PRBool bWrapAround, + PRBool bHighlight, CBrowserFrame* pOwner) +{ + memset(m_szUStr, 0, sizeof(m_szUStr)*sizeof(char)); + if (szSearch) + wcsncpy(m_szUStr, szSearch, sizeof(m_szUStr)/sizeof(WCHAR)-1); +#else +CFindRebar::CFindRebar(CString csSearchStr, PRBool bMatchCase, + PRBool bMatchWholeWord, PRBool bWrapAround, + PRBool bHighlight, CBrowserFrame* pOwner) + : CReBar() +{ + m_csSearchStr = csSearchStr; +#endif + m_bMatchCase = bMatchCase; + m_bMatchWholeWord = bMatchWholeWord; + m_bWrapAround = bWrapAround; + m_bHighlight = bHighlight; + m_pOwner = pOwner; + m_hid = 0; + + // Stay false until we have initialised the edit control + m_bAutoSearch = false; + m_clrBkgnd = RGB(255,128,128); + m_brBkgnd.CreateSolidBrush( m_clrBkgnd ); + m_NotFound = false; +} + +BEGIN_MESSAGE_MAP(CFindRebar, CReBar) +#ifndef FINDBAR_USE_TYPEAHEAD + ON_EN_CHANGE(IDC_FIND_EDIT, OnEnChangeSearchStr) +#endif + ON_WM_CREATE() + ON_COMMAND(ID_CLOSE_FINDBAR, Close) + ON_WM_SETFOCUS() + ON_WM_CTLCOLOR() + ON_WM_TIMER() +END_MESSAGE_MAP() + +CFindRebar::~CFindRebar() +{ + m_bStartsel = false; +} + +BOOL CFindRebar::Create(CWnd* parent, DWORD dwStyle) +{ + return CReBar::Create(parent, RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_DBLCLKTOGGLE, dwStyle | WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN); +} + +void CFindRebar::Close() +{ + DestroyWindow(); +} + +void CFindRebar::PostNcDestroy() +{ +#ifndef _UNICODE + if (theApp.m_bUnicode){ + ::DestroyWindow(m_cEdit.Detach()); + } +#endif + m_pOwner->ClearFindBar(); + //CReBar::PostNcDestroy(); +} + +#ifndef FINDBAR_USE_TYPEAHEAD + +void CFindRebar::OnEnChangeSearchStr() +{ + if (!m_bAutoSearch) return; + + bool disabled = false; + + if (m_csSearchStr.GetLength()==0) + disabled = true; +#ifndef _UNICODE + if (theApp.m_bUnicode) { + //int len = ::GetWindowTextLengthW(m_hWnd); + ::GetWindowTextW(m_cEdit.m_hWnd, m_szUStr, sizeof(m_szUStr)/sizeof(WCHAR)-1); + }else{ +#endif + m_cEdit.GetWindowText(m_csSearchStr); +#ifndef _UNICODE + USES_CONVERSION; + wcsncpy(m_szUStr, A2W(m_csSearchStr), sizeof(m_szUStr)/sizeof(WCHAR)-1); + } +#endif + if (Highlight()) + SetTimer(12345, 300, NULL); + + m_bStartsel = true; + m_pOwner->SendMessage(WM_COMMAND, ID_EDIT_FINDNEXT, 0); + m_bStartsel = false; +} +#endif + +void CFindRebar::OnTimer(UINT nIDEvent) +{ + if (nIDEvent == 12345){ + KillTimer(nIDEvent); + m_pOwner->SendMessage(WM_COMMAND, IDC_HIGHLIGHT, 0); + } + CReBar::OnTimer(nIDEvent); +} + +int CFindRebar::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CReBar::OnCreate(lpCreateStruct) == -1) + return -1; + + CString str; + + // Band with the close button + closeBar.CreateEx(this, TBSTYLE_FLAT|TBSTYLE_TRANSPARENT); + closeBar.LoadToolBar(IDR_TOOLBAR_CLOSE); + closeBar.GetToolBarCtrl().SetBitmapSize(CSize(10,10)); + + AddBar(&closeBar, _T(""), NULL, RBBS_NOGRIPPER); + + // Band with the edit control +#ifndef _UNICODE + if (theApp.m_bUnicode){ + HWND hWnd = ::CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", + NULL, WS_CHILD|ES_AUTOHSCROLL, 0, 0, 150, 18, + this->m_hWnd, (HMENU)(UINT_PTR)IDC_FIND_EDIT, AfxGetInstanceHandle(), NULL); + + m_cEdit.Attach(hWnd); + ::SetWindowTextW(hWnd, m_szUStr); + }else{ +#endif + m_cEdit.Create(WS_CHILD|ES_AUTOHSCROLL, CRect(0,0,150,18), this, IDC_FIND_EDIT); + m_cEdit.ModifyStyleEx(0, WS_EX_CLIENTEDGE); + m_cEdit.SetWindowText(m_csSearchStr); +#ifndef _UNICODE + } +#endif + + str.LoadString(IDS_FIND); + AddBar(&m_cEdit, str, NULL, RBBS_NOGRIPPER); + + // Toolbar with next/Previous and options + m_cToolbar.CreateEx(this, TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | TBSTYLE_LIST | TBSTYLE_TOOLTIPS + );//,WS_CHILD|WS_VISIBLE|CBRS_FLYBY); + + m_cToolbar.GetToolBarCtrl().SetImageList(NULL); + + CString skinFile; + if (theApp.FindSkinFile(skinFile, _T("findhot.bmp"))) + { + m_ilHot.Create(16, 16, ILC_MASK | ILC_COLOR8, 4, 8); + HBITMAP bitmap = (HBITMAP)LoadImage(NULL, skinFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); + if (bitmap) { + ImageList_AddMasked(m_ilHot.GetSafeHandle(), bitmap, RGB(255, 0, 255)); + DeleteObject(bitmap); + m_cToolbar.GetToolBarCtrl().SetHotImageList(&m_ilHot); + } + } + + if (theApp.FindSkinFile(skinFile, _T("findcold.bmp"))) + { + m_ilCold.Create(16, 16, ILC_MASK | ILC_COLOR8, 4, 8); + HBITMAP bitmap = (HBITMAP)LoadImage(NULL, skinFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); + if (bitmap) { + ImageList_AddMasked(m_ilCold.GetSafeHandle(), bitmap, RGB(255, 0, 255)); + DeleteObject(bitmap); + m_cToolbar.GetToolBarCtrl().SetImageList(&m_ilCold); + } + } + + + TBBUTTON button = {0}; + button.fsState = TBSTATE_ENABLED; + button.fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE; + + //int stringID = toolbar->GetToolBarCtrl().AddString(IDS_FINDNEXT); + int stringID=-1; + button.idCommand = ID_EDIT_FINDNEXT; + button.iString =stringID; + m_cToolbar.GetToolBarCtrl().InsertButton(0,&button); + + str.LoadString(IDS_FINDNEXT); + m_cToolbar.SetButtonText(0, (LPCTSTR)str); + + //stringID = toolbar->GetToolBarCtrl().AddString(IDS_FINDPREV); + button.idCommand = ID_EDIT_FINDPREV; + button.iBitmap = 1; + button.iString = stringID; + m_cToolbar.GetToolBarCtrl().InsertButton(1,&button); + str.LoadString(IDS_FINDPREV); + m_cToolbar.SetButtonText(1, (LPCTSTR)str); + + //button.fsStyle = TBSTYLE_CHECK | TB_AUTOSIZE; + + button.fsStyle = TBBS_CHECKBOX | TBSTYLE_AUTOSIZE; + + // Wrap around button + if (m_bWrapAround) + button.fsState = TBSTATE_CHECKED; + + button.idCommand = IDC_WRAP_AROUND; + button.iBitmap = 2; + m_cToolbar.GetToolBarCtrl().InsertButton(2,&button); + str.LoadString(IDS_FIND_WRAPAROUND); + m_cToolbar.SetButtonText(2, (LPCTSTR)str); + + // Match case button + + button.fsState = TBSTATE_ENABLED; + if (m_bMatchCase) + button.fsState = TBSTATE_CHECKED; + + button.idCommand = IDC_MATCH_CASE; + button.iBitmap = 3; + m_cToolbar.GetToolBarCtrl().InsertButton(3,&button); + str.LoadString(IDS_FIND_MATCHCASE); + m_cToolbar.SetButtonText(3, (LPCTSTR)str); + //toolbar->SetButtonStyle(2, TBBS_CHECKBOX); + + // Highlight button + button.fsState = TBSTATE_ENABLED; + if (m_bHighlight) + button.fsState = TBSTATE_CHECKED; + button.idCommand = IDC_HIGHLIGHT; + m_cToolbar.GetToolBarCtrl().InsertButton(4,&button); + str.LoadString(IDS_FIND_HIGHLIGHT); + m_cToolbar.SetButtonText(4, (LPCTSTR)str); + + + AddBar(&m_cToolbar, _T(""), NULL, RBBS_NOGRIPPER); + + // Setting the font of the edit control + m_cEdit.SetFont(m_cToolbar.GetFont()); + + // I wonder why I have to do that ... + REBARBANDINFO rbbi; + rbbi.cbSize = sizeof(rbbi); + rbbi.fMask = RBBIM_CHILDSIZE; + rbbi.cxMinChild = 150; + rbbi.cyMinChild = HIWORD(m_cToolbar.GetToolBarCtrl().GetButtonSize()); // Not sure what constant I should set here + GetReBarCtrl().SetBandInfo (1, &rbbi); + rbbi.cxMinChild = 20; + GetReBarCtrl().SetBandInfo (2, &rbbi); + rbbi.cyMinChild = 16; + GetReBarCtrl().SetBandInfo (0, &rbbi); + + m_cEdit.SetFocus(); + m_cEdit.SetSel(0,-1); + m_bAutoSearch = true; + + return 0; +} + + +void CFindRebar::OnSetFocus(CWnd* pOldWnd) +{ + CReBar::OnSetFocus(pOldWnd); + m_cEdit.SetFocus(); + m_cEdit.SetSel(0,-1); +} + + +BOOL CFindRebar::PreTranslateMessage(MSG* pMsg) +{ + // to test: Ctrl+F + + if(pMsg->message==WM_KEYDOWN){ + if (pMsg->wParam!=VK_SHIFT ){ + if(pMsg->wParam==VK_F3) + return false; // browserview will take care of it + } + if (pMsg->wParam==VK_ESCAPE){ + Close(); + return true; + } + if (pMsg->wParam==VK_RETURN){ + m_bStartsel = false; + m_pOwner->SendMessage(WM_COMMAND, ID_EDIT_FINDNEXT, 0); + //m_pOwner->SendMessage(WM_FINDMSG, (WPARAM)this, 1); + return true; + } +#ifdef FINDBAR_USE_TYPEAHEAD + m_pOwner->m_wndBrowserView.PostMessage(WM_KEYDOWN, pMsg->lParam, pMsg->wParam); +#endif + } + + return CReBar::PreTranslateMessage(pMsg); +} + +HBRUSH CFindRebar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) +{ + if (nCtlColor == CTLCOLOR_EDIT && m_NotFound) + { + pDC->SetBkColor( m_clrBkgnd ); + return m_brBkgnd; + } + + HBRUSH hbr = CReBar::OnCtlColor(pDC, pWnd, nCtlColor); + return hbr; +} + + +#if 0 +// File overview.... +// +// Contains find dialog stuff +// +//--------------------------------------------------------------------------// +// CFindDialog Stuff +//--------------------------------------------------------------------------// + +CFindDialog::CFindDialog(CString& csSearchStr, PRBool bMatchCase, + PRBool bMatchWholeWord, PRBool bWrapAround, + PRBool bSearchBackwards, CBrowserView* pOwner) + : CFindReplaceDialog() +{ + // Save these initial settings off in member vars + // We'll use these to initialize the controls + // in InitDialog() + + m_csSearchStr = csSearchStr; + m_bMatchCase = bMatchCase; + m_bMatchWholeWord = bMatchWholeWord; + m_bWrapAround = bWrapAround; + m_bSearchBackwards = bSearchBackwards; + m_pOwner = pOwner; + + // Set up to load our customized Find dialog template + // rather than the default one MFC provides + m_fr.Flags |= FR_ENABLETEMPLATE; + m_fr.hInstance = AfxGetInstanceHandle(); + m_fr.lpTemplateName = MAKEINTRESOURCE(IDD_FINDDLG); +} + +BOOL CFindDialog::OnInitDialog() +{ + CFindReplaceDialog::OnInitDialog(); + + + // -- Find settings + m_bMatchCase = theApp.preferences.bFindMatchCase; + m_bSearchBackwards = theApp.preferences.bFindSearchBackwards; + m_bWrapAround = theApp.preferences.bFindWrapAround; + + + CEdit* pEdit = (CEdit *)GetDlgItem(IDC_FIND_EDIT); + if(pEdit) + pEdit->SetWindowText(m_csSearchStr); + + CButton* pChk = (CButton *)GetDlgItem(IDC_MATCH_CASE); + if(pChk) + pChk->SetCheck(m_bMatchCase); + + pChk = (CButton *)GetDlgItem(IDC_MATCH_WHOLE_WORD); + if(pChk) + pChk->SetCheck(m_bMatchWholeWord); + + pChk = (CButton *)GetDlgItem(IDC_WRAP_AROUND); + if(pChk) + pChk->SetCheck(m_bWrapAround); + + pChk = (CButton *)GetDlgItem(IDC_SEARCH_BACKWARDS); + if(pChk) + pChk->SetCheck(m_bSearchBackwards); + + return TRUE; +} + +void CFindDialog::OnCancel() { + + CButton* pChk = (CButton *)GetDlgItem(IDC_MATCH_CASE); + if(pChk) + theApp.preferences.bFindMatchCase = pChk->GetCheck(); + + pChk = (CButton *)GetDlgItem(IDC_WRAP_AROUND); + if(pChk) + theApp.preferences.bFindWrapAround = pChk->GetCheck(); + + pChk = (CButton *)GetDlgItem(IDC_SEARCH_BACKWARDS); + if(pChk) + theApp.preferences.bFindSearchBackwards = pChk->GetCheck(); + + CFindReplaceDialog::OnCancel(); + +} + +void CFindDialog::PostNcDestroy() +{ + // Let the owner know we're gone + if(m_pOwner != NULL) + m_pOwner->ClearFindDialog(); + + CFindReplaceDialog::PostNcDestroy(); +} + +BOOL CFindDialog::WrapAround() +{ + CButton* pChk = (CButton *)GetDlgItem(IDC_WRAP_AROUND); + + return pChk ? pChk->GetCheck() : FALSE; +} + +BOOL CFindDialog::SearchBackwards() +{ + CButton* pChk = (CButton *)GetDlgItem(IDC_SEARCH_BACKWARDS); + + return pChk ? pChk->GetCheck() : FALSE; +} +#endif + +//IMPLEMENT_DYNAMIC(CSelectDialog, CDialog) +CSelectDialog::CSelectDialog(CWnd* pParent, LPCTSTR pTitle, LPCTSTR pText) + : CDialog(CSelectDialog::IDD, pParent) +{ + if(pTitle) m_csDialogTitle = pTitle; + if(pText) m_csMsgText = pText; + m_iChoice = 0; +} + +CSelectDialog::~CSelectDialog() +{ +} + +void CSelectDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST_SELECT, m_cList); +} + + +BEGIN_MESSAGE_MAP(CSelectDialog, CDialog) + ON_BN_CLICKED(IDOK, OnBnClickedOk) + ON_LBN_DBLCLK(IDC_LIST_SELECT, OnLbnDblclkListSelect) +END_MESSAGE_MAP() + + +// Gestionnaires de messages SelectDialog + +BOOL CSelectDialog::OnInitDialog() +{ + CDialog::OnInitDialog(); + + POSITION pos = m_clChoices.GetHeadPosition(); + for (int i=0;i < m_clChoices.GetCount();i++) { + int idx = m_cList.AddString(m_clChoices.GetNext(pos)); + m_cList.SetItemData(idx, i); + } + + SetWindowText(m_csDialogTitle); + + CWnd *pWnd = GetDlgItem(IDC_MSG_TEXT); + if(pWnd) + pWnd->SetWindowText(m_csMsgText); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION : les pages de propriétés OCX devraient retourner FALSE +} + +void CSelectDialog::AddChoice(LPCTSTR text) +{ + m_clChoices.AddTail(text); +} + +void CSelectDialog::OnBnClickedOk() +{ + int idx = m_cList.GetCaretIndex(); + m_iChoice = m_cList.GetItemData(idx); + OnOK(); +} + +void CSelectDialog::OnLbnDblclkListSelect() +{ + OnBnClickedOk(); +} diff --git a/k-meleon/Dialogs.h b/k-meleon/Dialogs.h new file mode 100644 index 00000000..f94b526c --- /dev/null +++ b/k-meleon/Dialogs.h @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chak Nanga + * + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _DIALOGS_H_ +#define _DIALOGS_H_ + +#include "resource.h" +#include "DialogEx.h" + +class CBrowserView; +class CBrowserFrame; + +#include +class CFindRebar: public CReBar +{ +public: +#ifndef _UNICODE + CFindRebar(WCHAR* szSearch, PRBool bMatchCase, + PRBool bMatchWholeWord, PRBool bWrapAround, + PRBool bHighlight, CBrowserFrame* pOwner); +#else + CFindRebar(CString csSearchStr, PRBool bMatchCase, + PRBool bMatchWholeWord, PRBool bWrapAround, + PRBool bHighlight, CBrowserFrame* pOwner); +#endif + virtual ~CFindRebar(); + BOOL Create(CWnd* parent, DWORD dwStyle); + void OnNotFound() { + if (!m_NotFound) { + m_NotFound=true; + m_cEdit.Invalidate(); + m_cEdit.SetFocus(); + MessageBeep(MB_ICONASTERISK); + } + } + void OnFound() {m_NotFound=false;Invalidate();m_cEdit.Invalidate();} + inline CString GetFindString( ) const {return m_csSearchStr;} + + inline BOOL WrapAround() {return m_cToolbar.GetToolBarCtrl().IsButtonChecked(IDC_WRAP_AROUND);} + inline BOOL MatchCase() {return m_cToolbar.GetToolBarCtrl().IsButtonChecked(IDC_MATCH_CASE);} + inline BOOL Highlight() {return m_cToolbar.GetToolBarCtrl().IsButtonChecked(IDC_HIGHLIGHT);} + inline bool StartSel() {return m_bStartsel;} + + CEdit m_cEdit; + +#ifndef _UNICODE + inline const WCHAR* GetUFindString( ) const { return m_szUStr; } +#else + inline const WCHAR* GetUFindString( ) const { return m_csSearchStr; } +#endif + + +private: + CString m_csSearchStr; +#ifndef _UNICODE + WCHAR m_szUStr[256]; +#endif + PRBool m_bMatchCase; + PRBool m_bMatchWholeWord; + PRBool m_bWrapAround; + PRBool m_bHighlight; + UINT m_hid; + + CBrowserFrame* m_pOwner; + CBrush m_brBkgnd; + COLORREF m_clrBkgnd; + + CToolBar m_cToolbar; + CToolBar closeBar; + CImageList m_ilHot; + CImageList m_ilCold; + + bool m_NotFound; + bool m_bStartsel; + bool m_bAutoSearch; + +public: + DECLARE_MESSAGE_MAP() + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void Close(); + afx_msg void OnSetFocus(CWnd* pOldWnd); +#ifndef FINDBAR_USE_TYPEAHEAD + afx_msg void OnEnChangeSearchStr(); +#endif + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); + afx_msg void OnWrapAround(); + afx_msg void OnMatchCase(); + +protected: + virtual void PostNcDestroy(); +public: + afx_msg void OnTimer(UINT nIDEvent); + +}; + +class CFindDialog : public CFindReplaceDialog +{ +public: + CFindDialog(CString& csSearchStr, PRBool bMatchCase, + PRBool bMatchWholeWord, PRBool bWrapAround, + PRBool bSearchBackwards, CBrowserView* pOwner); + BOOL WrapAround(); + BOOL SearchBackwards(); + +private: + CString m_csSearchStr; + PRBool m_bMatchCase; + PRBool m_bMatchWholeWord; + PRBool m_bWrapAround; + PRBool m_bSearchBackwards; + CBrowserView* m_pOwner; + +protected: + virtual void OnCancel(); + virtual BOOL OnInitDialog(); + virtual void PostNcDestroy(); +}; + +class CSelectDialog : public CDialog +{ +// DECLARE_DYNAMIC(CSelectDialog) + +public: + CSelectDialog(CWnd* pParent, LPCTSTR pTitle, LPCTSTR pText); // constructeur standard + virtual ~CSelectDialog(); + inline int GetChoice() {return m_iChoice;} + void AddChoice(LPCTSTR); + +// Données de boîte de dialogue + enum { IDD = IDD_PROMPT_SELECT }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // Prise en charge DDX/DDV + CString m_csDialogTitle; + CString m_csMsgText; + CListBox m_cList; + CList m_clChoices; + int m_iChoice; + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); + afx_msg void OnBnClickedOk(); + afx_msg void OnLbnDblclkListSelect(); +}; + +#endif //_DIALOG_H_ diff --git a/k-meleon/FavIconList.cpp b/k-meleon/FavIconList.cpp new file mode 100644 index 00000000..fbb1e176 --- /dev/null +++ b/k-meleon/FavIconList.cpp @@ -0,0 +1,835 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* +*/ + +/* + +Bug: Changing skin need to delete the iconcache. + +*/ + +#include "stdafx.h" + +#ifdef INTERNAL_SITEICONS + +#include "FavIconList.h" + +#include "UnknownContentTypeHandler.h" +#include "nscWebBrowserPersist.h" + +#include "imgILoader.h" +#include "gfxIImageFrame.h" +#include "imgIContainer.h" +#include "nsIImage.h" + +#include "mfcembed.h" +#include "kmeleon_plugin.h" + + +//#define PNG_SUPPORT + +#ifdef PNG_SUPPORT +#define PNGDIB_NO_D2P +#define PNGDIB_S +#include "../pngdib-3.0.1/pngdib.h" + +#ifdef _DEBUG +#pragma comment(lib,"../pngdib-3.0.1/lib/pngdib.lib") +#pragma comment(lib,"../lpng128/projects/visualc71/lib/libpng.lib") +#pragma comment(lib,"../lpng128/projects/visualc71/lib/zlib/zlib.lib") +#else +#ifdef _UNICODE +#pragma comment(lib,"../pngdib-3.0.1/lib/pngdib_u_s_md.lib") +#pragma comment(lib,"../lpng128/projects/visualc71/lib/libpng_u_md.lib") +#pragma comment(lib,"../lpng128/projects/visualc71/lib/zlib/zlib_u_md.lib") +#else +#pragma comment(lib,"../pngdib-3.0.1/lib/pngdib_s_md.lib") +#pragma comment(lib,"../lpng128/projects/visualc71/lib/libpng_md.lib") +#pragma comment(lib,"../lpng128/projects/visualc71/lib/zlib/zlib_md.lib") +#endif +#endif // _DEBUG +#endif + +#define FAVICON_CACHE_FILE _T("IconCache.dat") + +// Used to resize the icon if it's not 16x16 +HBITMAP ResizeIcon(HDC hDC, HBITMAP hBitmap, LONG w, LONG h) +{ + HDC hDCs = CreateCompatibleDC(hDC); + + HGDIOBJ old = SelectObject(hDCs, hBitmap); + if (!old) { + DeleteDC(hDCs); + return NULL; + } + + HDC hdcScaled = CreateCompatibleDC(hDCs); + HBITMAP hbmSized = CreateCompatibleBitmap(hDCs, 16, 16); + HGDIOBJ old2 = SelectObject(hdcScaled, hbmSized); + + StretchBlt(hdcScaled,0,0,16,16,hDCs,0,0,w,h,SRCCOPY); + SelectObject(hdcScaled, old2); + DeleteDC(hdcScaled); + SelectObject(hDCs, old); + DeleteDC(hDCs); + return hbmSized; +} + +CFavIconList::CFavIconList() +{ + m_iDefaultIcon = 0; + m_iOffset = 0; +} + +CFavIconList::~CFavIconList() +{ + WriteCache(); +} + +BOOL CFavIconList::LoadCache() +{ + CFile iconCache; + CImageList imgList; + if (!iconCache.Open(theApp.GetFolder(ProfileFolder) + _T("\\") FAVICON_CACHE_FILE, CFile::modeRead)) + return FALSE; + + if (!theApp.preferences.GetBool("kmeleon.favicons.cached", TRUE)) { + iconCache.Close(); + DeleteFile(theApp.GetFolder(ProfileFolder) + _T("\\") FAVICON_CACHE_FILE); + } + else { + CArchive ar(&iconCache, CArchive::load ); + TRY + if (imgList.Read(&ar)) + m_urlMap.Serialize(ar); + CATCH (CArchiveException, e) { + DeleteImageList(); + return FALSE; + } + END_CATCH + } + + for (int i=0; i < imgList.GetImageCount(); i++) { + int idx = Add(imgList.ExtractIcon(i)); + ASSERT(idx == i + m_iOffset); + } + + return TRUE; +} + +BOOL CFavIconList::WriteCache() +{ + if (!m_hImageList) + return FALSE; + + if (!theApp.preferences.GetBool("kmeleon.favicons.cached", TRUE)) + return FALSE; + + CImageList imgList; + imgList.Create(this); + + for (int i=0; i < m_iOffset; i++) + imgList.Remove(0); + + CFile iconCache; + if (iconCache.Open(theApp.GetFolder(ProfileFolder) + _T("\\") FAVICON_CACHE_FILE, CFile::modeCreate | CFile::modeWrite)) + { + CArchive ar(&iconCache, CArchive::store); + if (imgList.Write(&ar)) + m_urlMap.Serialize(ar); + } + return TRUE; +} + +void CFavIconList::LoadDefaultIcon() +{ + CString szFullPath; + + HICON defaultIcon = NULL; + if (theApp.FindSkinFile(szFullPath, _T("default.ico"))) + { + FILE *fp = _tfopen(szFullPath, _T("r")); + if (fp) { + fclose(fp); + defaultIcon = (HICON)LoadImage(NULL, szFullPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); + if (defaultIcon) { + m_iDefaultIcon = Add(defaultIcon); + } + } + } + + // Add can return 0 even if it fails... + if (GetImageCount()==0) + m_iDefaultIcon = Add(theApp.GetDefaultIcon()); + + if (theApp.FindSkinFile(szFullPath, _T("loading.ico"))) + { + FILE *fp = _tfopen(szFullPath, _T("r")); + if (fp) { + fclose(fp); + HICON loadingIcon = (HICON)LoadImage(NULL, szFullPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); + if (loadingIcon) { + m_iLoadingIcon = Add(loadingIcon); + DestroyIcon(loadingIcon); + } + } + } + + if (GetImageCount()==1) { + if (defaultIcon) + m_iLoadingIcon = Add(defaultIcon); + else + m_iLoadingIcon = Add(theApp.GetDefaultIcon()); + } + + if (defaultIcon) + DestroyIcon(defaultIcon); + +/* + if (theApp.FindSkinFile(szFullPath, _T("loader.bmp"))) + { + HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, szFullPath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); + if (hBitmap) + { + HDC hdcBitmap = CreateCompatibleDC(NULL); + HGDIOBJ oldBmp = SelectObject(hdcBitmap, hBitmap); + HBRUSH hBrush = CreateSolidBrush(RGB(255,0,255)); + + int cx, cy; + ImageList_GetIconSize(m_hImageList, &cx, &cy); + for (int i=0; i<8; i++) + { + CBitmap button; + HDC hdcButton = CreateCompatibleDC(hdcBitmap); + HBITMAP hButton = CreateCompatibleBitmap(hdcBitmap, cx, cy); + HGDIOBJ oldBmp2 = SelectObject(hdcButton, hButton); + + // fill the button with the transparency + HGDIOBJ oldBrush = SelectObject(hdcButton, hBrush); + PatBlt(hdcButton, 0, 0, cx, cy, PATCOPY); + + // copy the button from the full bitmap + BitBlt(hdcButton, 0, 0, cx, cy, hdcBitmap, cx*i, 0, SRCCOPY); + + SelectObject(hdcButton, oldBrush); + SelectObject(hdcButton, oldBmp2); + DeleteDC(hdcButton); + + CBitmap bmp; + bmp.Attach(hButton); + Add(&bmp, RGB(255,0,255)); + } + + SelectObject(hdcBitmap, oldBmp); + DeleteObject(hBrush); + DeleteDC(hdcBitmap); + DeleteObject(hBitmap); + } + } +*/ + m_iOffset = GetImageCount(); +} + +BOOL CFavIconList::Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow) +{ + if (!CImageList::Create(cx,cy,nFlags,nInitial,nGrow)) + return FALSE; + + LoadDefaultIcon(); + LoadCache(); + return TRUE; +} + +extern nsresult NewURI(nsIURI **result, const nsAString &spec); +extern nsresult NewURI(nsIURI **result, const nsACString &spec); + +void CFavIconList::AddMap(const char *uri, int index) +{ + // This function is called from another thread + // if the moz image loader is used. + + USES_CONVERSION; + m_urlMap[A2CT(uri)] = index - m_iOffset; + + // Add an entry for the hostname only. This is for the mru list. + // It's not really good to do it like that, because a site may + // have several different icons. + nsCOMPtr URI; + nsEmbedCString nsUri; + nsUri.Assign(uri); + nsresult rv = NewURI(getter_AddRefs(URI), nsUri); + if (NS_SUCCEEDED(rv)) { + URI->GetHost(nsUri); + nsUri.Insert("http://", 0, 7); + m_urlMap[A2CT(nsUri.get())] = index - m_iOffset; + } + + // If it's not really efficient, at least I don't have + // to mess with synchronisation. + theApp.BroadcastMessage(UWM_NEWSITEICON, (WPARAM)uri, index); +} + +int CFavIconList::AddIcon(const char* uri, CBitmap* icon, COLORREF cr) +{ + int index = Add(icon, cr); + AddMap(uri, index); + return index; +} + +int CFavIconList::AddIcon(const char* uri, CBitmap* icon, CBitmap* mask) +{ + int index = Add(icon, mask); + AddMap(uri, index); + return index; +} + +int CFavIconList::AddIcon(const char* uri, HICON icon) +{ + int index = Add(icon); + AddMap(uri, index); + return index; +} + +int CFavIconList::AddDownloadedIcon(char* uri, TCHAR* file, nsresult aStatus) +{ + int index = GetDefaultIcon(); + + if (NS_SUCCEEDED(aStatus)) + { + HICON favicon = (HICON)LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); + if (favicon){ + index = AddIcon(uri, favicon); + DestroyIcon(favicon); + } + #ifdef PNG_SUPPORT + else + { + PNGDIB *pngdib = pngdib_p2d_init(); + if (pngdib) + { + int errcode; + LPBITMAPINFOHEADER pdib; + int dib_size; + void *pdib_bits; + int bits_offs; + + pngdib_p2d_set_png_filename(pngdib, file); + pngdib_p2d_set_custom_bg(pngdib, 192, 192, 192); + + //pngdib_set_dibalpha32(pngdib, 1); // Can be used with Comctl32 Ver. 6 only + + pngdib_p2d_set_use_file_bg(pngdib, 1); + errcode=pngdib_p2d_run(pngdib); + if(!errcode) { + pngdib_p2d_get_dib(pngdib,&pdib,&dib_size); + pngdib_p2d_get_dibbits(pngdib,&pdib_bits,&bits_offs,NULL); + + HDC hDC = GetDC(NULL); + HBITMAP hBitmap = ::CreateDIBitmap(hDC,pdib,CBM_INIT,pdib_bits,(BITMAPINFO*)pdib,DIB_RGB_COLORS); + ReleaseDC(NULL,hDC); + + CBitmap bitmap; + bitmap.Attach(hBitmap); + + unsigned char pr,pg,pb; + int r = pngdib_p2d_get_bgcolor(pngdib, &pr, &pg, &pb); + if (r) + index = AddIcon(uri, &bitmap,RGB(pr,pg,pb)); + else + index = AddIcon(uri, &bitmap, (CBitmap*)NULL); + + bitmap.DeleteObject(); + + pngdib_p2d_free_dib(pngdib,NULL); + } + pngdib_done(pngdib); + } + + } + #endif + } + DeleteFile(file); + return index; +} + +int CFavIconList::GetHostIcon(const TCHAR* aUrl) +{ + int index = GetDefaultIcon(); + const char* url; +#ifdef _UNICODE + nsEmbedCString _str; + NS_UTF16ToCString(nsDependentString(aUrl), NS_CSTRING_ENCODING_UTF8, _str); + url = _str.get(); +#else + url = aUrl; +#endif + + nsCOMPtr URI; + nsEmbedCString nsUri; + nsUri.Assign(url); + nsresult rv = NewURI(getter_AddRefs(URI), nsUri); + if (NS_FAILED(rv)||!URI) return index; + + URI->GetHost(nsUri); + nsUri.Insert("http://", 0, 7); + USES_CONVERSION; + if (!m_urlMap.Lookup(A2CT(nsUri.get()), index)) + return index; + + return index + m_iOffset; +} + +int CFavIconList::GetIcon(nsIURI *aURI, BOOL download) +{ + int index = GetDefaultIcon(); + + if (!m_hImageList || !aURI) return 0; + + nsEmbedCString nsUri; + aURI->GetSpec(nsUri); + USES_CONVERSION; + if (m_urlMap.Lookup(A2CT(nsUri.get()), index)) + return index + m_iOffset; + + if (download) + DwnFavIcon(aURI); + return GetDefaultIcon(); +} + +void CFavIconList::RefreshIcon(nsIURI* aURI) +{ + if (!m_hImageList || !aURI) + return; + + int index = 0; + nsEmbedCString nsUri; + aURI->GetSpec(nsUri); + + USES_CONVERSION; + const TCHAR* url = A2CT(nsUri.get()); + if (!m_urlMap.Lookup(url, index)) + return; + + m_urlMap.RemoveKey(url); + + // Don't remove the default icon + if (index==GetDefaultIcon()) + return; + + Remove(index); + + // We have to remove all url with this icon. + POSITION pos = m_urlMap.GetStartPosition(); + while (pos!=NULL) + { + CString key; + int value; + m_urlMap.GetNextAssoc(pos, key, value); + if (value==index) + m_urlMap.RemoveKey(key); + else + if (value>index) + m_urlMap[key] = value-1; + + } + theApp.BroadcastMessage(UWM_NEWSITEICON, 0, -1); +} + +void CFavIconList::ResetCache() +{ + while (GetImageCount()) Remove(0); + m_urlMap.RemoveAll(); + LoadDefaultIcon(); + theApp.BroadcastMessage(UWM_NEWSITEICON, 0, -1); +} + +BOOL CFavIconList::DwnFavIcon(nsIURI* iconURI) +{ +#ifndef PNG_SUPPORT + // Borked way to get the favicon. + imgIRequest* request = nsnull; + IconObserver* observer = new IconObserver(this); + NS_ADDREF(observer); + + if (NS_FAILED(observer->LoadIcon(iconURI, nsnull))) { + NS_RELEASE(observer); + return FALSE; + } +#else + + // Currently the favicon is downloaded like any other file + // which is bad. A nsStreamListener have to be + // implemented. + nsCOMPtr persist(do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID)); + if(!persist) return FALSE; + + TCHAR tempPath[MAX_PATH]; + GetTempPath(MAX_PATH, tempPath); + GetTempFileName(tempPath, _T("kme"), 0, tempPath); + + nsCOMPtr file; +#ifdef _UNICODE + NS_NewLocalFile(nsDependentString(tempPath), TRUE, getter_AddRefs(file)); +#else + NS_NewNativeLocalFile(nsDependentCString(tempPath), TRUE, getter_AddRefs(file)); +#endif + + CProgressDialog *progress = new CProgressDialog(FALSE); + //persist->SetProgressListener(progress); + progress->InitPersist(iconURI, file, persist, FALSE); + progress->SetCallBack(CFavIconList::DwnCall, this); + persist->SetPersistFlags( + nsIWebBrowserPersist::PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION| + nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES); + nsresult rv = persist->SaveURI(iconURI, nsnull, nsnull, nsnull, nsnull, file); + if (NS_FAILED(rv)) { + persist->SetProgressListener(nsnull); + return FALSE; + } +#endif + + return TRUE; +} + +void CFavIconList::DwnCall(char* uri, TCHAR* file, nsresult status, void* param) +{ + ((CFavIconList*)param)->AddDownloadedIcon(uri,file,status); +} + +NS_IMPL_ISUPPORTS2(IconObserver, imgIDecoderObserver, imgIContainerObserver) + +#if GECKO_VERSION > 18 +NS_IMETHODIMP IconObserver::OnStartRequest(imgIRequest *aRequest) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP IconObserver::OnStopRequest(imgIRequest *aRequest, PRBool aIsLastPart) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} +#endif + +/* void onStartDecode (in imgIRequest aRequest); */ +NS_IMETHODIMP IconObserver::OnStartDecode(imgIRequest *aRequest) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void onStartContainer (in imgIRequest aRequest, in imgIContainer aContainer); */ +NS_IMETHODIMP IconObserver::OnStartContainer(imgIRequest *aRequest, imgIContainer *aContainer) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void onStartFrame (in imgIRequest aRequest, in gfxIImageFrame aFrame); */ +NS_IMETHODIMP IconObserver::OnStartFrame(imgIRequest *aRequest, gfxIImageFrame *aFrame) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* [noscript] void onDataAvailable (in imgIRequest aRequest, in gfxIImageFrame aFrame, [const] in nsIntRect aRect); */ +NS_IMETHODIMP IconObserver::OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame, const nsIntRect * aRect) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void onStopFrame (in imgIRequest aRequest, in gfxIImageFrame aFrame); */ +NS_IMETHODIMP IconObserver::OnStopFrame(imgIRequest *aRequest, gfxIImageFrame *aFrame) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void onStopContainer (in imgIRequest aRequest, in imgIContainer aContainer); */ +NS_IMETHODIMP IconObserver::OnStopContainer(imgIRequest *aRequest, imgIContainer *aContainer) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void onStopDecode (in imgIRequest aRequest, in nsresult status, in wstring statusArg); */ +NS_IMETHODIMP IconObserver::OnStopDecode(imgIRequest *aRequest, nsresult status, const PRUnichar *statusArg) +{ + if (NS_SUCCEEDED(status)) + CreateDIB(aRequest); + + aRequest->Cancel(status); + mRequest = nsnull; + NS_RELEASE_THIS(); + return NS_OK; +} + +struct ALPHABITMAPINFO { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[256]; + + + ALPHABITMAPINFO(LONG aWidth, LONG aHeight, WORD depth) + { + memset(&bmiHeader, 0, sizeof(bmiHeader)); + bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmiHeader.biWidth = aWidth; + bmiHeader.biHeight = aHeight; + bmiHeader.biPlanes = 1; + bmiHeader.biBitCount = depth; + + + /* fill in gray scale palette */ + int i, npal=1< 18 +static HBITMAP DataToBitmap(PRUint8* aImageData, + PRUint32 aWidth, + PRUint32 aHeight, + PRUint32 aDepth) +{ + HDC dc = ::GetDC(NULL); + + if (aDepth == 32) { + // Alpha channel. We need the new header. + BITMAPV4HEADER head = { 0 }; + head.bV4Size = sizeof(head); + head.bV4Width = aWidth; + head.bV4Height = aHeight; + head.bV4Planes = 1; + head.bV4BitCount = aDepth; + head.bV4V4Compression = BI_BITFIELDS; + head.bV4SizeImage = 0; // Uncompressed + head.bV4XPelsPerMeter = 0; + head.bV4YPelsPerMeter = 0; + head.bV4ClrUsed = 0; + head.bV4ClrImportant = 0; + + head.bV4RedMask = 0x00FF0000; + head.bV4GreenMask = 0x0000FF00; + head.bV4BlueMask = 0x000000FF; + head.bV4AlphaMask = 0xFF000000; + + HBITMAP bmp = ::CreateDIBitmap(dc, + reinterpret_cast(&head), + CBM_INIT, + aImageData, + reinterpret_cast(&head), + DIB_RGB_COLORS); + ::ReleaseDC(NULL, dc); + return bmp; + } + + char reserved_space[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2]; + BITMAPINFOHEADER& head = *(BITMAPINFOHEADER*)reserved_space; + + head.biSize = sizeof(BITMAPINFOHEADER); + head.biWidth = aWidth; + head.biHeight = aHeight; + head.biPlanes = 1; + head.biBitCount = (WORD)aDepth; + head.biCompression = BI_RGB; + head.biSizeImage = 0; // Uncompressed + head.biXPelsPerMeter = 0; + head.biYPelsPerMeter = 0; + head.biClrUsed = 0; + head.biClrImportant = 0; + + BITMAPINFO& bi = *(BITMAPINFO*)reserved_space; + + if (aDepth == 1) { + RGBQUAD black = { 0, 0, 0, 0 }; + RGBQUAD white = { 255, 255, 255, 0 }; + + bi.bmiColors[0] = white; + bi.bmiColors[1] = black; + } + + HBITMAP bmp = ::CreateDIBitmap(dc, &head, CBM_INIT, aImageData, &bi, DIB_RGB_COLORS); + ::ReleaseDC(NULL, dc); + return bmp; + +} +#endif + +NS_IMETHODIMP IconObserver::CreateDIB(imgIRequest *aRequest) +{ + nsresult rv; + nsCOMPtr image; + rv = aRequest->GetImage(getter_AddRefs(image)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr frame; + rv = image->GetFrameAt(0, getter_AddRefs(frame)); + NS_ENSURE_SUCCESS(rv, rv); + + frame->LockImageData(); + PRUint32 length; + PRUint8 *bits; + rv = frame->GetImageData(&bits, &length); + NS_ENSURE_SUCCESS(rv, rv); + + PRInt32 w,h; + frame->GetWidth(&w); + frame->GetHeight(&h); + + PRUint32 bpr; + frame->GetImageBytesPerRow(&bpr); + + /* PRUint32 alphaLength; + PRUint8 *alphaBits; + + frame->GetAlphaData(&alphaBits, &alphaLength); + + PRUint32 alphaBpr; + frame->GetAlphaBytesPerRow(&alphaBpr); + + PRUint32* fBits = new PRUint32[w*h]; + PRUint32 offset = 0; + for (int y = 0; y < w*h; y++) { + fBits[y] = alphaBits[y]; + fBits[y] = (fBits[y]<<8) + bits[offset+2]; + fBits[y] = (fBits[y]<<8) + bits[offset+1]; + fBits[y] = (fBits[y]<<8) + bits[offset]; + offset +=3; + }*/ + + CString uri; + nsCOMPtr URI; + nsEmbedCString nsuri; + rv = aRequest->GetURI(getter_AddRefs(URI)); + NS_ENSURE_SUCCESS(rv, rv); + URI->GetSpec(nsuri); + + CBitmap bitmap; + +#if GECKO_VERSION > 18 + HBITMAP hBitmap = DataToBitmap(bits, w, -h, (bpr/w)*8); +#else + BITMAPINFO binfo; + binfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + binfo.bmiHeader.biWidth = w; + binfo.bmiHeader.biHeight = h; + binfo.bmiHeader.biPlanes = 1; + binfo.bmiHeader.biBitCount = (bpr/w)*8; + binfo.bmiHeader.biCompression = BI_RGB; + binfo.bmiHeader.biSizeImage = length; + binfo.bmiHeader.biXPelsPerMeter = 0; + binfo.bmiHeader.biYPelsPerMeter = 0; + binfo.bmiHeader.biClrUsed = 0; + binfo.bmiHeader.biClrImportant = 0; + + HDC hDC = GetDC(NULL); + HBITMAP hBitmap = ::CreateDIBitmap(hDC,&binfo.bmiHeader,CBM_INIT,bits,&binfo,DIB_RGB_COLORS); +#endif + + if (w!=16 && h!=16) { + if (HBITMAP hbmSized = ResizeIcon(hDC, hBitmap, w, h)) { + DeleteObject(hBitmap); + hBitmap = hbmSized; + } + } + bitmap.Attach(hBitmap); + +#if GECKO_VERSION > 18 + mFavList->AddIcon(nsuri.get(),&bitmap, (CBitmap*)NULL); +#else + ReleaseDC(NULL,hDC); + + gfx_color bkgColor = 0; + rv = frame->GetBackgroundColor(&bkgColor); + if (NS_FAILED(frame->GetBackgroundColor(&bkgColor))) + { + CBitmap maskbitmap; + PRUint32 alphaLength; + PRUint8 *alphaBits; + PRUint8 *alphaBits2 = 0; + + if (NS_SUCCEEDED(frame->GetAlphaData(&alphaBits, &alphaLength))) + { + PRUint32 alphaBpr; + frame->GetAlphaBytesPerRow(&alphaBpr); // Return a false value?? + alphaBpr = (8 * alphaLength) / (w*h); + + if (alphaBpr<=8) { + + // XXX: if alphaBpr == 2, must convert to 4 + /*if (alphaBpr == 2) + { + alphaBits2 = alphaBits; + alphaBits = new PRUint8[alphaLength*4]; + for (int i=0;iAddIcon(nsuri.get(),&bitmap, &maskbitmap); + maskbitmap.DeleteObject(); + } else { + mFavList->AddIcon(nsuri.get(),&bitmap, bkgColor); + } +#endif + frame->UnlockImageData(); + bitmap.DeleteObject(); + return NS_OK; +} + +NS_IMETHODIMP IconObserver::LoadIcon(nsIURI *iconUri, nsIURI* pageUri) +{ + nsresult rv; + nsCOMPtr loader = do_GetService("@mozilla.org/image/loader;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + return loader->LoadImage(iconUri, pageUri, nsnull, + nsnull, this, this, nsIRequest::LOAD_BYPASS_CACHE, + nsnull, nsnull, getter_AddRefs(mRequest)); +} + +NS_IMETHODIMP IconObserver::FrameChanged(imgIContainer *aContainer, gfxIImageFrame *aFrame, nsIntRect * aDirtyRect) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +#endif // INTERNAL_SITEICONS \ No newline at end of file diff --git a/k-meleon/FavIconList.h b/k-meleon/FavIconList.h new file mode 100644 index 00000000..1a6cdb65 --- /dev/null +++ b/k-meleon/FavIconList.h @@ -0,0 +1,85 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* +*/ + +#pragma once + +#include "afxtempl.h" +#include "imgIDecoderObserver.h" +#include "imgIRequest.h" + +class CFavIconList; + +class IconObserver : public imgIDecoderObserver + + +{ + NS_DECL_ISUPPORTS + NS_DECL_IMGIDECODEROBSERVER + NS_DECL_IMGICONTAINEROBSERVER + + IconObserver(CFavIconList* favlist) : mFavList(favlist) {} + virtual ~IconObserver() { } + + NS_IMETHOD LoadIcon(nsIURI* iconUri, nsIURI* pageUri); + +protected: + CFavIconList* mFavList; + nsCOMPtr mRequest; + NS_IMETHOD CreateDIB(imgIRequest *aRequest); +}; + +class CFavIconList : public CImageList +{ +private: + CMap m_urlMap; + int m_iDefaultIcon; + int m_iLoadingIcon; + int m_iOffset; + + void AddMap(const char *uri, int index); + int AddDownloadedIcon(char* uri, TCHAR* file, nsresult aStatus); + BOOL LoadCache(); + BOOL WriteCache(); + +public: + CFavIconList(); + virtual ~CFavIconList(); + + int AddIcon(const char* uri, CBitmap*, CBitmap*); + int AddIcon(const char* uri, CBitmap*, COLORREF); + int AddIcon(const char* uri, HICON icon); + + int GetHostIcon(const TCHAR* aUri); + int GetIcon(nsIURI* aUri, BOOL download = FALSE); + + void RefreshIcon(nsIURI* aURI); + void ResetCache(); + void LoadDefaultIcon(); + + BOOL DwnFavIcon(nsIURI* iconURI); + static void DwnCall(char* , TCHAR* , nsresult, void* ); + + inline int GetDefaultIcon() {return m_iDefaultIcon;} + inline int GetLoadingIcon() {return m_iLoadingIcon;} + + BOOL Create(int, int, UINT, int, int); +}; + + diff --git a/k-meleon/FontPackageHandler.cpp b/k-meleon/FontPackageHandler.cpp new file mode 100644 index 00000000..13be1b63 --- /dev/null +++ b/k-meleon/FontPackageHandler.cpp @@ -0,0 +1,212 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include "stdafx.h" + +#if GECKO_VERSION < 19 + +#include "Fontpackagehandler.h" +#include "nsIFontPackageService.h" +#include "BrowserFrm.h" +#include "MfcEmbed.h" + +NS_IMPL_ISUPPORTS1(CFontPackageHandler, nsIFontPackageHandler); + +CFontPackageHandler::CFontPackageHandler(void) +{ +} + +CFontPackageHandler::~CFontPackageHandler(void) +{ +} + + +NS_IMETHODIMP CFontPackageHandler::NeedFontPackage(const char *aFontPackID) +{ + // no FontPackage is passed, return + NS_ENSURE_ARG_POINTER(aFontPackID); + + if (!strlen(aFontPackID)) + return NS_ERROR_UNEXPECTED; + + CMfcEmbedApp *pApp = (CMfcEmbedApp *)AfxGetApp(); + if (!pApp->preferences.GetBool("font.askWhenNeeded", true)) + return NS_OK; + + nsresult rv; + + // Should get that from chrome + CString cshandledLanguages; + cshandledLanguages.LoadString(IDS_HANDLED_LANGUAGES); + USES_CONVERSION; + const char* handledLanguages = T2CA(cshandledLanguages); + + // aFontPackID is of the form lang:xx or lang:xx-YY + const char *_langCode = strchr(aFontPackID,':'); + if (!_langCode || !*(_langCode + 1)) + return NS_ERROR_UNEXPECTED; + + char *langCode; + langCode = strdup(_langCode + 1); + strlwr(langCode); + + // check for xx or xx-yy in handled_languages + // if not handled, return now, don't show the font dialog + if (!strstr(handledLanguages, langCode)) + return NS_OK; // XXX should be error? + + HWND hWndTop; + HWND hWnd = CWnd::GetSafeOwner_(NULL, &hWndTop); + if (hWnd != hWndTop) + EnableWindow(hWnd, TRUE); + + CWnd* parent = CWnd::FromHandle(hWnd); + + // check windows version + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&vi); + if (vi.dwMajorVersion>4) + { + CFontNeededDialog* dlg = new CFontNeededDialog(langCode, parent); + rv = dlg->DoModal(); + } + else + { + CDownloadFontDialog* dlg = new CDownloadFontDialog(langCode, parent); + rv = dlg->DoModal(); + } + free(langCode); + + nsCOMPtr fontService(do_GetService(NS_FONTPACKAGESERVICE_CONTRACTID)); + NS_ENSURE_TRUE(fontService, NS_ERROR_FAILURE); + + fontService->FontPackageHandled(NS_SUCCEEDED(rv), PR_FALSE, aFontPackID); + return rv; + } + + +// Boîte de dialogue CDownloadFontDialog + +//IMPLEMENT_DYNAMIC(CDownloadFontDialog, CDialog) +CDownloadFontDialog::CDownloadFontDialog(const char* langcode, CWnd* pParent /*=NULL*/) + : CDialog(CDownloadFontDialog::IDD, pParent) +{ + USES_CONVERSION; + m_csFontName.LoadString(IDS_NAME_UNKNOW); + CString cshandledLanguages; + cshandledLanguages.LoadString(IDS_HANDLED_LANGUAGES); + char* handledLanguages = T2A(cshandledLanguages.GetBuffer(0)); + + int i=0; + char *token = strtok(handledLanguages, ", " ); + while( token != NULL ) + { + if (strcmp(token, langcode)==0) + { + m_csFontName.LoadString(IDS_NAME_FIRST + i); + m_csFontSize.LoadString(IDS_SIZE_FIRST + i); + break; + } + i++; + token = strtok(NULL, ", "); + } + + m_LangCode = langcode; +} + +CDownloadFontDialog::~CDownloadFontDialog() +{ +} + +void CDownloadFontDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Text(pDX, IDC_FONTNAME, m_csFontName); + DDX_Text(pDX, IDC_FONTSIZE, m_csFontSize); +} + + +BEGIN_MESSAGE_MAP(CDownloadFontDialog, CDialog) + ON_BN_CLICKED(IDOK, OnBnClickedOk) +END_MESSAGE_MAP() + + +// Gestionnaires de messages CDownloadFontDialog + +// Boîte de dialogue CFontNeededDialog + +//IMPLEMENT_DYNAMIC(CFontNeededDialog, CDialog) +CFontNeededDialog::CFontNeededDialog(const char* langcode, CWnd* pParent /*=NULL*/) + : CDialog(CFontNeededDialog::IDD, pParent) +{ + USES_CONVERSION; + m_csFontName.LoadString(IDS_NAME_UNKNOW); + CString cshandledLanguages; + cshandledLanguages.LoadString(IDS_HANDLED_LANGUAGES); + char* handledLanguages = T2A(cshandledLanguages.GetBuffer(0)); + + int i=0; + char *token = strtok(handledLanguages, ", " ); + while( token != NULL ) + { + if (strcmp(token, langcode)==0) + { + m_csFontName.LoadString(IDS_NAME_FIRST + i); + break; + } + i++; + token = strtok(NULL, ", "); + } + + m_LangCode = langcode; +} + +CFontNeededDialog::~CFontNeededDialog() +{ +} + +void CFontNeededDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Text(pDX, IDC_FONTNAME, m_csFontName); +} + + +BEGIN_MESSAGE_MAP(CFontNeededDialog, CDialog) +END_MESSAGE_MAP() + + +// Gestionnaires de messages CFontNeededDialog + + +void CDownloadFontDialog::OnBnClickedOk() +{ + CBrowserFrame* pFrm = theApp.CreateNewBrowserFrame(nsIWebBrowserChrome::CHROME_ALL, FALSE); + if(!pFrm) + return; + + pFrm->OpenURL( + _T("http://www.mozilla.org/projects/intl/fonts/win/redirect/package_") + m_LangCode + _T(".html")); + + pFrm->ShowWindow(SW_SHOW); + OnOK(); +} + +#endif // GECKO_VERSION \ No newline at end of file diff --git a/k-meleon/FontPackageHandler.h b/k-meleon/FontPackageHandler.h new file mode 100644 index 00000000..c9f3bde4 --- /dev/null +++ b/k-meleon/FontPackageHandler.h @@ -0,0 +1,88 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#pragma once + +#include "resource.h" +#include "nsIFontPackageHandler.h" +#include "DialogEx.h" + +/* a3328b5b-388c-4c9a-a5b7-2213621e1744 */ +#define NS_FONTPACKAGEHANDLER_CID \ +{ 0xa3328b5b, \ + 0x388c, \ + 0x4c9a, \ + {0xa5, 0xb7, 0x22, 0x13, 0x62, 0x1e, 0x17, 0x44} } + +class CFontPackageHandler : public nsIFontPackageHandler +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIFONTPACKAGEHANDLER + + CFontPackageHandler(void); + virtual ~CFontPackageHandler(void); +}; + + +// Boîte de dialogue CDownloadFontDialog + +class CDownloadFontDialog : public CDialog +{ + //DECLARE_DYNAMIC(CDownloadFontDialog) + +public: + CDownloadFontDialog(const char* langcode, CWnd* pParent = NULL); // constructeur standard + virtual ~CDownloadFontDialog(); + CString m_LangCode; + CString m_csFontName; + CString m_csFontSize; + +// Données de boîte de dialogue + enum { IDD = IDD_DOWNLOADFONT }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // Prise en charge DDX/DDV + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedOk(); +}; + + +// Boîte de dialogue CFontNeededDialog + +class CFontNeededDialog : public CDialog +{ + //DECLARE_DYNAMIC(CFontNeededDialog) + +public: + CFontNeededDialog(const char* langcode, CWnd* pParent = NULL); // constructeur standard + virtual ~CFontNeededDialog(); + CString m_LangCode; + CString m_csFontName; + +// Données de boîte de dialogue + enum { IDD = IDD_NEEDFONT }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // Prise en charge DDX/DDV + + DECLARE_MESSAGE_MAP() +}; diff --git a/k-meleon/GenKeyPairDialogs.cpp b/k-meleon/GenKeyPairDialogs.cpp new file mode 100644 index 00000000..8ad78ed5 --- /dev/null +++ b/k-meleon/GenKeyPairDialogs.cpp @@ -0,0 +1,112 @@ +/* +* Copyright (C) 2006 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include "stdafx.h" +#include "GenKeyPairDialogs.h" + +#include + +extern CWnd* CWndForDOMWindow(nsIDOMWindow *aWindow); + +NS_IMPL_ISUPPORTS1 (CGenKeyPairDialogs, nsIGeneratingKeypairInfoDialogs) + +CGenKeyPairDialogs::CGenKeyPairDialogs() +{ +} + +CGenKeyPairDialogs::~CGenKeyPairDialogs() +{ +} + +NS_IMETHODIMP CGenKeyPairDialogs::DisplayGeneratingKeypairInfo (nsIInterfaceRequestor *ctx, + nsIKeygenThread *runnable) +{ + nsCOMPtr parent = do_GetInterface (ctx); + CWnd* wnd = CWndForDOMWindow(parent); + if (wnd) + wnd = wnd->GetLastActivePopup(); + + CGenKeyPairDialog dlg(runnable, wnd); + dlg.DoModal(); + + return NS_OK; +} + +// Boîte de dialogue CGenKeyPairDialog + +//IMPLEMENT_DYNAMIC(CGenKeyPairDialog, CDialog) +CGenKeyPairDialog::CGenKeyPairDialog(nsIKeygenThread* runnable, CWnd* pParent /*=NULL*/) + : CDialog(CGenKeyPairDialog::IDD, pParent), mRunnable(runnable) +{ +} + +CGenKeyPairDialog::~CGenKeyPairDialog() +{ +} + +void CGenKeyPairDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); +} + + +BEGIN_MESSAGE_MAP(CGenKeyPairDialog, CDialog) + ON_MESSAGE(WM_USER+100, OnGenDone) +END_MESSAGE_MAP() + +NS_IMPL_ISUPPORTS1(GenKeyPairObserver, nsIObserver); + +NS_IMETHODIMP GenKeyPairObserver::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) +{ + if (mWnd) + mWnd->PostMessage(WM_USER+100, 0, 0); + return NS_OK; +} + +// Gestionnaires de messages CGenKeyPairDialog + +void CGenKeyPairDialog::OnCancel() +{ + /* CRASH + PRBool already_closed = FALSE; + mRunnable->UserCanceled(&already_closed); + CDialog::OnCancel();*/ +} + +BOOL CGenKeyPairDialog::OnInitDialog() +{ + CDialog::OnInitDialog(); + CWnd* okButton = GetDlgItem(IDOK); + if (okButton) + okButton->EnableWindow(FALSE); + + mObserver = new GenKeyPairObserver(this); + mRunnable->StartKeyGeneration(mObserver); + return TRUE; +} + +LRESULT CGenKeyPairDialog::OnGenDone(WPARAM, LPARAM) +{ + CWnd* okButton = GetDlgItem(IDOK); + if (okButton) + okButton->EnableWindow(TRUE); + OnOK(); + return 0; +} + diff --git a/k-meleon/GenKeyPairDialogs.h b/k-meleon/GenKeyPairDialogs.h new file mode 100644 index 00000000..e08dce68 --- /dev/null +++ b/k-meleon/GenKeyPairDialogs.h @@ -0,0 +1,75 @@ +/* +* Copyright (C) 2005 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#pragma once + +#include "DialogEx.h" +#include "resource.h" +#include + +// 6a8b1aff-ae8b-4751-982e-4ce5ad544100 +#define NS_NSSKEYPAIRDIALOGS_CID \ + {0x6a8b1aff, 0xae8b, 0x4751, {0x98, 0x2e, 0x4c, 0xe5, 0xad, 0x54, 0x41, 0x10}} + +#define GTK_NSSKEYPAIRDIALOGS_CLASSNAME "Gtk NSS Key Pair Dialogs" + +class CGenKeyPairDialogs : public nsIGeneratingKeypairInfoDialogs +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIGENERATINGKEYPAIRINFODIALOGS + + CGenKeyPairDialogs(); + virtual ~CGenKeyPairDialogs(); +}; + +class GenKeyPairObserver : public nsIObserver +{ +public: + NS_DECL_NSIOBSERVER + NS_DECL_ISUPPORTS + + GenKeyPairObserver(CWnd* wnd) : mWnd(wnd) {}; + virtual ~GenKeyPairObserver() {}; + + CWnd* mWnd; +}; + +class CGenKeyPairDialog : public CDialog +{ + //DECLARE_DYNAMIC(CGenKeyPairDialog) + +public: + CGenKeyPairDialog(nsIKeygenThread* runnable, CWnd* pParent = NULL); + virtual ~CGenKeyPairDialog(); + +// Données de boîte de dialogue + enum { IDD = IDD_GENKEYPAIR }; + +protected: + nsIKeygenThread* mRunnable; + nsCOMPtr mObserver; + virtual void DoDataExchange(CDataExchange* pDX); // Prise en charge DDX/DDV + + DECLARE_MESSAGE_MAP() + virtual void OnCancel(); + afx_msg LRESULT OnGenDone(WPARAM, LPARAM); +public: + virtual BOOL OnInitDialog(); +}; diff --git a/k-meleon/GenericDlg.cpp b/k-meleon/GenericDlg.cpp new file mode 100644 index 00000000..5a112232 --- /dev/null +++ b/k-meleon/GenericDlg.cpp @@ -0,0 +1,443 @@ +/* +* Copyright (C) 2006 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" +#include "GenericDlg.h" + + +const static BYTE tplGenericDlg[] = +{ + 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0xc8, 0x90, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x4d, 0x00, 0x53, 0x00, 0x20, 0x00, 0x53, 0x00, 0x68, 0x00, + 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6c, 0x00, 0x67, 0x00, 0x00, 0x00 +}; + +CGenericDlg::CGenericDlg(CWnd* pParent /*=NULL*/) +{ + m_pParentWnd = pParent; + m_hIcon = NULL; + m_hDlgIcon = NULL; + m_uDefault = -1; + m_uCancel = -1; + m_IsModeless = FALSE; +} + +INT_PTR CGenericDlg::DoModal() +{ + InitModalIndirect((LPCDLGTEMPLATE)tplGenericDlg, m_pParentWnd); + return CDialog::DoModal(); +} + +BOOL CGenericDlg::DoModeless() +{ + m_IsModeless = TRUE; + if (CreateIndirect((LPCDLGTEMPLATE)tplGenericDlg, m_pParentWnd)) { + ShowWindow(SW_SHOW); + return TRUE; + } + return FALSE; +} + +void CGenericDlg::AddButton(UINT nID, LPCTSTR pszText) +{ + ASSERT(nIDsize.cy) + { + BOOL stop = FALSE; + int maxSize = ::GetSystemMetrics(SM_CXFULLSCREEN)*2/3; + + // If the message is too narrow try to widen it to give + // it a better aspect. + int width = rect.Width(); + while (width maxSize) { + rect.right = maxSize; + stop = TRUE; + } + dc.DrawText(m_csMsgText, rect ,DT_CALCRECT|DT_WORDBREAK); + + // If the width is still the same than the previous one + // or narrower, stop too. We can't make it bigger. + if (stop || width >= rect.Width()) break; + width = rect.Width(); + } + } + + textSize.cx = rect.Width(); + textSize.cy = rect.Height(); + + // Compute the dialog size + CSize dlgSize; + + dlgSize.cx = max(textSize.cx + msgPadding, totalButtonsWidth); + dlgSize.cx = max(dlgSize.cx, cbxSize.cx + msgPadding); + dlgSize.cx = max(dlgSize.cx, editSize.cx + msgPadding); + dlgSize.cx += ConvX(BORDER_LEFT) + ConvX(BORDER_RIGHT); + + dlgSize.cy = + ConvY(BORDER_TOP) + ConvY(BORDER_BOTTOM) + + max(textSize.cy, iconSize.cy) + + (ned ? yMsgSpace + totalEditHeight : 0) + + (ncb ? yMsgSpace + totalCheckBoxHeight : 0) + + (nb ? yMsgSpace + buttonSize.cy : 0); + + int maxWidth = ::GetSystemMetrics(SM_CXFULLSCREEN) - 2*::GetSystemMetrics(SM_CXEDGE); + ASSERT(dlgSize.cx < maxWidth); + if (dlgSize.cx > maxWidth) dlgSize.cx = maxWidth; + + rc.SetRect(0, 0, dlgSize.cx, dlgSize.cy); + CalcWindowRect(rc); + MoveWindow(rc); + CenterWindow(); + + // Create and place the controls. + msgPadding = max( (dlgSize.cx - max(baseWidth, textSize.cx) - msgPadding)/2 + msgPadding, + ConvX(BORDER_LEFT) + msgPadding); + + // Message + m_edCtrl.Create(m_csMsgText, WS_CHILD|WS_VISIBLE|SS_LEFT, CRect(0,0,0,0), this, (UINT)IDC_STATIC); + //m_edCtrl.Create(WS_CHILD|WS_VISIBLE|ES_LEFT|ES_MULTILINE|ES_READONLY, CRect(0,0,0,0), this, (UINT)IDC_STATIC); + //m_edCtrl.SetBackgroundColor(FALSE, ::GetSysColor(COLOR_3DFACE)); + m_edCtrl.SetFont(GetFont()); + + m_edCtrl.MoveWindow( + msgPadding, + ConvY(BORDER_TOP), + textSize.cx, + textSize.cy); + + // Icon + if (m_hIcon) + { + m_stIconCtrl.Create(NULL, WS_CHILD|WS_VISIBLE|WS_DISABLED|SS_ICON, CRect(0,0,0,0), this); + m_stIconCtrl.SetIcon(m_hIcon); + m_stIconCtrl.MoveWindow( + ConvX(BORDER_LEFT), + ConvY(BORDER_TOP), + iconSize.cx, + iconSize.cy); + } + + // Edit controls + int bx = msgPadding; + int by = ConvY(BORDER_TOP) + max(textSize.cy, iconSize.cy) + yMsgSpace; + + for(int i=0;iSetFocus(); + return FALSE; + } + } + + return TRUE; +} + +BOOL CGenericDlg::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) +{ + if(pHandlerInfo == NULL && nCode == CN_COMMAND) + { + // Look if it's one of the button, since it could also + // be also one of the checkbox. + int nb = (int)m_aButtons.GetSize(); + for (int i=0;imessage==WM_KEYDOWN) + { + if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_CANCEL) + { + if (m_uCancel != -1) + CloseDialog(m_uCancel); + return TRUE; + } + } + + return CDialog::PreTranslateMessage(pMsg); +} + +void CGenericDlg::CloseDialog(int nResult) +{ + int ncb = (int)m_aCheckBoxes.GetSize(); + for (int i=0;iresult) = IsDlgButtonChecked(cbi->id); + } + + int ned = (int)m_aEdits.GetSize(); + for (int i=0;iid); + ASSERT(pEdit); + if (pEdit) + pEdit->GetWindowText(*(ei->result)); + } + + if (m_IsModeless) + DestroyWindow(); + else + EndDialog(nResult); +} + +void CGenericDlg::PostNcDestroy() +{ + CDialog::PostNcDestroy(); + if (m_IsModeless) + delete this; +} + +void CGenericDlg::OnClose() +{ + if (m_uCancel != -1) + CloseDialog(m_uCancel); +} diff --git a/k-meleon/GenericDlg.h b/k-meleon/GenericDlg.h new file mode 100644 index 00000000..d786e158 --- /dev/null +++ b/k-meleon/GenericDlg.h @@ -0,0 +1,140 @@ +/* +* Copyright (C) 2006 Dorian Boissonnade +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef _GENERIC_DLG_H +#define _GENERIC_DLG_H + +#include "afxwin.h" +#include "afxtempl.h" +#include "DialogEx.h" +// boîte de dialogue CGenericDlg +class CGenericDlg : public CDialog +{ + // Construction +public: + CGenericDlg(CWnd* pParent = NULL); // constructeur standard + + void AddButton(UINT nID, LPCTSTR pszText); + void AddButton(UINT nID, UINT nIDText); + + inline void SetDefaultButton(UINT id) { m_uDefault = id; } + inline void SetCancelButton(UINT id) { m_uCancel = id; } + + inline void SetTitle(LPCTSTR pszTitle) { m_csTitle = pszTitle; } + inline void SetMsg(LPCTSTR pszMsg) { m_csMsgText = pszMsg; } + + inline void SetMsgIcon(HICON hIcon) { m_hIcon = hIcon; } + inline void SetDlgIcon(HICON hIcon) { m_hDlgIcon = hIcon; } + + void AddCheckBox(BOOL* result, LPCTSTR pszCheckMsg); + void AddCheckBox(BOOL* result, UINT nIDText); + + void AddEdit(CString* result, LPCTSTR pszCheckMsg, BOOL password = FALSE); + void AddEdit(CString* result, UINT nIDText, BOOL password = FALSE); + + INT_PTR DoModal(); + BOOL DoModeless(); + +protected: + //virtual void DoDataExchange(CDataExchange* pDX); // Prise en charge DDX/DDV + + // Implémentation +protected: + HICON m_hIcon; + HICON m_hDlgIcon; + CString m_csTitle; + CString m_csMsgText; + CString m_csCheckBoxText; + CStatic m_stIconCtrl; + CStatic m_edCtrl; + + BOOL m_bCheckBoxValue; + UINT m_uDefault; + UINT m_uCancel; + BOOL m_IsModeless; + + struct ButtonInfos + { + UINT id; + CString text; + }; + + CArray m_aButtons; + + struct CheckBoxInfos + { + UINT id; + BOOL* result; + CString text; + }; + + CArray m_aCheckBoxes; + + struct EditInfos + { + UINT id; + BOOL password; + CString* result; + CString label; + }; + + CArray m_aEdits; + + enum { BORDER_TOP = 10 }; + enum { BORDER_BOTTOM = 10 }; + enum { BORDER_LEFT = 10 }; + enum { BORDER_RIGHT = 10 }; + enum { MSG_SPACE = 8 }; + enum { BUTTON_SPACE = 5 }; + enum { BUTTON_MIN = 40 }; + enum { BUTTON_MARGIN_X = 5 }; + enum { BUTTON_MARGIN_Y = 3 }; + + enum { CHECKBOX_SPACE = 1 }; + + enum {EDIT_SPACE = 2}; + enum {EDIT_LABEL_SPACE = 2}; + enum {EDIT_SIZE_X = 120}; + + enum { MSG_BASE_WIDTH = 100 }; + enum { MSG_RATIO_BASE = 100 }; + enum { MSG_RATIO = 5 }; + + enum { CHECKBOX_FIRST_ID = 60000 }; + enum { EDIT_FIRST_ID = 61000 }; + + CSize m_bu; + enum { DLGX = 10 }; + enum { DLGY = 10 }; + inline int ConvX(int x){ return MulDiv((int)(x), m_bu.cx, DLGX); } + inline int ConvY(int y){ return MulDiv((int)(y), m_bu.cy, DLGY); } + + // Fonctions générées de la table des messages + virtual BOOL OnInitDialog(); + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); + virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual void CloseDialog(int nResult); +protected: + virtual void PostNcDestroy(); +public: + afx_msg void OnClose(); +}; + +#endif //_GENERIC_DLG_H diff --git a/k-meleon/HiddenWnd.cpp b/k-meleon/HiddenWnd.cpp new file mode 100644 index 00000000..a604242f --- /dev/null +++ b/k-meleon/HiddenWnd.cpp @@ -0,0 +1,347 @@ +/* +* Copyright (C) 2001 Jeff Doozan +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" +#include "HiddenWnd.h" +#include "BrowserView.h" //XX +#include "SaveAsHandler.h" + +BEGIN_MESSAGE_MAP(CHiddenWnd, CFrameWnd) + //{{AFX_MSG_MAP(CHiddenWnd) + ON_WM_CREATE() + ON_WM_CLOSE() + ON_WM_COPYDATA() + ON_WM_ENDSESSION() + ON_MESSAGE(UWM_NEWWINDOW, OnNewWindow) + ON_MESSAGE(UWM_PERSIST_SET, OnSetPersist) + ON_MESSAGE(UWM_PERSIST_SHOW, OnShowBrowser) + ON_MESSAGE(WM_DEFERSHOW, OnDeferShow) + ON_MESSAGE(WM_DEFERSAVEAS, OnDeferSaveAs) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +BOOL CHiddenWnd::PreCreateWindow(CREATESTRUCT& cs) { + + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + cs.lpszClass = HIDDEN_WINDOW_CLASS; + + return TRUE; +} + +int CHiddenWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { + + // Check if the tray control is running, and get the persist setting from it + QueryPersistFlags(); + USES_CONVERSION; + if (m_bStayResident) + StayResident(); + else { + BOOL webapp = theApp.cmdline.GetSwitch("-webapp", NULL, TRUE)>=0; + if (!ShowBrowser(A2T(theApp.cmdline.m_sCmdLine), webapp, TRUE)) + return -1; + } + + return CFrameWnd::OnCreate(lpCreateStruct); +} + +void CHiddenWnd::QueryPersistFlags() { + HWND hwndLoader = ::FindWindowEx(NULL, NULL, _T("KMeleon Tray Control"), NULL); + if (hwndLoader) { + LRESULT flags = ::SendMessage(hwndLoader, UWM_PERSIST_GET, NULL, NULL); + + m_bStayResident = ((flags & PERSIST_BROWSER)); + m_bPreloadWindow = ((flags & PERSIST_WINDOW)); + m_bPreloadStartPage = ((flags & PERSIST_STARTPAGE)); + m_bShowNow = ((flags & PERSIST_SHOWNOW)); + + // a little sanity checking + if (m_bPreloadWindow && !m_bStayResident) + m_bPreloadWindow = FALSE; + if (m_bPreloadStartPage && ! m_bPreloadWindow) + m_bPreloadStartPage = FALSE; + } + else { + m_bStayResident = FALSE; + m_bPreloadWindow = FALSE; + m_bPreloadStartPage = FALSE; + m_bShowNow = FALSE; + } +} + +void CHiddenWnd::OnClose() { + // if we're not staying resident, call the default handler, which will exit + if (!m_bStayResident) { + CFrameWnd::OnClose(); + return; + } + + // make sure the loader hasn't exited without notifying us + HWND hwndLoader = ::FindWindowEx(NULL, NULL, _T("KMeleon Tray Control"), NULL); + if (!hwndLoader) { + CFrameWnd::OnClose(); + return; + } + + // else close all the browser windows and stay resident + CBrowserFrame* pBrowserFrame = NULL; + + POSITION pos = theApp.m_FrameWndLst.GetHeadPosition(); + while( pos != NULL ) { + pBrowserFrame = (CBrowserFrame *) theApp.m_FrameWndLst.GetNext(pos); + if(pBrowserFrame) { + pBrowserFrame->ShowWindow(false); + pBrowserFrame->DestroyWindow(); + } + } + theApp.m_FrameWndLst.RemoveAll(); + StayResident(); +} + +LRESULT CHiddenWnd::OnSetPersist(WPARAM flags, LPARAM lParam) { + BOOL bNewStayResident = (flags & PERSIST_BROWSER); + BOOL bNewPreloadWindow = (flags & PERSIST_WINDOW); + BOOL bNewPreloadStartPage = (flags & PERSIST_STARTPAGE); + + // a little sanity checking + if (bNewPreloadWindow && !bNewStayResident) + bNewPreloadWindow = FALSE; + if (bNewPreloadStartPage && ! bNewPreloadWindow) + bNewPreloadStartPage = FALSE; + + + // update the hidden window with the new settings + if (m_bPersisting) { + + // exit kmeleon if the stay resident flag is cleared + if (!bNewStayResident) + PostMessage(WM_QUIT); +/* + // preload the window + if (bNewPreloadWindow && !m_bPreloadWindow) { + m_pHiddenBrowser = theApp.CreateNewBrowserFrame(nsIWebBrowserChrome::CHROME_ALL, + -1, -1, -1, -1, PR_FALSE); + if (bNewPreloadStartPage) + m_pHiddenBrowser->m_wndBrowserView.LoadHomePage(); + else + m_pHiddenBrowser->m_wndBrowserView.OpenURL("about:blank"); + } + + // don't preload the window + if (!bNewPreloadWindow && m_bPreloadWindow) { + m_pHiddenBrowser->DestroyWindow(); + POSITION pos = theApp.m_FrameWndLst.Find(m_pHiddenBrowser); + theApp.m_FrameWndLst.RemoveAt(pos); + } + + // preload the start page + if (bNewPreloadStartPage && !m_bPreloadStartPage) + m_pHiddenBrowser->m_wndBrowserView.LoadHomePage(); + + // don't preload the start page + if (bNewPreloadWindow && !bNewPreloadStartPage && m_bPreloadStartPage) + m_pHiddenBrowser->m_wndBrowserView.OpenURL("about:blank");*/ + } + + m_bStayResident = bNewStayResident; + m_bPreloadWindow = bNewPreloadWindow; + m_bPreloadStartPage = bNewPreloadStartPage; + + return 0; +} + +LRESULT CHiddenWnd::OnShowBrowser(WPARAM URI, LPARAM lParam) { + USES_CONVERSION; + ShowBrowser(A2T((char*)URI)); + + return 0; +} + +BOOL CHiddenWnd::ShowBrowser(LPTSTR URI, BOOL webapp, BOOL atStart) { + + // if we already have a browser, load home page (if necessary), and show the window + /* if (m_bPersisting && m_bPreloadWindow) { + if (URI && *URI) { + if (*URI == _T('\"')) URI++; + int len = _tcslen(URI); + if (URI[len-1] == _T('\"')) URI[len-1] = 0; + m_pHiddenBrowser->m_wndBrowserView.OpenURL(URI); + } + else { + m_pHiddenBrowser->SetFocus(); + // m_pHiddenBrowser->m_wndUrlBar.MaintainFocus(); + if (!m_bPreloadStartPage) + m_pHiddenBrowser->m_wndBrowserView.LoadHomePage(); + } + + if (theApp.preferences.bMaximized) m_pHiddenBrowser->ShowWindow(SW_MAXIMIZE); + else m_pHiddenBrowser->ShowWindow(SW_SHOW); + m_pHiddenBrowser->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); + } + + // otherwise, just create a new browser + else */{ + + // If we already have a browser and no url, do nothing. + // This is to accomodate the session plugin + if ( atStart && (!URI || !*URI) && theApp.m_pMostRecentBrowserFrame) + return TRUE; + + int openmode = theApp.preferences.GetInt("browser.link.open_external", 2); + CBrowserFrame* browser = NULL; + if (webapp) { + PRUint32 chromeMask = nsIWebBrowserChrome::CHROME_WINDOW_RESIZE | + nsIWebBrowserChrome::CHROME_WINDOW_CLOSE | + nsIWebBrowserChrome::CHROME_TITLEBAR | + nsIWebBrowserChrome::CHROME_WINDOW_MIN; + browser = theApp.CreateNewBrowserFrame(chromeMask, FALSE, NULL); + } else if (openmode == 2 || !theApp.m_pMostRecentBrowserFrame ) { + browser = theApp.CreateNewBrowserFrame(); + //browser->ShowWindow(SW_SHOW); + } else { + if (theApp.m_pMostRecentBrowserFrame) { + browser = theApp.m_pMostRecentBrowserFrame; + CBrowserGlue* glue = browser->GetActiveView()->GetBrowserGlue(); + if (glue) if (!glue->ReuseWindow(openmode == 1)) browser = theApp.CreateNewBrowserFrame(); //XXXXXX + } + } + + if (!browser) { + AfxMessageBox(IDS_FAILED_TO_CREATE_BROWSER); + return FALSE; + } + + if (URI && *URI) { + // if the URI is in quotes, strip them off + int len = _tcslen(URI); + if (URI[0] == _T('"')) { + if (URI[len-1] == _T('"')) URI[len-1] = 0; + URI++; + } + browser->OpenURL(URI); + } + else { + // browser->m_wndUrlBar.MaintainFocus(); + browser->GetActiveView()->LoadHomePage(); + } + + // Bullshit: the first window in never maximized + if (atStart && theApp.preferences.bMaximized) + browser->ShowWindow(SW_SHOWMAXIMIZED); + else + browser->ShowWindow(SW_SHOW); + browser->SetForegroundWindow(); + } + + m_bPersisting = FALSE; + return TRUE; +} + +int CHiddenWnd::Persisting() { + if (m_bPersisting) + return PERSIST_STATE_PERSISTING; + if (m_bStayResident) + return PERSIST_STATE_ENABLED; + return PERSIST_STATE_DISABLED; +} + + +BOOL CHiddenWnd::StayResident() { + + // if the ShowNow flag is set, we're not really going to stay resident + if (m_bShowNow) { + m_bShowNow = FALSE; + m_bPersisting = FALSE; + + ShowBrowser(); + } + + else { + m_bPersisting = TRUE; +/* + if (m_bPreloadWindow) { + m_pHiddenBrowser = theApp.CreateNewBrowserFrame(nsIWebBrowserChrome::CHROME_ALL, + -1, -1, -1, -1, PR_FALSE); + if (!m_pHiddenBrowser) + return FALSE; + + if (m_bPreloadStartPage) + m_pHiddenBrowser->m_wndBrowserView.LoadHomePage(); + else + m_pHiddenBrowser->m_wndBrowserView.OpenURL("about:blank"); + }*/ + } + + return TRUE; +} + + + +// This is called from another instance of Kmeleon (via the UWM_NEWWINDOW message), +// when no command line paramaters have been specified +LRESULT CHiddenWnd::OnNewWindow(WPARAM wParam, LPARAM lParam) { + ShowBrowser(); + + return 0; +} + +// This is called from another instance of Kmeleon, +// and contains any command line parameters specified +BOOL CHiddenWnd::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { + + CCmdLine cmdline; + USES_CONVERSION; + cmdline.Initialize((LPSTR) pCopyDataStruct->lpData); + BOOL webapp = cmdline.GetSwitch("-webapp", NULL, TRUE)>=0; + ShowBrowser(A2T(cmdline.m_sCmdLine), webapp); + + return true; +} + +//////////////////////////////////////////////////////////////////////// +// Lame download defering + +#include "UnknownContentTypeHandler.h" + +LRESULT CHiddenWnd::OnDeferShow(WPARAM wParam, LPARAM lParam) +{ + if (!lParam) return 0; + return ((CUnknownContentTypeHandler*)lParam)->Show((CWnd*)wParam); +} + +LRESULT CHiddenWnd::OnDeferSaveAs(WPARAM wParam, LPARAM lParam) +{ + if (!lParam || !wParam) return 0; + CSaveAsHandler* handler = (CSaveAsHandler*)wParam; + + nsresult rv = handler->Save((char*)lParam); + NS_RELEASE(handler); + free((char*)lParam); + return rv; +} + +void CHiddenWnd::OnEndSession(BOOL bEnding) +{ + if (!bEnding) return; + // If we try to close anything then windows will trash us, + // so remove all windows from the lists. + theApp.m_FrameWndLst.RemoveAll(); + theApp.m_MiscWndLst.RemoveAll(); + CFrameWnd::OnEndSession(bEnding); +} diff --git a/k-meleon/HiddenWnd.h b/k-meleon/HiddenWnd.h new file mode 100644 index 00000000..59daa1c3 --- /dev/null +++ b/k-meleon/HiddenWnd.h @@ -0,0 +1,83 @@ +/* +* Copyright (C) 2001 Jeff Doozan +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +///////////////////////////////////////////////////////////////////////////// +// CHiddenWnd: +// The Evil Hidden window is used to keep mozilla running while all browser +// windows are closed during a profile change +// Now also used to receive notification messages from the tray icon + + +#include "MfcEmbed.h" +#include "KmeleonConst.h" +#include "BrowserFrm.h" + +class CHiddenWnd : public CFrameWnd { + +public: + + // returns the current state of the browser + // 0 - don't stay resident + // 1 - stay resident + // 2 - currently staying resident + int Persisting(); + + BOOL StayResident(); + +private: + + void QueryPersistFlags(); + BOOL ShowBrowser(LPTSTR URI=NULL, BOOL webapp = FALSE, BOOL atStart = FALSE); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CHiddenWnd) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + + + //{{AFX_MSG(CHiddenWnd) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnClose(); + afx_msg void OnEndSession(BOOL bEnding); + afx_msg LRESULT OnSetPersist(WPARAM flags, LPARAM lParam); + afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct); + afx_msg LRESULT OnNewWindow(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnShowBrowser(WPARAM URI, LPARAM lParam); + afx_msg LRESULT OnDeferShow(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnDeferSaveAs(WPARAM wParam, LPARAM lParam); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + BOOL m_bPersisting; + BOOL m_bStayResident; + BOOL m_bPreloadWindow; + BOOL m_bPreloadStartPage; + BOOL m_bShowNow; + CBrowserFrame* m_pHiddenBrowser; + + BOOL m_bFirstWindowCreated; + // used to process the rebar DrawToolbarMenu function, which must only + // be called once, but must be called after the first window has been created + +}; + + diff --git a/k-meleon/IBrowserFrameGlue.h b/k-meleon/IBrowserFrameGlue.h new file mode 100644 index 00000000..4218bb62 --- /dev/null +++ b/k-meleon/IBrowserFrameGlue.h @@ -0,0 +1,192 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: Mozilla-sample-code 1.0 + * + * Copyright (c) 2002 Netscape Communications Corporation and + * other contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this Mozilla sample software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * Chak Nanga + * + * ***** END LICENSE BLOCK ***** */ + +// This interface acts as a glue between the required/optional +// Gecko embedding interfaces and the actual platform specific +// way of doing things - such as updating a statusbar etc. +// +// For ex, in the mfcembed sample the required interfaces such as +// IWebBrowserChrome etc. are implemented in a XP way in the +// BrowserImp*.cpp files. However, when they get called to update the +// statusbar etc. they call on this interface to get the actual job +// done. During the BrowserFrame creation some object must implement +// this interface and pass the pointer to it via the Init() member of +// the CBrowserImpl class + +#ifndef _IBROWSERFRAMEGLUE_H +#define _IBROWSERFRAMEGLUE_H + +class CBrowserWrapper; + +struct IBrowserGlue { + // Progress Related Methods + virtual void UpdateStatusBarText(LPCTSTR aMessage) = 0; + virtual void UpdateProgress(int aCurrent, int aMax) = 0; + virtual void UpdateBusyState(BOOL aBusy) = 0; + virtual void UpdateCurrentURI(nsIURI *aLocation) = 0; + virtual void UpdateSecurityStatus(int aState) = 0; + + // BrowserFrame Related Methods + virtual CBrowserWrapper* ReuseWindow(BOOL useCurrent) = 0; + virtual void DestroyBrowserFrame() = 0; + virtual void GetBrowserTitle(CString& aTitle) = 0; + virtual void SetBrowserTitle(LPCTSTR aTitle) = 0; + virtual void SetBrowserSize(int aCX, int aCY) = 0; + virtual void SetVisibility(BOOL aVisible) = 0; + virtual void GetVisibility(BOOL *aVisible) = 0; + virtual void SetFocus() = 0; + + // ContextMenu Related Methods + virtual void ShowContextMenu(UINT aContextFlags, nsIDOMNode* node) = 0; + + //Prompt Related Methods + virtual HWND GetBrowserFrameNativeWnd() = 0; + + // Tooltip function + virtual void ShowTooltip(int x, int y, LPCTSTR text) = 0; + + virtual BOOL FocusNextElement() = 0; + virtual BOOL FocusPrevElement() = 0; + virtual BOOL MouseAction(nsIDOMNode *node, UINT flags) = 0; + virtual void PopupBlocked(const char* uri) = 0; + virtual void SetFavIcon(nsIURI* favUri) = 0; + virtual ~IBrowserGlue() {}; +}; + +#define NS_DECL_BROWSERGLUE \ + public: \ + virtual void UpdateStatusBarText(LPCTSTR aMessage); \ + virtual void UpdateProgress(int aCurrent, int aMax); \ + virtual void UpdateBusyState(PRBool aBusy); \ + virtual void UpdateCurrentURI(nsIURI *aLocation); \ + virtual void UpdateSecurityStatus(int aState); \ + virtual CBrowserWrapper* ReuseWindow(BOOL useCurrent); \ + virtual CBrowserWrapper* CreateNewBrowser(PRUint32 chromeMask); \ + virtual void DestroyBrowserFrame(); \ + virtual void SetBrowserSize(int aCX, int aCY); \ + virtual void GetBrowserTitle(CString& aTitle); \ + virtual void SetBrowserTitle(LPCTSTR aTitle); \ + virtual void SetVisibility(BOOL aVisible); \ + virtual void GetVisibility(BOOL *aVisible); \ + virtual void SetFocus(); \ + virtual void ShowContextMenu(UINT aContextFlags, nsIDOMNode* node); \ + virtual HWND GetBrowserFrameNativeWnd(); \ + virtual void ShowTooltip(int x, int y, LPCTSTR text); \ + virtual BOOL FocusNextElement(); \ + virtual BOOL FocusPrevElement(); \ + virtual BOOL MouseAction(nsIDOMNode *node, UINT flags);\ + virtual void PopupBlocked(const char* uri);\ + virtual void SetFavIcon(nsIURI* favUri);\ + +typedef IBrowserGlue *PBROWSERGLUE; + +struct IBrowserFrameGlue { + // Progress Related Methods + virtual void UpdateStatusBarText(const PRUnichar *aMessage) = 0; + virtual void UpdateProgress(PRInt32 aCurrent, PRInt32 aMax) = 0; + virtual void UpdateBusyState(PRBool aBusy) = 0; + virtual void UpdateCurrentURI(nsIURI *aLocation) = 0; + virtual void UpdateSecurityStatus(PRInt32 aState) = 0; + + // BrowserFrame Related Methods + virtual PRBool CreateNewBrowserFrame(PRUint32 chromeMask, + PRInt32 x, PRInt32 y, + PRInt32 cx, PRInt32 cy, + nsIWebBrowser ** aWebBrowser) = 0; + virtual void DestroyBrowserFrame() = 0; + virtual void GetBrowserFrameTitle(PRUnichar **aTitle) = 0; + virtual void SetBrowserFrameTitle(const PRUnichar *aTitle) = 0; + virtual void SetBrowserSize(PRInt32 aCX, PRInt32 aCY) = 0; + /*virtual void GetBrowserFramePosition(PRInt32 *aX, PRInt32 *aY) = 0; + virtual void SetBrowserFramePosition(PRInt32 aX, PRInt32 aY) = 0; + virtual void GetBrowserFrameSize(PRInt32 *aCX, PRInt32 *aCY) = 0; + virtual void SetBrowserFrameSize(PRInt32 aCX, PRInt32 aCY) = 0; + virtual void GetBrowserSize(PRInt32 *aCX, PRInt32 *aCY) = 0; + virtual void GetBrowserFramePositionAndSize(PRInt32 *aX, PRInt32 *aY, PRInt32 *aCX, PRInt32 *aCY) = 0; + virtual void SetBrowserFramePositionAndSize(PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY, PRBool fRepaint) = 0; + virtual void SetBrowserPositionAndSize(PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY, PRBool fRepaint) = 0;*/ + virtual void ShowBrowserFrame(PRBool aShow) = 0; + virtual void SetFocus() = 0; + virtual void FocusAvailable(PRBool *aFocusAvail) = 0; + virtual void GetBrowserFrameVisibility(PRBool *aVisible) = 0; + + // ContextMenu Related Methods + virtual void ShowContextMenu(PRUint32 aContextFlags, nsIContextMenuInfo *aInfo) = 0; + + //Prompt Related Methods + virtual HWND GetBrowserFrameNativeWnd() = 0; + + // Tooltip function + virtual void ShowTooltip(PRInt32 x, PRInt32 y, const TCHAR *text) = 0; + + virtual BOOL FocusNextElement() = 0; + virtual BOOL FocusPrevElement() = 0; + virtual BOOL MouseAction(nsIDOMNode *node, UINT flags) = 0; + virtual void PopupBlocked(const char* uri) = 0; + virtual void SetFavIcon(nsIURI* favUri) = 0; +}; + +#define NS_DECL_BROWSERFRAMEGLUE \ + public: \ + virtual void UpdateStatusBarText(const PRUnichar *aMessage); \ + virtual void UpdateProgress(PRInt32 aCurrent, PRInt32 aMax); \ + virtual void UpdateBusyState(PRBool aBusy); \ + virtual void UpdateCurrentURI(nsIURI *aLocation); \ + virtual void UpdateSecurityStatus(PRInt32 aState); \ + virtual PRBool CreateNewBrowserFrame(PRUint32 chromeMask, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy, nsIWebBrowser** aWebBrowser); \ + virtual void DestroyBrowserFrame(); \ + virtual void SetBrowserSize(PRInt32 aCX, PRInt32 aCY); \ + virtual void GetBrowserFrameTitle(PRUnichar **aTitle); \ + virtual void SetBrowserFrameTitle(const PRUnichar *aTitle); \ + /*virtual void GetBrowserFramePosition(PRInt32 *aX, PRInt32 *aY); \ + virtual void SetBrowserFramePosition(PRInt32 aX, PRInt32 aY); \ + virtual void GetBrowserFrameSize(PRInt32 *aCX, PRInt32 *aCY); \ + virtual void SetBrowserFrameSize(PRInt32 aCX, PRInt32 aCY); \ + virtual void GetBrowserSize(PRInt32 *aCX, PRInt32 *aCY); \ + virtual void GetBrowserFramePositionAndSize(PRInt32 *aX, PRInt32 *aY, PRInt32 *aCX, PRInt32 *aCY); \ + virtual void SetBrowserFramePositionAndSize(PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY, PRBool fRepaint); \ + virtual void SetBrowserPositionAndSize(PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY, PRBool fRepaint); */\ + virtual void ShowBrowserFrame(PRBool aShow); \ + virtual void SetFocus(); \ + virtual void FocusAvailable(PRBool *aFocusAvail); \ + virtual void GetBrowserFrameVisibility(PRBool *aVisible); \ + virtual void ShowContextMenu(PRUint32 aContextFlags, nsIContextMenuInfo *aInfo); \ + virtual HWND GetBrowserFrameNativeWnd(); \ + virtual void ShowTooltip(PRInt32 x, PRInt32 y, const TCHAR *text); \ + virtual BOOL FocusNextElement(); \ + virtual BOOL FocusPrevElement(); \ + virtual BOOL MouseAction(nsIDOMNode *node, UINT flags);\ + virtual void PopupBlocked(const char* uri);\ + virtual void SetFavIcon(nsIURI* favUri);\ + +typedef IBrowserFrameGlue *PBROWSERFRAMEGLUE; + +#endif //_IBROWSERFRAMEGLUE_H diff --git a/k-meleon/Install/GNUlicense.txt b/k-meleon/Install/GNUlicense.txt new file mode 100644 index 00000000..731cd11a --- /dev/null +++ b/k-meleon/Install/GNUlicense.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. \ No newline at end of file diff --git a/k-meleon/Install/K-Meleon.bmp b/k-meleon/Install/K-Meleon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..101006f4820c40ba457bb418fae4d911ef9b9eef GIT binary patch literal 154542 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
NN znjnjf_6W;%9X9c`G2t0_Px9{kU`I~~bZ!Q2DJUv2phyh~7IY@2u&_6yDDK#9AA39e|xkmWoQq8ib7m8ifHhzFIB? zen5c(5CcJ|A)23B-zadf_DJ6oDYkjMSrq48GRETqefKL2cPVhCM#U#7p}gg$0;U2T z@It{Np7u*0=Pa}j++8a+bORkeO7yrNS>{>E9UTS{ZEkH*Hd*Ul7BtZ~jkK`V5NVVK z@4`B8jy)MRxHLnYH2y0-{$=F}Z+U{nLbeGDodBzt+L`BaAlF)LD6HK>vw4t~s_ndz zPldE{mlAT7#byA_#(5kw2{jl2K^SY4w(Df9FqqEVhDy0vZ~{L_sNtWG>rO|L4-6Kq zi_Wz3jrrx2=S|ehJC9uF zN8U@qVX{}4)5KV((g*A6)vy!d*?o12X>S>QZac~w(|_>WwlPznEGDcg>iXTqhYb zPw(4Qa&!q41h;2~8|j8af?;~}xzEM$YMupaE`}^Lv&1;UQZv~ocD6{TGP_8bfGcGi zO$ty0WNw9fG3~G9e*84G1}+*7AAy+G7zljJU&`pK^rZu3q!>>gdB;-%*2bCduAT0M z8;n58AoIO@%(8(d$hJb%|4v?KA^Dr%#QpGwO=K5#0cC#Z**YQogrFKw~<=3qdyHnCzj8 zmkt!*3OWyK^|#M&cRqO%HzO=~xN4p)eD^$`yx9!GkdbS$(-LjewaZuP9oY(jUeQ=# zwkti+h&S?fD1ZX*PO4TRZY{WJZ#naH9vL(Nyl?_XOHzPOg=~U5!50^z3ZRkEf@r|X zMIeTChP*sw5t*E>1*AAdg!h_c`T8X!l%2T)m=1hJhigB$Y_IcQ`J~S2`$!6GHMUF27Ri7M$#{M?f?O_huR~>*})Z*$dx$q4%tBXRtK9>R^5S z)ep50H}$DmK^}prLwp>YXYPh>CYz=bJ-LCy<3Cwwm@;K-sja­Y^Lp;2 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 H0Sf$o>)Djc literal 0 HcmV?d00001 diff --git a/k-meleon/Install/K-MeleonUNINST.ini b/k-meleon/Install/K-MeleonUNINST.ini new file mode 100644 index 00000000..33060805 --- /dev/null +++ b/k-meleon/Install/K-MeleonUNINST.ini @@ -0,0 +1 @@ +; KMeleon uninstall file diff --git a/k-meleon/Install/License.txt b/k-meleon/Install/License.txt new file mode 100644 index 00000000..1f57fdbc --- /dev/null +++ b/k-meleon/Install/License.txt @@ -0,0 +1,916 @@ +K-Meleon is licensed under the GNU General Public License (GPL). +The Gecko(tm) engine is subject to the Mozilla Public License (as shown below the GPL). + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + + + +The Gecko(tm) engine is subject to the Mozilla Public License license : + + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + + ---------------------------------------------------------------------- + + AMENDMENTS + + The Netscape Public License Version 1.1 ("NPL") consists of the + Mozilla Public License Version 1.1 with the following Amendments, + including Exhibit A-Netscape Public License. Files identified with + "Exhibit A-Netscape Public License" are governed by the Netscape + Public License Version 1.1. + + Additional Terms applicable to the Netscape Public License. + I. Effect. + These additional terms described in this Netscape Public + License -- Amendments shall apply to the Mozilla Communicator + client code and to all Covered Code under this License. + + II. "Netscape's Branded Code" means Covered Code that Netscape + distributes and/or permits others to distribute under one or more + trademark(s) which are controlled by Netscape but which are not + licensed for use under this License. + + III. Netscape and logo. + This License does not grant any rights to use the trademarks + "Netscape", the "Netscape N and horizon" logo or the "Netscape + lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript", + "Smart Browsing" even if such marks are included in the Original + Code or Modifications. + + IV. Inability to Comply Due to Contractual Obligation. + Prior to licensing the Original Code under this License, Netscape + has licensed third party code for use in Netscape's Branded Code. + To the extent that Netscape is limited contractually from making + such third party code available under this License, Netscape may + choose to reintegrate such code into Covered Code without being + required to distribute such code in Source Code form, even if + such code would otherwise be considered "Modifications" under + this License. + + V. Use of Modifications and Covered Code by Initial Developer. + V.1. In General. + The obligations of Section 3 apply to Netscape, except to + the extent specified in this Amendment, Section V.2 and V.3. + + V.2. Other Products. + Netscape may include Covered Code in products other than the + Netscape's Branded Code which are released by Netscape + during the two (2) years following the release date of the + Original Code, without such additional products becoming + subject to the terms of this License, and may license such + additional products on different terms from those contained + in this License. + + V.3. Alternative Licensing. + Netscape may license the Source Code of Netscape's Branded + Code, including Modifications incorporated therein, without + such Netscape Branded Code becoming subject to the terms of + this License, and may license such Netscape Branded Code on + different terms from those contained in this License. + + VI. Litigation. + Notwithstanding the limitations of Section 11 above, the + provisions regarding litigation in Section 11(a), (b) and (c) of + the License shall apply to all disputes relating to this License. + + EXHIBIT A-Netscape Public License. + + "The contents of this file are subject to the Netscape Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/NPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The Original Code is Mozilla Communicator client code, released + March 31, 1998. + + The Initial Developer of the Original Code is Netscape + Communications Corporation. Portions created by Netscape are + Copyright (C) 1998-1999 Netscape Communications Corporation. All + Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the + terms of the _____ license (the "[___] License"), in which case + the provisions of [______] License are applicable instead of + those above. If you wish to allow use of your version of this + file only under the terms of the [____] License and not to allow + others to use your version of this file under the NPL, indicate + your decision by deleting the provisions above and replace them + with the notice and other provisions required by the [___] + License. If you do not delete the provisions above, a recipient + may use your version of this file under either the NPL or the + [___] License." diff --git a/k-meleon/Install/SetDefault.nsi b/k-meleon/Install/SetDefault.nsi new file mode 100644 index 00000000..139b1100 --- /dev/null +++ b/k-meleon/Install/SetDefault.nsi @@ -0,0 +1,981 @@ +; Script generated by the HM NIS Edit Script Wizard, and manually modified. +; This script is a multi-language setup for K-Meleon + +; K-Meleon SetDefault version +!define SETUP_VERSION "1.3.1.2" + +; HM NIS Edit Wizard helper defines +!define PRODUCT_NAME "K-Meleon" +!define PRODUCT_VERSION "1.1" +!define PRODUCT_VERSION_PLUS "$(PRODUCT_VERSION}.0.0" +!define PRODUCT_BUILD "${PRODUCT_NAME} ${PRODUCT_VERSION}" +!define PRODUCT_PUBLISHER "${PRODUCT_NAME} Team" +!define PRODUCT_WEB_SITE "http://kmeleon.sourceforge.net/" +!define PRODUCT_MOZVERS "1.8.1.3" +!define PRODUCT_KEY "Software\${PRODUCT_NAME}" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" +!define CLIENT "Software\Clients\StartMenuInternet" +!define MOZILLA "Software\Mozilla" + +!define SETDEF "SetDefault" + +;-------------------------------- +;Global Variables for translation purpose + +; Caption + Var /Global _SetupCaption +; Welcome + Var /Global _MUI_WELCOMEPAGE_TITLE + Var /Global _MUI_WELCOMEPAGE_TEXT +; Directory + Var /Global _MUI_DIRECTORYPAGE_HEADER_TEXT + Var /Global _MUI_DIRECTORYPAGE_HEADER_SUBTEXT + Var /Global _MUI_DIRECTORYPAGE_TEXT_TOP + Var /Global _MUI_DIRECTORYPAGE_TEXT_TOP_1 + Var /Global _MUI_DIRECTORYPAGE_TEXT_TOP_2 + Var /Global _DirSubText + Var /Global _BrowseBtn + Var /Global _DirBrowseText +; Components + Var /Global _MUI_COMPONENTSPAGE_HEADER_TEXT + Var /Global _MUI_COMPONENTSPAGE_HEADER_SUBTEXT + Var /Global _MUI_COMPONENTSPAGE_TEXT_TOP + Var /Global _MUI_COMPONENTSPAGE_TEXT_COMPLIST + Var /Global _MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO + Var /Global _MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE +; Installing + Var /Global _MUI_TEXT_INSTALLING_TITLE + Var /Global _MUI_TEXT_INSTALLING_SUBTITLE + Var /Global _MUI_TEXT_FINISH_TITLE + Var /Global _MUI_TEXT_FINISH_SUBTITLE + Var /Global _MUI_INSTFILESPAGE_HEADER_TEXT + Var /Global _MUI_INSTFILESPAGE_HEADER_SUBTEXT + Var /Global _MUI_INSTFILESPAGE_FINISHHEADER_TEXT + Var /Global _MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT + Var /Global _InstallBtn + Var /Global _Completed +; General buttons + Var /Global _BackBtn + Var /Global _NextBtn + Var /Global _CancelBtn + Var /Global _CloseBtn +; Main section + Var /Global _SecMain + Var /Global _DESC_SecMain + Var /Global _SET_SecMain +; Windows Browser section + Var /Global _SecDefWindowsBrowser + Var /Global _DESC_SecDefWindowsBrowser + Var /Global _SET_SecDefWindowsBrowser +; Assoc proto section + Var /Global _SecAssoc + Var /Global _DESC_SecAssoc +; Protocols section + Var /Global _SecAssocProto + Var /Global _DESC_SecAssocProto +; Http section + Var /Global _SecHttp + Var /Global _DESC_SecHttp + Var /Global _SET_SecHttp +; Https section + Var /Global _SecHttps + Var /Global _DESC_SecHttps + Var /Global _SET_SecHttps +; Extensions section + Var /Global _SD_DocumentName +; Assoc Ext section + Var /Global _SecAssocExt + Var /Global _DESC_SecAssocExt +; Htm section + Var /Global _SecHtm + Var /Global _DESC_SecHtm + Var /Global _SET_SecHtm +; Html section + Var /Global _SecHtml + Var /Global _DESC_SecHtml + Var /Global _SET_SecHtml +; sHtml section + Var /Global _SecShtml + Var /Global _DESC_SecShtml + Var /Global _SET_SecShtml +; xHt section + Var /Global _SecXht + Var /Global _DESC_SecXht + Var /Global _SET_SecXht +; xHtml section + Var /Global _SecXhtml + Var /Global _DESC_SecXhtml + Var /Global _SET_SecXhtml +; Shortcuts section + Var /Global _SecShortcuts + Var /Global _DESC_SecShortcuts +; Desktop section + Var /Global _SecDesktop + Var /Global _DESC_SecDesktop + Var /Global _SET_SecDesktop +; Startup section + Var /Global _SecStartMenu + Var /Global _DESC_SecStartMenu + Var /Global _SET_SecStartMenu +; QuickLaunch section + Var /Global _SecQuickLaunch + Var /Global _DESC_SecQuickLaunch + Var /Global _SET_SecQuickLaunch +; Loader section +; Var /Global _PRODUCT_NAME_LOADER + Var /Global _SecLoader + Var /Global _DESC_SecLoader + Var /Global _SET_SecLoader +; No K-Meleon Folder Message + Var /Global _NotDetected +; Abort message + Var /Global _MUI_ABORTWARNING_TEXT + +;-------------------------------- +;Include Modern UI + + !define MUI_COMPONENTSPAGE_SMALLDESC + !include "MUI.nsh" + !include "Sections.nsh" +; !include "${NSISDIR}\Contrib\Modern UI\System.nsh" + +;-------------------------------- +;Include Windows SendMessage + + !include "WinMessages.nsh" + !define Startup "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + +;-------------------------------- +;Global Variable + + Var /Global UserIsAdmin + +;-------------------------------- +;Version tab in properties + + VIProductVersion ${SETUP_VERSION} + + VIAddVersionKey ProductName "${PRODUCT_NAME} ${SETDEF}" + VIAddVersionKey Comments "${PRODUCT_NAME} ${SETDEF} ${SETUP_VERSION}" + VIAddVersionKey CompanyName "${PRODUCT_NAME} Team" + VIAddVersionKey LegalCopyright "${PRODUCT_NAME} Team" + VIAddVersionKey FileDescription "${PRODUCT_NAME} Setup Assistant" + VIAddVersionKey FileVersion "${SETUP_VERSION}" + VIAddVersionKey ProductVersion "${SETUP_VERSION}" + VIAddVersionKey InternalName "${PRODUCT_NAME} ${SETDEF} ${SETUP_VERSION}" + VIAddVersionKey LegalTrademarks "${PRODUCT_WEB_SITE}" + VIAddVersionKey OriginalFilename "${SETDEF}.exe" + VIAddVersionKey SpecialBuild "${SETUP_VERSION}" + +;-------------------------------- +; MUI Settings + + !define MUI_ABORTWARNING + !define MUI_ABORTWARNING_TEXT "$_MUI_ABORTWARNING_TEXT" + !define MUI_ICON "${PRODUCT_NAME}.ico" + !define MUI_UNICON "${PRODUCT_NAME}.ico" + !define MUI_CHECKBITMAP "${NSISDIR}\Contrib\Icons\modern.bmp" + +; Welcome/Finish pages parameters + !define MUI_WELCOMEFINISHPAGE_BITMAP "${PRODUCT_NAME}.bmp" + !define MUI_WELCOMEPAGE_TITLE $_MUI_WELCOMEPAGE_TITLE + !define MUI_WELCOMEPAGE_TITLE_3LINES + !define MUI_WELCOMEPAGE_TEXT "$_MUI_WELCOMEPAGE_TEXT ${SETUP_VERSION}" + + !insertmacro MUI_PAGE_WELCOME + +; Directory page parameters + !define MUI_PAGE_CUSTOMFUNCTION_LEAVE DirectoryLeave + !define MUI_PAGE_HEADER_TEXT $_MUI_DIRECTORYPAGE_HEADER_TEXT + !define MUI_PAGE_HEADER_SUBTEXT $_MUI_DIRECTORYPAGE_HEADER_SUBTEXT + !define MUI_DIRECTORYPAGE_TEXT_TOP $_MUI_DIRECTORYPAGE_TEXT_TOP + + !insertmacro MUI_PAGE_DIRECTORY + +; Components page parameters + !define MUI_PAGE_HEADER_TEXT "$_MUI_COMPONENTSPAGE_HEADER_TEXT" + !define MUI_PAGE_HEADER_SUBTEXT "$_MUI_COMPONENTSPAGE_HEADER_SUBTEXT" + !define MUI_COMPONENTSPAGE_TEXT_TOP "$_MUI_COMPONENTSPAGE_TEXT_TOP" + !define MUI_COMPONENTSPAGE_TEXT_COMPLIST "$_MUI_COMPONENTSPAGE_TEXT_COMPLIST" + !define MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO "$_MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO" + !define MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE "$_MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE" + + !insertmacro MUI_PAGE_COMPONENTS + +#; Installation page parameters + !define MUI_INSTFILESPAGE_HEADER_TEXT "$_MUI_INSTFILESPAGE_HEADER_TEXT" + !define MUI_INSTFILESPAGE_HEADER_SUBTEXT "$_MUI_INSTFILESPAGE_HEADER_SUBTEXT" + !define MUI_INSTFILESPAGE_FINISHHEADER_TEXT "$_MUI_INSTFILESPAGE_FINISHHEADER_TEXT" + !define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "$_MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT" + !define MUI_PROGRESSBAR smooth + + !insertmacro MUI_PAGE_INSTFILES + +;-------------------------------- +; English Language by default + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +; English messages +; A trick to localize the last untranlatable messages + + LangString MUI_TEXT_INSTALLING_TITLE ${LANG_ENGLISH} "$_MUI_TEXT_INSTALLING_TITLE" + LangString MUI_TEXT_INSTALLING_SUBTITLE ${LANG_ENGLISH} "$_MUI_TEXT_INSTALLING_SUBTITLE" + +;-------------------------------- +;MUI parameters + +;Name and file + Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" + Caption "$_SetupCaption" + OutFile "${SETDEF}.exe" + +;Default installation folder and strings + InstallDir "$EXEDIR\" + DirText "$_MUI_DIRECTORYPAGE_HEADER_SUBTEXT" "$_DirSubText" "$_BrowseBtn" "$_DirBrowseText" + InstallButtonText "$_InstallBtn" + MiscButtonText "$_BackBtn" "$_NextBtn" "$_CancelBtn" "$_CloseBtn" + CompletedText "$_Completed" + SpaceTexts "none" + + ShowInstDetails show + ShowUnInstDetails show + + BrandingText /TRIMRIGHT "${PRODUCT_BUILD}" + +# ---------------------------------------------------------------------- +; macro Protocol + +!macro assocProtocol proto desc +push $0 + + ReadRegStr $0 SHCTX "Software\Classes\${proto}" "" + StrCmp $0 "${desc}" +3 + WriteRegStr SHCTX "${PRODUCT_KEY}\Desktop" "${proto}" $0 + WriteRegStr SHCTX "Software\Classes\${proto}" "" "${desc}" + + ReadRegStr $0 SHCTX "Software\Classes\${proto}\shell\open\command" "" + StrCmp $0 '"$INSTDIR\${PRODUCT_NAME}.exe" "%1"' assocProtocol_End + WriteRegStr SHCTX "${PRODUCT_KEY}\Desktop" "${proto}\shell\open\command" $0 + ReadRegStr $0 SHCTX "Software\Classes\${proto}\DefaultIcon" "" + WriteRegStr SHCTX "${PRODUCT_KEY}\Desktop" "${proto}\DefaultIcon" $0 + + WriteRegStr SHCTX "Software\Classes\${proto}\DefaultIcon" "" "$INSTDIR\${PRODUCT_NAME}.exe,1" + WriteRegStr SHCTX "Software\Classes\${proto}\shell\open\command" "" '"$INSTDIR\${PRODUCT_NAME}.exe" "%1"' + DeleteRegKey SHCTX "Software\Classes\${proto}\shell\open\ddeexec" + WriteRegStr SHCTX "Software\Classes\${proto}\shell\open\ddeexec\Application" "" "${PRODUCT_NAME}" + +assocProtocol_End: + + pop $0 +!macroend + +# ---------------------------------------------------------------------- +; macro Extension + +!macro assocExtension ext type + push $0 + + ReadRegStr $0 SHCTX "Software\Classes\${ext}" "" + + StrCmp $0 "${PRODUCT_NAME}.HTML" assocExtension_End + WriteRegStr SHCTX "${PRODUCT_KEY}\Desktop" "${ext}" $0 + WriteRegStr SHCTX "Software\Classes\${ext}" "" "${PRODUCT_NAME}.HTML" + + ReadRegStr $0 SHCTX "Software\Classes\${ext}" "Content Type" + WriteRegStr SHCTX "Software\Classes\${ext}" "Content Type" "${type}" + + DeleteRegKey SHCTX "Software\Classes\${ext}\PersistentHandler" + +assocExtension_End: + + pop $0 +!macroend + +# ---------------------------------------------------------------------- + +Section $_SecMain SecMain + + SectionIn 1 + DetailPrint "$_SET_SecMain" + WriteRegStr HKLM ${MOZILLA}\${PRODUCT_NAME} "GeckoVer" ${PRODUCT_MOZVERS} + WriteRegStr HKLM "${MOZILLA}\${PRODUCT_NAME}\bin" "PathToExe" "$INSTDIR" + WriteRegStr HKLM "${MOZILLA}\${PRODUCT_NAME}\Extensions" "Plugins" "$INSTDIR\Plugins" + WriteRegStr HKLM "${MOZILLA}\${PRODUCT_NAME}\Extensions" "Components" "$INSTDIR\Components" + WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" ${PRODUCT_MOZVERS} + WriteRegStr HKCU "${PRODUCT_KEY}\General" "InstallDir" "$INSTDIR" + + +SectionEnd + +# ---------------------------------------------------------------------- + +Section $_SecDefWindowsBrowser SecDefWindowsBrowser + + DetailPrint "$_SET_SecDefWindowsBrowser" + WriteRegStr HKLM "${CLIENT}\${PRODUCT_NAME}.exe" "" ${PRODUCT_NAME} +# WriteRegStr HKLM "Software\Clients\StartMenuInternet\${PRODUCT_NAME}.exe" "LocalizedString" "@$INSTDIR\${PRODUCT_NAME}.exe,-9" + WriteRegStr HKLM "${CLIENT}\${PRODUCT_NAME}.exe\DefaultIcon" "" "$INSTDIR\${PRODUCT_NAME}.exe,0" + WriteRegStr HKLM "${CLIENT}\${PRODUCT_NAME}.exe\Shell\Open\Command" "" "$INSTDIR\${PRODUCT_NAME}.exe" + WriteRegStr HKLM "${CLIENT}\${PRODUCT_NAME}.exe\InstallInfo" "ReinstallCommand" '"$INSTDIR\SetDefault.exe" /S' + WriteRegStr HKLM "${CLIENT}\${PRODUCT_NAME}.exe\InstallInfo" "HideIconsCommand" '"$INSTDIR\SetDefault.exe" /hide' + WriteRegStr HKLM "${CLIENT}\${PRODUCT_NAME}.exe\InstallInfo" "ShowIconsCommand" '"$INSTDIR\SetDefault.exe" /show' + WriteRegDWORD HKLM "${CLIENT}\${PRODUCT_NAME}.exe\InstallInfo" "IconsVisible" 0 + +SectionEnd + +# ---------------------------------------------------------------------- + +SubSection $_SecAssoc SecAssoc + + Section + SectionIn 1 2 RO + #XP Start Menu + WriteRegStr HKLM ${CLIENT} "" "${PRODUCT_NAME}.exe" + IfErrors 0 +3 + WriteRegStr HKCU ${CLIENT} "" "${PRODUCT_NAME}.exe" + Goto +2 + WriteRegStr HKCU ${CLIENT} "" "" + + StrCmp $UserIsAdmin "true" 0 +3 + SetShellVarContext all + Goto +2 + SetShellVarContext current + + WriteRegStr SHCTX "Software\Classes\${PRODUCT_NAME}.HTML" "" $_SD_DocumentName + WriteRegStr SHCTX "Software\Classes\${PRODUCT_NAME}.HTML\DefaultIcon" "" "$INSTDIR\${PRODUCT_NAME}.exe,1" + WriteRegStr SHCTX "Software\Classes\${PRODUCT_NAME}.HTML\shell\open\command" "" '"$INSTDIR\${PRODUCT_NAME}.exe" "%1"' + + WriteRegStr HKCU "${PRODUCT_KEY}\General" "InstallDir" "$INSTDIR" + SendMessage HWND_BROADCAST WM_SETTINGCHANGE 0 "STR:${CLIENT}" /TIMEOUT=5000 + + SectionEnd + + SubSection $_SecAssocProto SecAssocProto + Section $_SecHttp SecHttp + SectionIn 1 + DetailPrint "$_SET_SecHttp" + !insertmacro assocProtocol "http" "URL:HTTP (HyperText Transfer Protocol)" + SectionEnd + + Section $_SecHttps SecHttps + SectionIn 1 + DetailPrint "$_SET_SecHttps" + !insertmacro assocProtocol "https" "URL:HTTPS (HyperText Transfer Protocol) with Security System" + SectionEnd + + SubSectionEnd + + SubSection $_SecAssocExt SecAssocExt + + Section $_SecHtm SecHtm + SectionIn 1 + DetailPrint "$_SET_SecHtm" + !insertmacro assocExtension ".htm" "text/html" + SectionEnd + + Section $_SecHtml SecHtml + SectionIn 1 + DetailPrint "$_SET_SecHtml" + !insertmacro assocExtension ".html" "text/html" + SectionEnd + + Section $_SecShtml SecShtml + SectionIn 1 + DetailPrint "$_SET_SecShtml" + !insertmacro assocExtension ".shtml" "text/html" + SectionEnd + + Section $_SecXht SecXht + SectionIn 1 + DetailPrint "$_SET_SecXht" + !insertmacro assocExtension ".xht" "application/xhtml+xml" + SectionEnd + + Section $_SecXhtml SecXhtml + SectionIn 1 + DetailPrint "$_SET_SecXhtml" + !insertmacro assocExtension ".xhtml" "application/xhtml+xml" + SectionEnd + + SubSectionEnd + +SubSectionEnd + +# ---------------------------------------------------------------------- + +SubSection $_SecShortcuts SecShortcuts + + Section /o $_SecDesktop SecDesktop + DetailPrint "$_SET_SecDesktop" + SetShellVarContext current ; shortcut in AllUsers are annoying + CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" "" 0 + WriteRegDWORD HKLM "${CLIENT}\${PRODUCT_NAME}\InstallInfo" "IconsVisible" 1 + SectionEnd + + Section /o $_SecStartMenu SecStartMenu + DetailPrint "$_SET_SecStartMenu" + CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" "$INSTDIR\${PRODUCT_NAME}.exe" 0 + WriteRegDWORD HKLM "${CLIENT}\${PRODUCT_NAME}\InstallInfo" "IconsVisible" 1 + SectionEnd + + Section /o $_SecQuickLaunch SecQuickLaunch + DetailPrint "$_SET_SecQuickLaunch" + CreateShortCut "$QUICKLAUNCH\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" "" 0 + WriteRegDWORD HKLM "${CLIENT}\${PRODUCT_NAME}\InstallInfo" "IconsVisible" 1 + SectionEnd + +SubSectionEnd + +# ---------------------------------------------------------------------- + + Section /o $_SecLoader SecLoader + + DetailPrint "$_SET_SecLoader" + ReadRegStr $9 HKCU "${STARTUP}" "Startup" + Push "$9\${PRODUCT_NAME} Loader.lnk" + Pop $1 + CreateShortCut $1 "$INSTDIR\Loader.exe" + +SectionEnd + +# ---------------------------------------------------------------------- +; Function Restore Extension + +Function restoreExtension + Exch $R0 + Push $0 + + StrCmp $UserIsAdmin "true" 0 NotAdmin + ReadRegStr $0 HKLM "Software\Classes\$R0" "" + StrCmp $0 "${PRODUCT_NAME}.HTML" 0 restoreExtension_End + ReadRegStr $0 HKLM "${PRODUCT_KEY}\Desktop" "$R0" + IfErrors restoreExtension_End + WriteRegStr HKLM "Software\Classes\$R0" "" $0 + Goto restoreExtension_End +NotAdmin: + ReadRegStr $0 HKCU "Software\Classes\$R0" "" + StrCmp $0 "${PRODUCT_NAME}.HTML" 0 restoreExtension_End + ReadRegStr $0 HKCU "${PRODUCT_KEY}\Desktop" "$R0" + StrCmp $0 "" +3 0 + WriteRegStr HKCU "Software\Classes\$R0" "" $0 + Goto restoreExtension_End + DeleteRegKey HKCU "Software\Classes\$R0" + +restoreExtension_End: + Pop $0 + Pop $R0 +FunctionEnd + +# ---------------------------------------------------------------------- +; Function Restore Protocol + +Function restoreProtocol + Exch $R1 + Exch + Exch $R0 + + StrCmp $UserIsAdmin "true" 0 NotAdmin + + ReadRegStr $0 HKLM "Software\Classes\$R0" "" + StrCmp $0 "$R1" 0 +3 + ReadRegStr $0 HKLM "${PRODUCT_KEY}\Desktop" "$R0" + IfErrors restoreProtocol_End + WriteRegStr HKLM "Software\Classes\$R0" "" $0 + + ReadRegStr $0 HKLM "Software\Classes\$R0\shell\open\command" "" + StrCmp $0 '"$INSTDIR\${PRODUCT_NAME}.exe" "%1"' 0 restoreProtocol_End + ReadRegStr $0 HKLM "${PRODUCT_KEY}\Desktop" "$R0\DefaultIcon" + IfErrors restoreProtocol_End + WriteRegStr HKLM "Software\Classes\$R0\DefaultIcon" "" $0 + ReadRegStr $0 HKLM "${PRODUCT_KEY}\Desktop" "$R0\shell\open\command" + IfErrors restoreProtocol_End + WriteRegStr HKLM "Software\Classes\$R0\shell\open\command" "" $0 + DeleteRegKey HKLM "Software\Classes\$R0\shell\open\ddeexec" + Goto restoreProtocol_End +NotAdmin: + + ReadRegStr $0 HKCU "Software\Classes\$R0" "" + StrCmp $0 "$R1" 0 +3 + ReadRegStr $0 HKCU "${PRODUCT_KEY}\Desktop" "$R0" + StrCmp $0 "" 0 +3 + DeleteRegKey HKCU "Software\Classes\$R0" + Goto restoreProtocol_End + + WriteRegStr HKCU "Software\Classes\$R0" "" $0 + + ReadRegStr $0 HKCU "Software\Classes\$R0\shell\open\command" "" + StrCmp $0 '"$INSTDIR\${PRODUCT_NAME}.exe" "%1"' 0 restoreProtocol_End + ReadRegStr $0 HKCU "${PRODUCT_KEY}\Desktop" "$R0\DefaultIcon" + WriteRegStr HKCU "Software\Classes\$R0\DefaultIcon" "" $0 + ReadRegStr $0 HKCU "${PRODUCT_KEY}\Desktop" "$R0\shell\open\command" + WriteRegStr HKCU "Software\Classes\$R0\shell\open\command" "" $0 + DeleteRegKey HKCU "Software\Classes\$R0\shell\open\ddeexec" + +restoreProtocol_End: + Pop $R0 + Pop $0 + Pop $R0 + Pop $R1 + +FunctionEnd + +# ---------------------------------------------------------------------- + +Function DirectoryLeave + IfFileExists "$INSTDIR\${PRODUCT_NAME}.exe" KMFound + MessageBox MB_RETRYCANCEL|MB_ICONSTOP "$_NotDetected$\n$\n ''$INSTDIR'' !!! $\n" IDRETRY Retry + MessageBox MB_YESNO|MB_ICONEXCLAMATION $_MUI_ABORTWARNING_TEXT IDNO Retry + Quit +Retry: + Abort +KMFound: + +FunctionEnd + +# ---------------------------------------------------------------------- + +Function GetParameters + + Push $R0 + Push $R1 + Push $R2 + Push $R3 + + StrCpy $R2 1 + StrLen $R3 $CMDLINE + + ;Check for quote or space + StrCpy $R0 $CMDLINE $R2 + StrCmp $R0 '"' 0 +3 + StrCpy $R1 '"' + Goto loop + StrCpy $R1 " " + + loop: + IntOp $R2 $R2 + 1 + StrCpy $R0 $CMDLINE 1 $R2 + StrCmp $R0 $R1 get + StrCmp $R2 $R3 get + Goto loop + + get: + IntOp $R2 $R2 + 1 + StrCpy $R0 $CMDLINE 1 $R2 + StrCmp $R0 " " get + StrCpy $R0 $CMDLINE "" $R2 + + Pop $R3 + Pop $R2 + Pop $R1 + Exch $R0 + +FunctionEnd + +# ---------------------------------------------------------------------- + +Function .onInit + + Call GetParameters + Pop $1 + +; StrCmp $1 "/u" TestLoader 0 + StrCmp $1 "/s" Lang_En 0 + strcmp $1 "" Lang_En 0 + strcmp $1 "en-US" Lang_En SearchLocale + +SearchLocale: + IfFileExists $EXEDIR\locales\$1\setdefault.ini ReadLocale Lang_En + +ReadLocale: + strcpy $0 $EXEDIR\locales\$1\SetDefault.ini + Push $0 + call Translate_Strings + goto TestLoader + +Lang_En: + call Messages_En + +TestLoader: + ReadRegStr $9 HKCU "${STARTUP}" "Startup" + Push "$9\${PRODUCT_NAME} Loader.lnk" + Pop $8 + + IfFileExists $8 0 Params + SectionSetFlags ${SecLoader} ${SF_SELECTED} + +Params: + Call IsUserAdmin + Exch $R0 + StrCpy $UserIsAdmin $R0 + + StrCmp $1 "/u" 0 onInit_noUn + Push ".htm" + Call restoreExtension + Push ".html" + Call restoreExtension + Push ".shtml" + Call restoreExtension + Push ".xht" + Call restoreExtension + Push ".xhtml" + Call restoreExtension + + Push "http" + Push "URL:HTTP (HyperText Transfer Protocol)" + Call restoreProtocol + + Push "https" + Push "URL:HTTPS (HyperText Transfer Protocol) with Security System" + Call restoreProtocol + + System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' + Quit + +onInit_noUn: +# This is probably more annoying than anything else. + StrCmp $1 "/hide" 0 onInit_noHide + SetShellVarContext all + Delete $DESKTOP\${PRODUCT_NAME}.lnk + RMDir /r $SMPROGRAMS\${PRODUCT_NAME} +# Delete "$QUICKLAUNCH\${PRODUCT_NAME}.lnk" + WriteRegDWORD HKLM "${CLIENT}\${PRODUCT_NAME}\InstallInfo" "IconsVisible" 0 + Quit + +onInit_noHide: + StrCmp $1 "/show" 0 onInit_noShow + SetShellVarContext all + CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" "" 0 +# CreateShortCut "$QUICKLAUNCH\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" "" 0 + CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe" "" "$INSTDIR\${PRODUCT_NAME}.exe" 0 + WriteRegDWORD HKLM "${CLIENT}\${PRODUCT_NAME}\InstallInfo" "IconsVisible" 1 + Quit + +onInit_noShow: + IfSilent 0 +3 + IfFileExists "$INSTDIR\${PRODUCT_NAME}.exe" +2 + Quit + +FunctionEnd + +# ---------------------------------------------------------------------- + +Function .onInstSuccess + + SectionGetFlags ${SecLoader} $0 + IntCmp $0 ${SF_SELECTED} Notify 0 + Delete "$9\${PRODUCT_NAME} Loader.lnk" + +Notify: + System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' + +FunctionEnd + +# ---------------------------------------------------------------------- + +Function IsUserAdmin + + Push $R0 + Push $R1 + Push $R2 + + ClearErrors + UserInfo::GetName + IfErrors Win9x + Pop $R1 + UserInfo::GetAccountType + Pop $R2 + + StrCmp $R2 "Admin" 0 Continue +; Observation: I get here when running Win98SE. (Lilla) +; The functions UserInfo.dll looks for are there on Win98 too, +; but just don't work. So UserInfo.dll, knowing that admin isn't required +; on Win98, returns admin anyway. (per kichik) +; MessageBox MB_OK 'User "$R1" is in the Administrators group' + StrCpy $R0 "true" + Goto Done + +Continue: +; You should still check for an empty string because the functions +; UserInfo.dll looks for may not be present on Windows 95. (per kichik) + StrCmp $R2 "" Win9x + StrCpy $R0 "false" +;MessageBox MB_OK 'User "$R1" is in the "$R2" group' + Goto Done + +Win9x: +; comment/message below is by UserInfo.nsi author: +; This one means you don't need to care about admin or +; not admin because Windows 9x doesn't either +;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!" + StrCpy $R0 "true" + +Done: +;MessageBox MB_OK 'User= "$R1" AccountType= "$R2" IsUserAdmin= "$R0"' + + Pop $R2 + Pop $R1 + Exch $R0 + +FunctionEnd + +# ---------------------------------------------------------------------- + +Function Translate_Strings + +; inifile name + Pop $1 + +; Read lines + +; Caption + ReadIniStr $_SetupCaption $1 SetDefault SetupCaption +; Welcome + ReadIniStr $_MUI_WELCOMEPAGE_TITLE $1 SetDefault MUI_WELCOMEPAGE_TITLE + ReadIniStr $_MUI_WELCOMEPAGE_TEXT $1 SetDefault MUI_WELCOMEPAGE_TEXT +; Directory + ReadIniStr $_MUI_DIRECTORYPAGE_TEXT_TOP_1 $1 SetDefault MUI_DIRECTORYPAGE_TEXT_TOP_1 + ReadIniStr $_MUI_DIRECTORYPAGE_TEXT_TOP_2 $1 SetDefault MUI_DIRECTORYPAGE_TEXT_TOP_2 + strcpy $_MUI_DIRECTORYPAGE_TEXT_TOP "$_MUI_DIRECTORYPAGE_TEXT_TOP_1 $\n$\n$_MUI_DIRECTORYPAGE_TEXT_TOP_2" + + ReadIniStr $_MUI_DIRECTORYPAGE_HEADER_TEXT $1 SetDefault MUI_DIRECTORYPAGE_HEADER_TEXT + ReadIniStr $_MUI_DIRECTORYPAGE_HEADER_SUBTEXT $1 SetDefault MUI_DIRECTORYPAGE_HEADER_SUBTEXT + ReadIniStr $_DirSubText $1 SetDefault DirSubText + ReadIniStr $_BrowseBtn $1 SetDefault BrowseBtn + ReadIniStr $_DirBrowseText $1 SetDefault DirBrowseText +; Components + ReadIniStr $_MUI_COMPONENTSPAGE_HEADER_TEXT $1 SetDefault MUI_COMPONENTSPAGE_HEADER_TEXT + ReadIniStr $_MUI_COMPONENTSPAGE_HEADER_SUBTEXT $1 SetDefault MUI_COMPONENTSPAGE_HEADER_SUBTEXT + ReadIniStr $_MUI_COMPONENTSPAGE_TEXT_TOP $1 SetDefault MUI_COMPONENTSPAGE_TEXT_TOP + ReadIniStr $_MUI_COMPONENTSPAGE_TEXT_COMPLIST $1 SetDefault MUI_COMPONENTSPAGE_TEXT_COMPLIST + ReadIniStr $_MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO $1 SetDefault MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO + ReadIniStr $_MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE $1 SetDefault MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE +; Installing + ReadIniStr $_MUI_TEXT_INSTALLING_TITLE $1 SetDefault MUI_TEXT_INSTALLING_TITLE + ReadIniStr $_MUI_TEXT_INSTALLING_SUBTITLE $1 SetDefault MUI_TEXT_INSTALLING_SUBTITLE + ReadIniStr $_MUI_TEXT_FINISH_TITLE $1 SetDefault MUI_TEXT_FINISH_TITLE + ReadIniStr $_MUI_TEXT_FINISH_SUBTITLE $1 SetDefault MUI_TEXT_FINISH_SUBTITLE + ReadIniStr $_MUI_INSTFILESPAGE_HEADER_TEXT $1 SetDefault MUI_INSTFILESPAGE_HEADER_TEXT + ReadIniStr $_MUI_INSTFILESPAGE_HEADER_SUBTEXT $1 SetDefault MUI_INSTFILESPAGE_HEADER_SUBTEXT + ReadIniStr $_MUI_INSTFILESPAGE_FINISHHEADER_TEXT $1 SetDefault MUI_INSTFILESPAGE_FINISHHEADER_TEXT + ReadIniStr $_MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT $1 SetDefault MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT + ReadIniStr $_InstallBtn $1 SetDefault InstallBtn + ReadIniStr $_Completed $1 SetDefault Completed +; General Buttons + ReadIniStr $_BackBtn $1 SetDefault BackBtn + ReadIniStr $_NextBtn $1 SetDefault NextBtn + ReadIniStr $_CancelBtn $1 SetDefault CancelBtn + ReadIniStr $_CloseBtn $1 SetDefault CloseBtn +; Main Section + ReadIniStr $_SecMain $1 SetDefault SecMain + ReadIniStr $_DESC_SecMain $1 SetDefault DESC_SecMain + ReadIniStr $_SET_SecMain $1 SetDefault SET_SecMain +; Default Windows Browser + ReadIniStr $_SecDefWindowsBrowser $1 SetDefault SecDefWindowsBrowser + ReadIniStr $_DESC_SecDefWindowsBrowser $1 SetDefault DESC_SecDefWindowsBrowser + ReadIniStr $_SET_SecDefWindowsBrowser $1 SetDefault SET_SecDefWindowsBrowser +; Assoc Section + ReadIniStr $_SecAssoc $1 SetDefault SecAssoc + ReadIniStr $_DESC_SecAssoc $1 SetDefault DESC_SecAssoc +; Assoc Proto Section + ReadIniStr $_SecAssocProto $1 SetDefault SecAssocProto + ReadIniStr $_DESC_SecAssocProto $1 SetDefault DESC_SecAssocProto +; Http Section + ReadIniStr $_SecHttp $1 SetDefault SecHttp + ReadIniStr $_DESC_SecHttp $1 SetDefault DESC_SecHttp + ReadIniStr $_SET_SecHttp $1 SetDefault SET_SecHttp +; Https Section + ReadIniStr $_SecHttps $1 SetDefault SecHttps + ReadIniStr $_DESC_SecHttps $1 SetDefault DESC_SecHttps + ReadIniStr $_SET_SecHttps $1 SetDefault SET_SecHttps +; Assoc Ext Section + ReadIniStr $_SD_DocumentName $1 SetDefault SD_DocumentName + ReadIniStr $_SecAssocExt $1 SetDefault SecAssocExt + ReadIniStr $_DESC_SecAssocExt $1 SetDefault DESC_SecAssocExt +; Htm Section + ReadIniStr $_SecHtm $1 SetDefault SecHtm + ReadIniStr $_DESC_SecHtm $1 SetDefault DESC_SecHtm + ReadIniStr $_SET_SecHtm $1 SetDefault SET_SecHtm +; Html Section + ReadIniStr $_SecHtml $1 SetDefault SecHtml + ReadIniStr $_DESC_SecHtml $1 SetDefault DESC_SecHtml + ReadIniStr $_SET_SecHtml $1 SetDefault SET_SecHtml +; sHtml Section + ReadIniStr $_SecShtml $1 SetDefault SecShtml + ReadIniStr $_DESC_SecShtml $1 SetDefault DESC_SecShtml + ReadIniStr $_SET_SecShtml $1 SetDefault SET_SecShtml +; xht Section + ReadIniStr $_SecXht $1 SetDefault SecXht + ReadIniStr $_DESC_SecXht $1 SetDefault DESC_SecXht + ReadIniStr $_SET_SecXht $1 SetDefault SET_SecXht +; xHtml Section + ReadIniStr $_SecXhtml $1 SetDefault SecXhtml + ReadIniStr $_DESC_SecXhtml $1 SetDefault DESC_SecXhtml + ReadIniStr $_SET_SecXhtml $1 SetDefault SET_SecXhtml +; Shortcuts Section + ReadIniStr $_SecShortcuts $1 SetDefault SecShortcuts + ReadIniStr $_DESC_SecShortcuts $1 SetDefault DESC_SecShortcuts +; Desktop Section + ReadIniStr $_SecDesktop $1 SetDefault SecDesktop + ReadIniStr $_DESC_SecDesktop $1 SetDefault DESC_SecDesktop + ReadIniStr $_SET_SecDesktop $1 SetDefault SET_SecDesktop +; StartMenu Section + ReadIniStr $_SecStartMenu $1 SetDefault SecStartMenu + ReadIniStr $_DESC_SecStartMenu $1 SetDefault DESC_SecStartMenu + ReadIniStr $_SET_SecStartMenu $1 SetDefault SET_SecStartMenu +; QuickLaunch Section + ReadIniStr $_SecQuickLaunch $1 SetDefault SecQuickLaunch + ReadIniStr $_DESC_SecQuickLaunch $1 SetDefault DESC_SecQuickLaunch + ReadIniStr $_SET_SecQuickLaunch $1 SetDefault SET_SecQuickLaunch +; Loader Section + ReadIniStr $_SecLoader $1 SetDefault SecLoader + ReadIniStr $_DESC_SecLoader $1 SetDefault DESC_SecLoader + ReadIniStr $_SET_SecLoader $1 SetDefault SET_SecLoader +; Warning messages + ReadIniStr $_NotDetected $1 SetDefault NotDetected + ReadIniStr $_MUI_ABORTWARNING_TEXT $1 SetDefault MUI_ABORTWARNING_TEXT + + FunctionEnd + +# ---------------------------------------------------------------------- + +Function Messages_En + +; Caption + strcpy $_SetupCaption "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup Assistant" +; Welcome + strcpy $_MUI_WELCOMEPAGE_TITLE "Welcome to the ${PRODUCT_NAME} ${PRODUCT_VERSION} Setup Assistant !" + strcpy $_MUI_WELCOMEPAGE_TEXT "This assistant will help you to integrate ${PRODUCT_NAME} into your Windows operating system:\n\n- Register ${PRODUCT_NAME} as a Mozilla product\n- Register ${PRODUCT_NAME} as a Windows Browser\n- Set ${PRODUCT_NAME} as default browser for various protocols\n- Set ${PRODUCT_NAME} as default browser for various file types\n- Create shortcuts for ${PRODUCT_NAME}\n- Enable/disable the ${PRODUCT_NAME} Loader\n\n\n\n\n\n\n\t\t\t\tSetDefault v." +; Directory + strcpy $_MUI_DIRECTORYPAGE_HEADER_TEXT "${PRODUCT_NAME} Install Location" + strcpy $_MUI_DIRECTORYPAGE_HEADER_SUBTEXT "Specify the location of the ${PRODUCT_NAME} installation which you want to set up now." + strcpy $_MUI_DIRECTORYPAGE_TEXT_TOP "By default, this is the directory where the ${PRODUCT_NAME} installation is located with which you are currently working.$\n$\nIf you have more than one installation of ${PRODUCT_NAME}, you might want to specify the location of a different installation. (This version of ${PRODUCT_NAME} Setup Assistant is compatible with versions 0.9 through ${PRODUCT_VERSION} of ${PRODUCT_NAME}.)" + strcpy $_DirSubText "Install Location" + strcpy $_BrowseBtn "Browse..." + strcpy $_DirBrowseText "Choose the location of a ${PRODUCT_NAME} installation." +; Components + strcpy $_MUI_COMPONENTSPAGE_HEADER_TEXT "${PRODUCT_NAME} Setup Options" + strcpy $_MUI_COMPONENTSPAGE_HEADER_SUBTEXT "Configure the setup options to be performed." + strcpy $_MUI_COMPONENTSPAGE_TEXT_TOP "Check an option to add the related registry entries or file system shortcuts to your system. Uncheck an option to remove them. Click Install to apply your changes." + strcpy $_MUI_COMPONENTSPAGE_TEXT_COMPLIST "Available Options:" + strcpy $_MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO "Check an option to add the related entries/files to your system. Uncheck an option to remove them." + strcpy $_MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE "Description" +; Installing + strcpy $_MUI_TEXT_INSTALLING_TITLE "Setting up ${PRODUCT_NAME}" + strcpy $_MUI_TEXT_INSTALLING_SUBTITLE "Please wait while setting up ${PRODUCT_NAME}." +; Trick to translate the last strings (see english messages at the top of this file) + strcpy $_MUI_TEXT_FINISH_TITLE $(MUI_TEXT_FINISH_TITLE) + strcpy $_MUI_TEXT_FINISH_SUBTITLE $(MUI_TEXT_FINISH_SUBTITLE) +; Installing + strcpy $_MUI_INSTFILESPAGE_HEADER_TEXT "Setting ${PRODUCT_NAME} parameters" + strcpy $_MUI_INSTFILESPAGE_HEADER_SUBTEXT "Setup is in progress..." + strcpy $_MUI_INSTFILESPAGE_FINISHHEADER_TEXT "${PRODUCT_NAME} Setup Completed" + strcpy $_MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "${PRODUCT_NAME} setup has completed successfully." + strcpy $_InstallBtn "Install" + strcpy $_Completed "Completed" +; General Buttons + strcpy $_BackBtn "< Back" + strcpy $_NextBtn "Next >" + strcpy $_CancelBtn "Cancel" + strcpy $_CloseBtn "Close" +; Main Section + strcpy $_SecMain "Register ${PRODUCT_NAME} as a Mozilla product" + strcpy $_DESC_SecMain "These registry entries are needed for Netscape/Mozilla plugins to work correctly." + strcpy $_SET_SecMain "${PRODUCT_NAME} registered as a Mozilla product" +; Windows Default Browser + strcpy $_SecDefWindowsBrowser "Register ${PRODUCT_NAME} as a Windows Browser" + strcpy $_DESC_SecDefWindowsBrowser "Add ${PRODUCT_NAME} to the Windows 2000/XP browser list. You need administrative privileges." + strcpy $_SET_SecDefWindowsBrowser "${PRODUCT_NAME} registered as a Windows Browser" +; Assoc Section + strcpy $_SecAssoc "Set ${PRODUCT_NAME} as your default browser" + strcpy $_DESC_SecAssoc "Set ${PRODUCT_NAME} as your default browser. You need administrative privileges." +; Assoc Protocols Section + strcpy $_SecAssocProto "Protocols" + strcpy $_DESC_SecAssocProto "Choose the protocols to be opened with ${PRODUCT_NAME} by default." +; Http Section + strcpy $_SecHttp "HTTP Protocol" + strcpy $_DESC_SecHttp "Open HTTP addresses with ${PRODUCT_NAME} by default." + strcpy $_SET_SecHttp "${PRODUCT_NAME} set as your default application for the HTTP protocol" +; Https Section + strcpy $_SecHttps "HTTPS Protocol" + strcpy $_DESC_SecHttps "Open HTTPS addresses with ${PRODUCT_NAME} by default." + strcpy $_SET_SecHttps "${PRODUCT_NAME} set as your default application for the HTTPS protocol" +; Assoc Ext Section + strcpy $_SD_DocumentName "Hypertext Markup Language Document" + strcpy $_SecAssocExt "File Types" + strcpy $_DESC_SecAssocExt "Choose the file types to be opened with ${PRODUCT_NAME} by default." +; Htm Section + strcpy $_SecHtm "HTM Files" + strcpy $_DESC_SecHtm "Open HTM files with ${PRODUCT_NAME} by default." + strcpy $_SET_SecHtm "${PRODUCT_NAME} set as your default application for HTM files" +; Html Section + strcpy $_SecHtml "HTML Files" + strcpy $_DESC_SecHtml "Open HTML files with ${PRODUCT_NAME} by default." + strcpy $_SET_SecHtml "${PRODUCT_NAME} set as your default application for HTML files" +; sHtml Section + strcpy $_SecShtml "SHTML Files" + strcpy $_DESC_SecShtml "Open SHTML files with ${PRODUCT_NAME} by default." + strcpy $_SET_SecShtml "${PRODUCT_NAME} set as your default application for SHTML files" +; Xht Section + strcpy $_SecXht "XHT Files" + strcpy $_DESC_SecXht "Open XHT files with ${PRODUCT_NAME} by default." + strcpy $_SET_SecXht "${PRODUCT_NAME} set as your default application for XHT files" +; Xhtml Section + strcpy $_SecXhtml "XHTML Files" + strcpy $_DESC_SecXhtml "Open XHTML files with ${PRODUCT_NAME} by default." + strcpy $_SET_SecXhtml "${PRODUCT_NAME} set as your default application for XHTML files" +; Shortcuts Section + strcpy $_SecShortcuts "Create ${PRODUCT_NAME} Shortcuts" + strcpy $_DESC_SecShortcuts "Choose the shortcuts to be created." +; Desktop Section + strcpy $_SecDesktop "Desktop" + strcpy $_DESC_SecDesktop "Create a shortcut on the Desktop." + strcpy $_SET_SecDesktop "Shortcut created on the Desktop" +; StartMenu Section + strcpy $_SecStartMenu "Start Menu" + strcpy $_DESC_SecStartMenu "Create a folder with shortcuts in the Start Menu." + strcpy $_SET_SecStartMenu "Shortcuts created in the Start Menu" +; QuickLaunch Section + strcpy $_SecQuickLaunch "Quick Launch Toolbar" + strcpy $_DESC_SecQuickLaunch "Create a shortcut in the Quick Launch Toolbar." + strcpy $_SET_SecQuickLaunch "Shortcut created in the Quick Launch Toolbar" +; Loader Section + strcpy $_SecLoader "Autostart ${PRODUCT_NAME} Loader" + strcpy $_DESC_SecLoader "Create a shortcut to ${PRODUCT_NAME} Loader in the Autostart Menu. Uncheck to remove the shortcut." + strcpy $_SET_SecLoader "${PRODUCT_NAME} Loader added to the Autostart Menu" +; Warning boxes + strcpy $_NotDetected "No ${PRODUCT_NAME} installation detected in" + strcpy $_MUI_ABORTWARNING_TEXT "Are you sure you want to quit the ${PRODUCT_NAME} ${PRODUCT_VERSION} Setup Assistant?" + + FunctionEnd + +; ---------------------------------------------------------------------- +; Section descriptions + +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + + !insertmacro MUI_DESCRIPTION_TEXT ${SecMain} $_DESC_SecMain + !insertmacro MUI_DESCRIPTION_TEXT ${SecDefWindowsBrowser} $_DESC_SecDefWindowsBrowser + !insertmacro MUI_DESCRIPTION_TEXT ${SecAssoc} $_DESC_SecAssoc + !insertmacro MUI_DESCRIPTION_TEXT ${SecAssocProto} $_DESC_SecAssocProto + !insertmacro MUI_DESCRIPTION_TEXT ${SecHttp} $_DESC_SecHttp + !insertmacro MUI_DESCRIPTION_TEXT ${SecHttps} $_DESC_SecHttps + !insertmacro MUI_DESCRIPTION_TEXT ${SecAssocExt} $_DESC_SecAssocExt + !insertmacro MUI_DESCRIPTION_TEXT ${SecHtm} $_DESC_SecHtm + !insertmacro MUI_DESCRIPTION_TEXT ${SecHtml} $_DESC_SecHtml + !insertmacro MUI_DESCRIPTION_TEXT ${SecShtml} $_DESC_SecShtml + !insertmacro MUI_DESCRIPTION_TEXT ${SecXht} $_DESC_SecXht + !insertmacro MUI_DESCRIPTION_TEXT ${SecXhtml} $_DESC_SecXhtml + !insertmacro MUI_DESCRIPTION_TEXT ${SecShortcuts} $_DESC_SecShortcuts + !insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} $_DESC_SecDesktop + !insertmacro MUI_DESCRIPTION_TEXT ${SecStartMenu} $_DESC_SecStartMenu + !insertmacro MUI_DESCRIPTION_TEXT ${SecQuickLaunch} $_DESC_SecQuickLaunch + !insertmacro MUI_DESCRIPTION_TEXT ${SecLoader} $_DESC_SecLoader + +!insertmacro MUI_FUNCTION_DESCRIPTION_END + diff --git a/k-meleon/Install/english.nlf b/k-meleon/Install/english.nlf new file mode 100644 index 00000000..b4a2a446 --- /dev/null +++ b/k-meleon/Install/english.nlf @@ -0,0 +1,50 @@ +!ifdef ULANG + !undef ULANG +!endif + +!define ULANG ${LANG_ENGLISH} + +LangString INST_Welcome ULANG "${NAME} ${VERSION} Install Wizard" +LangString MUI_WELCOMEPAGE_TEXT ULANG "This wizard will guide you through the installation of ${PRODUCT_BUILD}.\n\nIt is recommanded that you close all other applications before starting Setup. This will make it possible to update relevant system files without having to reboot your computer.\n\nClick Next to continue.\n\n\n\n\n\n\n\n\t\t\t\t${NAME} Setup v. ${SETUP_VERSION}" +LangString INST_Caption ULANG "${PRODUCT_BUILD} Setup" + +LangString DESC_SecMain ULANG "Install the required ${NAME} files." +LangString DESC_SecAllUser ULANG "Install ${NAME} for all user accounts. You need administration privileges." +LangString DESC_SecBookmarks ULANG "Choose what type of bookmark support you wish to have enabled by default." +LangString DESC_SecNetscapeBookmarks ULANG "Enable support for Netscape compatible bookmarks." +LangString DESC_SecIEFavorites ULANG "Enable support for Internet Explorer compatible Favorites." +LangString DESC_SecOperaHotlist ULANG "Enable support for Opera compatible bookmarks (Hotlist)." +LangString DESC_SecAssoc ULANG "Set ${NAME} as your default browser. You need administration privileges." +LangString DESC_SecShortcuts ULANG "Select which shortcuts you would like to have created." +LangString DESC_SecDesktop ULANG "Create a desktop shortcut." +LangString DESC_SecStartMenu ULANG "Create a Start Menu folder with shortcuts." +LangString DESC_SecQuickLaunch ULANG "Create a Quick Launch shortcut." +LangString DESC_SecTools ULANG "Select which extra ${NAME} tools you would like to install." +LangString DESC_SecLoader ULANG "Install the ${NAME} Loader, for significantly faster startup times." +#LangString DESC_SecRemote ULANG "Install the ${NAME} Remote Control tool. (requires the external program control plugin to be enabled)" +#LangString DESC_SecSplash ULANG "Install a splash screen tool." + +LangString UN_confirm ULANG "This will remove ${PRODUCT_BUILD} from your computer. Click Uninstall to start the uninstallation." +LangString UN_RemoveProfile ULANG "Would you like to remove the user profiles?$\n$\nThe user profile contains your personal preferences, bookmarks, and history and is located in " +LangString UN_everything ULANG "There seems to be more files left in the install directory, would you like to remove everything?$\n$\n(This is most likely installed plugins, skins, or other downloaded files)" +LangString UN_Title ULANG "${PRODUCT_BUILD} (remove only)" + +LangString INIT_KmeleonRunning ULANG "It appears that ${NAME} or the Loader is currently running.$\r$\nIt must be closed before ${NAME} ${VERSION} can continue installation.$\r$\n$\r$\nPress OK to close now, or Cancel to abort installation." +LangString INST_AlreadyInstalled ULANG "An earlier install of ${NAME} has been detected in ''$INSTDIR'' !$\nAre you sure you want to install ${NAME} in this directory?" +LangString INST_Quit ULANG "Are you sure you want to quit ${PRODUCT_BUILD} Setup?" + +LangString SECT_Loader ULANG "${NAME} Loader" +LangString SECT_AllUser ULANG "Install for all user" +LangString SECT_Bookmarks ULANG "Bookmark Support" +LangString SECT_IEFavorites ULANG "Internet Explorer Favorites" +LangString SECT_NSBookmarks ULANG "Netscape Bookmarks" +LangString SECT_Hotlist ULANG "Opera Hotlist" +LangString SECT_DefaultBrowser ULANG "Set ${NAME} as your default browser" + +LangString SECT_CreateShortcut ULANG "Create Windows Shortcuts for ${NAME}" +LangString SECT_WSShortcut ULANG "Desktop Shortcut" +LangString SECT_SMShortcut ULANG "Start Menu Shortcut" +LangString SECT_QLShortcut ULANG "Quick Launch Shortcut" +LangString SECT_Tools ULANG "Miscellaneous ${NAME} Tools" +LangString SECT_Profile ULANG "Multi-user Profiles" +LangString DESC_SecProfile ULANG "Uncheck this option to store ${NAME} profiles in the ${NAME} folder instead of the application data folder." diff --git a/k-meleon/Install/install.ico b/k-meleon/Install/install.ico new file mode 100644 index 0000000000000000000000000000000000000000..e9ac42d9be30d704f0eccb3ba07eaf2b721544d3 GIT binary patch literal 4710 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 B2ND1P literal 0 HcmV?d00001 diff --git a/k-meleon/Install/k-meleon.nsi b/k-meleon/Install/k-meleon.nsi new file mode 100644 index 00000000..e41d61b7 --- /dev/null +++ b/k-meleon/Install/k-meleon.nsi @@ -0,0 +1,728 @@ +!define SETUP_VERSION "1.3.0" + +!define NAME "K-Meleon" +!define YEAR "2007" +!define VERSION "1.1" +!define PRODUCT_VERSION_PLUS "1.1.0.5" +!define ADDRESS "http://kmeleon.sourceforge.net/" +!define GECKO_VERSION "1.8.1.3" + +!define LANG "English" ; see NSIS\Examples\Modern UI\MultiLanguage.nsi: Languages +!define LANGCODE "en-US" ; specify "xx-YY" if not "en-US" + +!if "${LANGCODE}" == "" + !define PRODUCT_BUILD "${NAME} ${VERSION}" +!endif +!if "${LANGCODE}" != "" + !define PRODUCT_BUILD "${NAME} ${VERSION} ${LANGCODE}" +!endif + +!define PRODUCT_KEY "Software\${NAME}" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" +!define CLIENT_INTERNET_KEY "Software\Clients\StartMenuInternet" +!define PRODUCT_CLIENT_INTERNET_KEY "${CLIENT_INTERNET_KEY}\k-meleon.exe" +!define MOZILLA_REG_KEY "Software\Mozilla\${NAME}" +!define MEDIAPLAYER_REG_KEY "SOFTWARE\Microsoft\MediaPlayer\ShimInclusionList\k-meleon.exe" + +; uncomment if IsUserAdmin function is used +#!define _IsUserAdmin + +;-------------------------------- +;Include Modern UI + +!include "MUI.nsh" +!include "Sections.nsh" + +;-------------------------------- +;General + + + +;Default installation folder +InstallDir "$PROGRAMFILES\${NAME}\" + +;Get installation folder from registry if available +InstallDirRegKey HKEY_CURRENT_USER "${PRODUCT_KEY}\General" "InstallDir" + +SetCompressor /SOLID lzma +SetDatablockOptimize on +ShowInstDetails show +AutoCloseWindow false +SetOverwrite on +BrandingText /TRIMRIGHT "${NAME} ${VERSION}" +LicenseBkColor "ffffff" + +;Name and file +Name "${NAME} ${VERSION}" +Caption $(INST_Caption) +OutFile "${NAME}${VERSION}${LANGCODE}.exe" + +;-------------------------------- +;Version tab in properties + + VIProductVersion "${PRODUCT_VERSION_PLUS}" + + VIAddVersionKey Comments "${PRODUCT_BUILD} Setup" + VIAddVersionKey CompanyName "${NAME} Team" + VIAddVersionKey FileDescription "${PRODUCT_BUILD} Setup" + VIAddVersionKey FileVersion "${PRODUCT_VERSION_PLUS}" + VIAddVersionKey InternalName "${PRODUCT_BUILD}" + VIAddVersionKey LegalCopyright "Copyright (C) ${YEAR} ${NAME} Team" + VIAddVersionKey LegalTrademarks "${ADDRESS}" + VIAddVersionKey OriginalFilename "${NAME}${VERSION}${LANGCODE}.exe" + VIAddVersionKey PrivateBuild "" + VIAddVersionKey ProductName "${NAME}" + VIAddVersionKey ProductVersion "${PRODUCT_VERSION_PLUS}" + VIAddVersionKey SpecialBuild "" + +;---------------------------------------- +;Interface Settings + +!define MUI_ABORTWARNING + +!define MUI_ICON "install.ico" +!define MUI_UNICON "uninstall.ico" +!define MUI_CHECKBITMAP "${NSISDIR}\Contrib\Icons\modern.bmp" +!define MUI_COMPONENTSPAGE_SMALLDESC +!define MUI_NAME "${NAME} ${VERSION}" + +!define MUI_INSTALLCOLORS /windows +!define MUI_PROGRESSBAR smooth + +!define MUI_INSTFILESPAGE_COLORS "000000 ffffff" ;Multiple settings + + + + +;-------------------------------- +;Pages + +!define MUI_WELCOMEFINISHPAGE_BITMAP "${NAME}.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${NAME}.bmp" + +!define MUI_WELCOMEPAGE_TITLE $(INST_Welcome) +!define MUI_WELCOMEPAGE_TEXT $(MUI_WELCOMEPAGE_TEXT) +!insertmacro MUI_PAGE_WELCOME + +!insertmacro MUI_PAGE_LICENSE "license.txt" +!insertmacro MUI_PAGE_COMPONENTS + +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE DirectoryLeave +!insertmacro MUI_PAGE_DIRECTORY +;Page custom ProfilePage ProfilePageLeave + +!insertmacro MUI_PAGE_INSTFILES +!define MUI_FINISHPAGE +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_FINISHPAGE_RUN "$INSTDIR\k-meleon.exe" +;!define MUI_FINISHPAGE_RUN_PARAMETERS "$INSTDIR\readme.html" +!insertmacro MUI_PAGE_FINISH + +!define MUI_UNINSTPAGE +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + +!if ${LANG} != "English" + !insertmacro MUI_LANGUAGE "English" + !include "English.nlf" +!endif +!insertmacro MUI_LANGUAGE "${LANG}" +!include "${LANG}.nlf" + +;-------------------------------- + + +# ---------------------------------------------------------------------- + +!macro GET_PROFILES_LOCATION + Push $R1 + Push $R2 + IfFileExists "$INSTDIR\profile.ini" 0 AppDataProfile + ReadINIStr $R1 "$INSTDIR\profile.ini" "Profile" "path" + ReadINIStr $R2 "$INSTDIR\profile.ini" "Profile" "isrelative" + StrCmp $R1 "" 0 +2 ; If path empty + StrCpy $R1 "Profiles" ; Copy default folder name + StrCmp $R2 "1" 0 +2 ; If path is relative + StrCpy $R0 "$INSTDIR\$R1" ; add the install dir to the path + Goto +2 ; else + StrCpy $R0 $R1 ; use the path only + + Goto End_proflocation +AppDataProfile: + StrCpy $R0 "$APPDATA\K-Meleon" +End_proflocation: + + Pop $R2 + Pop $R1 +!macroend + +# ---------------------------------------------------------------------- +/* +LangString PROFILEPAGE_TITLE ${LANG_ENGLISH} "Profiles Location" +LangString PROFILEPAGE_SUBTITLE ${LANG_ENGLISH} "Choose the location of the profiles." +LangString PROFILEPAGE_CHOOSEDIRDIALOG ${LANG_ENGLISH} "Select a folder to be the root location for the profiles." +LangString PROFILEPAGE_CHOOSEDIR ${LANG_ENGLISH} "Choose Folder:" +LangString PROFILEPAGE_CHECK ${LANG_ENGLISH} "Use default Application Data location (uncheck to set a custom location)." +LangString PROFILEPAGE_HEADER ${LANG_ENGLISH} "" + +Var HWND +Var DLGITEM + +Function ProfilePageLeave + + ReadINIStr $0 "$PLUGINSDIR\profpage.ini" "Settings" "State" + StrCmp $0 0 validate + StrCmp $0 1 checkbutton + Abort + +checkbutton: + ReadINIStr $0 "$PLUGINSDIR\profpage.ini" "Field 1" "State" + ReadINIStr $1 "$PLUGINSDIR\profpage.ini" "Field 2" "HWND" + ReadINIStr $2 "$PLUGINSDIR\profpage.ini" "Field 2" "HWND2" + StrCmp $0 0 Notchecked + + EnableWindow $1 0 + EnableWindow $2 0 + Goto checkbutton_end + +NotChecked: + EnableWindow $1 1 + EnableWindow $2 1 + +checkbutton_end: + Abort +validate: + +FunctionEnd + +Function ProfilePage + Push $R0 + WriteINIStr "$PLUGINSDIR\profpage.ini" "Field 1" "Text" "$(PROFILEPAGE_CHECK)" + WriteINIStr "$PLUGINSDIR\profpage.ini" "Field 2" "Text" "$(PROFILEPAGE_CHOOSEDIRDIALOG)" + WriteINIStr "$PLUGINSDIR\profpage.ini" "Field 3" "Text" "$(PROFILEPAGE_CHOOSEDIR)" + WriteINIStr "$PLUGINSDIR\profpage.ini" "Field 4" "Text" "$(PROFILEPAGE_HEADER)" + !insertmacro MUI_HEADER_TEXT "$(PROFILEPAGE_TITLE)" "$(PROFILEPAGE_SUBTITLE)" + !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "profpage.ini" + Pop $HWND + + IfFileExists "$INSTDIR\profile.ini" 0 NoProfileIni + ReadINIStr $1 "$PLUGINSDIR\profpage.ini" "Field 2" "HWND" + ReadINIStr $2 "$PLUGINSDIR\profpage.ini" "Field 2" "HWND2" + EnableWindow $1 1 + EnableWindow $2 1 + +NoProfileIni: + !insertmacro GET_PROFILES_LOCATION + GetDlgItem $DLGITEM $HWND 1201 + SendMessage $DLGITEM ${WM_SETTEXT} 0 "STR:$R0" + + Pop $R0 + !insertmacro MUI_INSTALLOPTIONS_SHOW +FunctionEnd +*/ +# ---------------------------------------------------------------------- + + +Section ${NAME} SecMain + SectionIn RO + + RMDir /r $INSTDIR\components + RMDir /r $INSTDIR\defaults + RMDir /r $INSTDIR\greprefs + RMDir /r $INSTDIR\ipc + RMDir /r $INSTDIR\res + Delete $INSTDIR\chrome\installed-chrome.txt + Delete $INSTDIR\chrome\chrome.rdf + Delete $INSTDIR\chrome\overlays.rdf + RMDir /r "$INSTDIR\chrome\overlayinfo" + + ; Delete Loader shortcut in Startup Folder to let the choice possible (No by default) + Delete "$SMSTARTUP\K-Meleon Loader.lnk" + + SetOutPath "$INSTDIR" + File /r .\k-meleon\*.* + + !ifdef _IsUserAdmin + Call IsUserAdmin + StrCmp $R0 "true" 0 +3 + SetOutPath $SYSDIR + Goto +2 + !endif + SetOutPath $INSTDIR + File /nonfatal .\dll\*.* + File /nonfatal .\misc\*.* + + + + WriteRegStr HKLM ${MOZILLA_REG_KEY} "GeckoVer" GECKO_VERSION + WriteRegStr HKLM "${MOZILLA_REG_KEY}\bin" "PathToExe" "$INSTDIR" + WriteRegStr HKLM "${MOZILLA_REG_KEY}\Extensions" "Plugins" "$INSTDIR\Plugins" + WriteRegStr HKLM "${MOZILLA_REG_KEY}\Extensions" "Components" "$INSTDIR\Components" + WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" GECKO_VERSION + + ; Register K-Meleon as a windows browser for windows > 2K + Call GetWindowsVersion + pop $R0 + StrCpy $R1 $R0 1 0 + StrCmp $R1 "5" RegClientInternet + StrCmp $R1 "6" RegClientInternet + Goto NoClientInternet + +RegClientInternet: + WriteRegStr HKLM "${PRODUCT_CLIENT_INTERNET_KEY}" "" ${NAME} +# WriteRegStr HKLM "${CLIENT_INTERNET_KEY}\${NAME}.exe" "LocalizedString" "@$INSTDIR\K-Meleon.exe,-9" + WriteRegStr HKLM "${PRODUCT_CLIENT_INTERNET_KEY}\DefaultIcon" "" "$INSTDIR\K-Meleon.exe,0" + WriteRegStr HKLM "${PRODUCT_CLIENT_INTERNET_KEY}\Shell\Open\Command" "" "$INSTDIR\K-Meleon.exe" + WriteRegStr HKLM "${PRODUCT_CLIENT_INTERNET_KEY}\InstallInfo" "ReinstallCommand" '"$INSTDIR\SetDefault.exe" /S' + WriteRegStr HKLM "${PRODUCT_CLIENT_INTERNET_KEY}\InstallInfo" "HideIconsCommand" '"$INSTDIR\SetDefault.exe" /hide' + WriteRegStr HKLM "${PRODUCT_CLIENT_INTERNET_KEY}\InstallInfo" "ShowIconsCommand" '"$INSTDIR\SetDefault.exe" /show' + WriteRegDWORD HKLM "${PRODUCT_CLIENT_INTERNET_KEY}\InstallInfo" "IconsVisible" 0 + +NoClientInternet: + StrCpy $R1 $R0 3 0 + StrCmp $R1 "4.0" OldWindow + Goto NotOldWindow + +OldWindow: + FileOpen $1 "$INSTDIR\defaults\profile\Prefs.js" "a" + FileSeek $1 0 END + FileWrite $1 'user_pref("kmeleon.plugins.rebarmenu.load", false);' + FileWriteByte $1 "13" + FileWriteByte $1 "10" + FileWrite $1 'user_pref("kmeleon.plugins.bmpmenu.load", false);' + FileWriteByte $1 "13" + FileWriteByte $1 "10" + FileClose $1 + +NotOldWindow: + WriteRegStr HKEY_CURRENT_USER "${PRODUCT_KEY}\General" "InstallDir" $INSTDIR + + WriteUninstaller $INSTDIR\uninstall.exe + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "DisplayName" $(UN_Title) + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "UninstallString" "$INSTDIR\uninstall.exe" + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "DisplayIcon" "$INSTDIR\k-meleon.exe,0" + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "DisplayVersion" "${VERSION}" + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "InstallLocation" "$INSTDIR" + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "NoModify" "1" + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "NoRepair" "1" + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "Publisher" "K-Meleon Team" + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "HelpLink" ${ADDRESS} + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "URLInfoAbout" ${ADDRESS} + WriteRegStr HKLM ${PRODUCT_UNINST_KEY} "URLUpdateInfo" ${ADDRESS} + + ;Mediaplayer support + WriteRegStr HKLM ${MEDIAPLAYER_REG_KEY} "" "" + + IfFileExists "$INSTDIR\profile.ini" AlreadyProfile 0 + FileOpen $1 "$INSTDIR\profile.ini" "w" + FileClose $1 + WriteINIStr "$INSTDIR\profile.ini" "Profile" "path" "Profiles" + WriteINIStr "$INSTDIR\profile.ini" "Profile" "isrelative" "1" +AlreadyProfile: +SectionEnd ; }}} + +# ---------------------------------------------------------------------- + +SubSection $(SECT_Bookmarks) SecBookmarks ; {{{ + Section /o $(SECT_IEFavorites) SecIEFavorites + FileOpen $1 "$INSTDIR\defaults\profile\Prefs.js" "a" + FileSeek $1 0 END + FileWrite $1 'user_pref("kmeleon.plugins.favorites.load", true);' + FileWriteByte $1 "13" + FileWriteByte $1 "10" + FileClose $1 + SectionEnd + + Section $(SECT_NSBookmarks) SecNetscapeBookmarks + FileOpen $1 "$INSTDIR\defaults\profile\Prefs.js" "a" + FileSeek $1 0 END + FileWrite $1 'user_pref("kmeleon.plugins.bookmarks.load", true);' + FileWriteByte $1 "13" + FileWriteByte $1 "10" + FileClose $1 + SectionEnd + + Section /o $(SECT_Hotlist) SecOperaHotlist + FileOpen $1 "$INSTDIR\defaults\profile\Prefs.js" "a" + FileSeek $1 0 END + FileWrite $1 'user_pref("kmeleon.plugins.hotlist.load", true);' + FileWriteByte $1 "13" + FileWriteByte $1 "10" + FileClose $1 + SectionEnd +SubSectionEnd ; }}} + +Section $(SECT_Profile) SecProfile + Delete $INSTDIR\profile.ini +SectionEnd + +Section $(SECT_DefaultBrowser) SecAssoc +SectionIn 1 2 + Exec '"$INSTDIR\SetDefault.exe" /S' +SectionEnd + +# ---------------------------------------------------------------------- + +SubSection $(SECT_CreateShortcut) SecShortcuts ; {{{ + + Section $(SECT_WSShortcut) SecDesktop + CreateShortCut "$DESKTOP\K-Meleon.lnk" "$INSTDIR\K-Meleon.exe" "" "" 0 + WriteRegDWORD HKLM "${CLIENT_INTERNET_KEY}\k-meleon.exe\InstallInfo" "IconsVisible" 1 + SectionEnd + + Section $(SECT_SMShortcut) SecStartMenu + CreateDirectory "$SMPROGRAMS\K-Meleon" + CreateShortCut "$SMPROGRAMS\K-Meleon\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\K-Meleon\K-Meleon.lnk" "$INSTDIR\k-meleon.exe" "" "$INSTDIR\k-meleon.exe" 0 + WriteRegDWORD HKLM "${CLIENT_INTERNET_KEY}\k-meleon.exe\InstallInfo" "IconsVisible" 1 + SectionEnd + + Section $(SECT_QLShortcut) SecQuickLaunch + CreateShortCut "$QUICKLAUNCH\K-Meleon.lnk" "$INSTDIR\K-Meleon.exe" "" "" 0 + WriteRegDWORD HKLM "${CLIENT_INTERNET_KEY}\k-meleon.exe\InstallInfo" "IconsVisible" 1 + SectionEnd + +SubSectionEnd + +# ---------------------------------------------------------------------- + +Section /o $(SECT_Loader) SecLoader ; {{{ + CreateShortCut "$SMSTARTUP\K-Meleon Loader.lnk" "$INSTDIR\loader.exe" +SectionEnd + +# ---------------------------------------------------------------------- + +UninstallText $(UN_confirm) + +Section Uninstall + + Call un.CloseKMeleon + Sleep 1000 + + ExecWait '"$INSTDIR\SetDefault.exe" /u' + + Delete $INSTDIR\k-meleon.exe + Delete $INSTDIR\k-meleon.exe.manifest + Delete $INSTDIR\readme.html + Delete $INSTDIR\k-meleonloc.dll + Delete $INSTDIR\Language.cfg + Delete $INSTDIR\License.txt + Delete $INSTDIR\loader.exe + Delete $INSTDIR\uninstall.exe + + Delete $INSTDIR\AccessibleMarshal.dll + Delete $INSTDIR\gkgfx.dll + Delete $INSTDIR\js3250.dll + Delete $INSTDIR\jsj3250.dll + Delete $INSTDIR\mozctl.dll + Delete $INSTDIR\mozctlx.dll + Delete $INSTDIR\mozipcd.exe + Delete $INSTDIR\mozz.dll + Delete $INSTDIR\nspr4.dll + Delete $INSTDIR\nss3.dll + Delete $INSTDIR\nssckbi.dll + Delete $INSTDIR\plc4.dll + Delete $INSTDIR\plds4.dll + Delete $INSTDIR\smime3.dll + Delete $INSTDIR\softokn3.chk + Delete $INSTDIR\softokn3.dll + Delete $INSTDIR\ssl3.dll + Delete $INSTDIR\xpcom.dll + Delete $INSTDIR\xpcom_compat.dll + Delete $INSTDIR\xpcom_core.dll + Delete $INSTDIR\msvcr71.dll + Delete $INSTDIR\msvcp71.dll + Delete $INSTDIR\freebl3.dll + Delete $INSTDIR\freebl3.chk + + RMdir /r $INSTDIR\chrome + RMdir /r $INSTDIR\components + RMdir /r $INSTDIR\defaults + RMdir /r $INSTDIR\greprefs + RMdir /r $INSTDIR\ipc + RMdir /r $INSTDIR\res + RMdir /r $INSTDIR\kplugins + RMdir /r $INSTDIR\locales + RMdir /r $INSTDIR\macros + + Delete $INSTDIR\plugins\npnul32.dll + RMdir $INSTDIR\plugins + + RMdir /r $INSTDIR\skins\Phoenity + RMdir /r $INSTDIR\skins\Phoenity(Large) + RMdir /r $INSTDIR\skins\Klassic + Delete $INSTDIR\skins\commands.txt + RMdir $INSTDIR\skins + + Delete $INSTDIR\SetDefault.exe + + Push $R0 + !insertmacro GET_PROFILES_LOCATION + goto AskProfile + +AskProfile: + IfFileExists "$R0" 0 KeepProfiles + MessageBox MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2 "$(UN_RemoveProfile)$R0" IDNO KeepProfiles + RMDir /r "$R0" + Delete $INSTDIR\profile.ini + +KeepProfiles: + RMdir $INSTDIR + + IfFileExists "$INSTDIR" 0 KeepInstDir + MessageBox MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2 $(UN_everything) IDNO KeepInstDir + FindFirst $R2 $R3 "$INSTDIR\*.*" + +FindNextFile: + StrCmp $R3 "" NoFiles + StrCmp $R3 "." KeepProfilesDir + StrCmp $R3 ".." KeepProfilesDir + StrCmp $R3 "Profiles" KeepProfilesDir + StrCmp $R3 "Profile.ini" KeepProfilesDir + RMDir /r "$INSTDIR\$R3" + +KeepProfilesDir: + FindNext $R2 $R3 + Goto FindNextFile + +NoFiles: + FindClose $R2 + RMdir $INSTDIR + +KeepInstDir: + + Pop $R0 + + DeleteRegKey HKLM ${PRODUCT_KEY} + DeleteRegKey HKLM ${PRODUCT_UNINST_KEY} + DeleteRegKey HKLM ${PRODUCT_CLIENT_INTERNET_KEY} + DeleteRegKey HKCR "K-Meleon.HTML" + DeleteRegKey HKLM ${MOZILLA_REG_KEY} + + DeleteRegKey HKCU ${PRODUCT_KEY} + DeleteRegKey HKCU ${PRODUCT_UNINST_KEY} + DeleteRegKey HKCU ${PRODUCT_CLIENT_INTERNET_KEY} + DeleteRegKey HKCU "Software\Classes\K-Meleon.HTML" + + DeleteRegKey HKLM ${MEDIAPLAYER_REG_KEY} + + Delete $DESKTOP\K-Meleon.lnk + RMDir /r $SMPROGRAMS\K-Meleon + Delete "$QUICKLAUNCH\K-Meleon.lnk" + Delete "$SMSTARTUP\K-Meleon Loader.lnk" + + SetShellVarContext all + Delete $DESKTOP\K-Meleon.lnk + RMDir /r $SMPROGRAMS\K-Meleon + Delete "$QUICKLAUNCH\K-Meleon.lnk" + Delete "$SMSTARTUP\K-Meleon Loader.lnk" + goto UnEnd + +UnEnd: + +SectionEnd + + +;-------------------------------- +; Close K-Melon Functions + +Function CloseKMeleon + Push $0 + loop1: + FindWindow $0 "KMeleon" + IntCmp $0 0 loop2 + SendMessage $0 16 0 0 + Sleep 200 + Goto loop1 + loop2: + FindWindow $0 "KMeleon Tray Control" + IntCmp $0 0 done + SendMessage $0 16 0 0 + Sleep 200 + Goto loop2 + done: + Pop $0 +FunctionEnd + +Function un.CloseKMeleon + Push $0 + loop1: + FindWindow $0 "KMeleon" + IntCmp $0 0 loop2 + SendMessage $0 16 0 0 + Sleep 200 + Goto loop1 + loop2: + FindWindow $0 "KMeleon Tray Control" + IntCmp $0 0 done + SendMessage $0 16 0 0 + Sleep 200 + Goto loop2 + done: + Sleep 1000 + Pop $0 +FunctionEnd + +;-------------------------------- +Function .onInit + +# StrCpy $1 ${SecFull} ; Group 1 - Option 1 is selected by default + +; !insertmacro MUI_LANGDLL_DISPLAY ; Uncomment for multi language installer +; !insertmacro MUI_INSTALLOPTIONS_EXTRACT "profpage.ini" + + FindWindow $0 "KMeleon Tray Control" + StrCmp $0 0 FindKM 0 + Goto QueryClose + +FindKM: + FindWindow $0 "KMeleon" + StrCmp $0 0 NoKMrunning 0 + +QueryClose: + MessageBox MB_OKCANCEL|MB_ICONSTOP $(INIT_KmeleonRunning) IDCANCEL 0 IDOK CloseKM + Abort + +CloseKM: + Call CloseKMeleon + +NoKMrunning: + +FunctionEnd + +;-------------------------------- +;Function un.onInit +;!insertmacro MUI_UNGET +; MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "$(UN_confirm)" IDYES +2 +; Abort +;FunctionEnd + +;-------------------------------- +;Function un.onUninstSuccess +; HideWindow +; MessageBox MB_ICONINFORMATION|MB_OK "$(UNINST_OK)" +;FunctionEnd + +Function DirectoryLeave + Call CloseKMeleon + + IfFileExists "$INSTDIR\k-meleon.exe" KMFound + IfFileExists "$INSTDIR\Profiles" KMFound + Goto Done +KMFound: + MessageBox MB_YESNO|MB_ICONEXCLAMATION $(INST_AlreadyInstalled) IDYES Done +; MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION $(INST_AlreadyInstalled) IDYES Done IDNO Retry +; MessageBox MB_YESNO|MB_ICONEXCLAMATION $(INST_Quit) IDNO Retry +; Quit +;Retry: + Abort +Done: + +FunctionEnd + +; ---------------------------------------------------------------------- +; Section descriptions + +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SecMain} $(DESC_SecMain) + #!insertmacro MUI_DESCRIPTION_TEXT ${SecAllUser} $(DESC_SecAllUser) + !insertmacro MUI_DESCRIPTION_TEXT ${SecShortcuts} $(DESC_SecShortcuts) + !insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} $(DESC_SecDesktop) + !insertmacro MUI_DESCRIPTION_TEXT ${SecStartmenu} $(DESC_SecStartmenu) + !insertmacro MUI_DESCRIPTION_TEXT ${SecQuickLaunch} $(DESC_SecQuickLaunch) + !insertmacro MUI_DESCRIPTION_TEXT ${SecAssoc} $(DESC_SecAssoc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecBookmarks} $(DESC_SecBookmarks) + !insertmacro MUI_DESCRIPTION_TEXT ${SecNetscapeBookmarks} $(DESC_SecNetscapeBookmarks) + !insertmacro MUI_DESCRIPTION_TEXT ${SecIEFavorites} $(DESC_SecIEFavorites) + !insertmacro MUI_DESCRIPTION_TEXT ${SecOperaHotlist} $(DESC_SecOperaHotList) +# !insertmacro MUI_DESCRIPTION_TEXT ${SecTools} $(DESC_SecTools) + !insertmacro MUI_DESCRIPTION_TEXT ${SecLoader} $(DESC_SecLoader) + !insertmacro MUI_DESCRIPTION_TEXT ${SecProfile} $(DESC_SecProfile) +# !insertmacro MUI_DESCRIPTION_TEXT ${SecRemote} $(DESC_SecRemote) +# !insertmacro MUI_DESCRIPTION_TEXT ${SecSplash} $(DESC_SecSplash) +!insertmacro MUI_FUNCTION_DESCRIPTION_END +; }}} + +;------------------------------------------------------------------------------------------------- +; Author: Lilla (lilla@earthlink.net) 2003-06-13 +; function IsUserAdmin uses plugin \NSIS\PlusgIns\UserInfo.dll +; This function is based upon code in \NSIS\Contrib\UserInfo\UserInfo.nsi +; This function was tested under NSIS 2 beta 4 (latest CVS as of this writing). +; +; Usage: +; Call IsUserAdmin +; Pop $R0 ; at this point $R0 is "true" or "false" +; + +!ifdef _IsUserAdmin + +Function IsUserAdmin +Push $R0 +Push $R1 +Push $R2 + +ClearErrors +UserInfo::GetName +IfErrors Win9x +Pop $R1 +UserInfo::GetAccountType +Pop $R2 + +StrCmp $R2 "Admin" 0 Continue +; Observation: I get here when running Win98SE. (Lilla) +; The functions UserInfo.dll looks for are there on Win98 too, +; but just don't work. So UserInfo.dll, knowing that admin isn't required +; on Win98, returns admin anyway. (per kichik) +; MessageBox MB_OK 'User "$R1" is in the Administrators group' +StrCpy $R0 "true" +Goto Done + +Continue: +; You should still check for an empty string because the functions +; UserInfo.dll looks for may not be present on Windows 95. (per kichik) +StrCmp $R2 "" Win9x +StrCpy $R0 "false" +;MessageBox MB_OK 'User "$R1" is in the "$R2" group' +Goto Done + +Win9x: +; comment/message below is by UserInfo.nsi author: +; This one means you don't need to care about admin or +; not admin because Windows 9x doesn't either +;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!" +StrCpy $R0 "true" + +Done: +;MessageBox MB_OK 'User= "$R1" AccountType= "$R2" IsUserAdmin= "$R0"' + +Pop $R2 +Pop $R1 +Exch $R0 +FunctionEnd + +!endif + +;----------------------------------------------------------------------------------------------- +Function GetWindowsVersion + + Push $R0 + + ClearErrors + + ReadRegStr $R0 HKLM \ + "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion + IfErrors 0 lbl_winnt + + ; we are not NT + ReadRegStr $R0 HKLM \ + "SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber + +lbl_winnt: + + Exch $R0 + +FunctionEnd + diff --git a/k-meleon/Install/makensis.exe b/k-meleon/Install/makensis.exe new file mode 100644 index 0000000000000000000000000000000000000000..2b500d71211075431af8387d7822b073e1363145 GIT binary patch literal 195584 zcmeEv4|r77nfD|!z<>iY=m=3`jXK?8gNlZB!J#&g3`8I}Nl3sI!M1F6N~uzrQCgEg zycx{R;UcbtwXL}B7PoGtmah60m0$wM0RH2TT3g)~Tif0-Xi=#IMDzWA@40u90QS$< z-Tj{LdA{&)?)m?|=Y8Mvp7*@x+&h(jx5nf3csxG*@9p(?Hsi^^QVIWfa2UlSE_iZ; z=dq#BU${AM=JOZMPJDG~(UMzk{)bz>^!1{zeCei}ZcY|``R|KvN!?WR)tidSudONi z`ppaf{<7i2hee#O>!)9ucTsU!wfq0NzrD8lLZmClS5#k&=fC`IW%U)3zNUH^o~7gC z)x~&TR6M2nHasK#Yova}Ur`-F`Zt%xq+Rt_zmi~|CyyW=^LS?F`8@N!yFBWa9rOhA z&d3|=@$Aj>c&^5O{C#ZT8A9YB)1^9|ujzygp%jss% zzUyFU!5Llix36*jRCy$%W&+#U5q}&Bf7K$-BLAY`B7b$<4gzCiM^Uaa+Ek%VQM$9H zwr)-aO-Z(3%bk!vHN4a_#na}wDleG64QZnxGQKF7Ud$pHaq5f(^KaPvac^($_1A3& z$U@^-Zz_OJ3ZW@H%mCFQ>E6Z>M}Nt#NiGvP0650z$!q8`dWJ6Ff^LiasmG08f5RrD zH@N)a^zMf58^?w&|5wx-o9=A*j?t69yj@+o;oxLXV)H1EXHjYI%jz&#An;G*;72gz zkh!$LY#Q@4VIBA#a2R8B4KeEqtZBXG)Um>`0|(7n6-HOS`6+X1d4)N3=H`cg@Pi*5 zePiESW?kG0f3bQ|so50iec7BkPEC#MI~W&uvqQH7GJ699a6WQ;j=k~Mv>+u_Q! zz^m(EzOK8PDJyIN2aj17P<7)<-j1R_f3W3TAU5%)3Bi_;5}6cip<0MO6KwI|srK!A z%L>OWUxjyE#x~R^)smP9n(PdpkO)XcmChhx` zSvS7kTs-+>RadT>CRsDj{8;Vl%I24JzW=b=W4z&g{|9PngXJs57)y57tJZ&fW3s1Y zzp=x&z?`+LUaeWf^lo!q3y?$cS}8VHw@Px&IwUt!rI|M^G;f-1-n7`9y2PA1*SzUQ z^QKa>E;;{(l1>OwjeRvVE_;PwIgDlWxaP4)culQZ90{b~uA38V`4H+--GIp#Y&pzm zL!`jy^#$+xH4^FG;HuY{84IL4gDrazH5xsh)EO$~Lq_^(mX-Ow@Ezcl8p>wrjm)YH zrFW->5$cD8y4~pctXf)R7Mr(2_%j%TnlVO|HFUiZXwG_;c{~;SdW;_Lt%EkBF+^bS z8M{>3!gOcSYwRv6*{`~uz5w}0kE)EiJ)9}?eFLfDZC+IJgTin5Tf-AnO?Zk~6IR<) zjlVUJuV#eN!{l_QiO8|!Ocg6cL6;p;ySlQda1}a2#xxU;7h8S9+~%>uPg6UoUFtaN z>#FFY#y=T7p<-`Ym=wyyL<&?{7+Bt_Y75kqFh(8ix;0;QA#0YpC8Qby=!X*U{)3wT z8&oQwDhs@a%~T+7GAe{sD#VPQ;=^WR*i3~knH*NJ0#y+P{RXQFzgZC?I28+}J5yso z&`enoDB257ZxJ(UgQ7 zf-IqLSphgHWW_K&BzU1(8dftzj`oV&T|q(12?xXhiBc1f!>H_tl1R~&11eIAP8r|y zzd~ld4iSMULS|xqGZq4{1@lWf)4MUY0?JEptq2UI2#gdFaz;tfkmaZUdR8L~cKU;4 zN=+pZZc=l7#)qFx4mUphM$+H>q0IN|RH;ARIY)gVf<-0ijraZ(l~w5^)R)Ap0yTMp zo2bJK8RsUXPu3~vM2Erl&IOsN1t76!{`D2c!H>4jKN+Jc+6Mtu7N|8kKl}n`s9tCp zTk12pT9+-xa(G*$#=enjD^fe4p;BRL{PgZ%%jX=?{d-FJjD^r0Xk^Ymy}>)yAyK?Hz1yr=Y?du-7@}&%dG~eam+W8UDej6_*Vs=%%F&JTnrOeI zK-Gm+MF>(J-3JA*FTFoGUELZ|%K~bT%4!AhJQsis%&I8x9ygZ-@~T2A5mw7W%y`R8 zgo}|Ix}++sN^=Sz?lX zu_gk8&xFB*A*dPS)zZbqyNX{hXGRKABLV0Fm{;eaxFCBEs6xYTI83+#&bDkba@5j@ z_1Klik&f=X@T6{}H#yifMlvlF5EeOGRSIvlEEa&P1a5BMSf0;pz-ESuBxnfr{j%W|VQrFD6d7Zca%r%;k`ZE&hVE_)M++ zMM`Ik3PNWEK!zgDucu&raC!R;bOn~YTVg6!sw(5EcA-kmJaAA|j>DE?-pG7aIjN+# zWc$USKxw_2G+D*Qs>%r$Z>u*EuPs%vN%g97A;H$0fq1$%`5AT*ixmGJ$}?w%ZX1vsOuT=}1|gK;zb# z_GECW`%KB`vWKAQnweSTZ9}{CilIOwO>5ji>4wE6yDOr5fvl=s#;N>jbenm@V({tN z+rDfZ^WJhpg^XpPYAh`^V+$3kjsu*T`LK;ZPi!ebz|6(5nV?@uuTZdZtcp#zcpoSj z=TKE;sj8iXkxmDc3Q`h1rZ#5(nKD|rP}Pp}?(*&{=`<0qjAvqVk?(2CM}G$n0@C!n zk}lnS_fjGKxHezDvV=hGBxrrcH$68Vi?nR@jZ~VP<&iKXH9Ymxq@pQ#B*Q9#wuB6l zXX&hKO7=(JRh5f_YqwovRxVcW^~M&aKM1y{k04}~v#}2w3T#!ER?I*KE6Bd;c&+`- z;pi{6(2UJiG0$mL->lpc@-w}JJbSt&WUjk}{M?*-x+TQ5Aw!&`)PKR20~kv7Eo==m zfkSSVE}~nUl0MrU~^l^9Sl_7HCb) z*c#(dn0s+l9iyft)trUuwuriRoVs}lY=yA8lUpk5erjItp6CJO72G9 znlrAgJaU%zl?lGj2GbN;B*#oB|7>qCeK%A2^atF@*p$2}S53}KHDND3rEPNF zr^?*ORc_=8H!{YJT;N7Vxsl;+#20<`mdDh-;sedwh-UO%^f-hokghj3Z^Aq`H$R3jvtlDc%p%W|p8~7u&51^rZ+hye zdf~}WA+s<2?336m_NC3u8>Ej1Bz#Ch@@c{R`pk+|FeLNf4sm?td=P)tN{Gg>;b3G4 zgK3(p-aGJH_^|4SZX!l%Nx1D^Mp_H6KwK^J)Asx^GNzhK!mWY7h1W}MVjq*uig5iC zAy0kr3-t%yGIqXiN_M@uhRwUrJn*afp%OK^yrw{PVf(S-hnvQzIJV<{7urZBm-wfc zc);)9wuUfU!y~%SO7Ctu6BSXOtJ_`Ry6?90p=1l9FDK82W+;l+0P;6+z5@qj_Pa2xqg`q>#XFe(CxC`rHhl^8i>xX6 zYAx%^6I2%-RFdnolANe!h1ELtHQAiyDvtUCHpNo1>&=zy zp!*ymVsz#oI9NYaa;TdHiNs6L4vEs8E`g)dERUpz1%eY9f(5g`cZ7PP%JR|FQwQY22$+IemD)% zq|$f*2`l!0335Org_2-RIq_dK?jr-oO-TtGohSMY-{%Y;1tq<(xmQ07v2}?tylDyK z@t-((xRq*I$LaHbE-<_x@F!&X;*!p`J7uz}wJQm&KF9x@RC5s1qCLS?wb&rfsIj(E zDa@&}e+BEavevqv`kq#gwf1;ITVrF4PTw`Dqt;5+enMMhxjY(w zPiU*m$(y)1QdFN=sqHWG5m6P7h>7-ym}rmCL`x2>v(LxU4EH8?>)J{)4pqQvfV!JY zpU91BnqMUXsz8k{>5SU&T7=;42xB0<=E@43X=hf>MEC_v(x%VX8&`Rf7pc|EpKQv* zY*{@Uvxcseoh{?yDDZR-uFp(C{ZeC_FZxWw9$nu!mfyHQ*xi%gIHZ&f=w=$&4GgUi z{Bg~Bo}Dd&r8BjTgPNXx&6G%Tc**{HHQUI)WF3c`>$>4V84Ef!r}>m1{_Wyzs%KxX z(VN$BHv63e)xAdCtAT5g+1O3n)GGXeuB}$Bsl-G1qr}vm!gbZpmi?1=|;gCkgq{7Yh-tZIHB%5cot-6{+gCMV!F zcKh|FNA3Bzt98|7tR=0@#m)JP@^GKviTo<_5yGyE8QXn!7pSb!2QEB>wJxWNM&l%? zy9jPGo$-}}<8dF@UFuh0ddo0IUqhSHe4HX;E{==~TK^6M$ZA>V$i=+PEWr`|UhupK?QX=F=Bc5az~w5R zPTvM2Uu8<8&orF@E*4Bv&j4&ebY>({Z=%NXFM}&%;CG!$w6HqwX*fe2D?X0gv1-zj z6o|0$X0*u}{L!|&l@u9>S|QFDFT&*p9Pj{?m9JKd%m7Dk2K8{{pfg;QxN3FzDnNvJ zL^YVMAvJ*tPsd*ZHK2;?jV*$P$66)N)G!>XRMZ<2J;@L1dv#vD(K7Y(Ks6s3HxXy! z_xb7G8US%#^2^pnAsdEvqpCbH-FTaR#2ZNpl6Lu3 z4$&+SKAOSceqU@e%cp`rvXzY6`wT`r&Xjn)c@@YouY!H!Z06skTfn^5cpC^2dTIrj zF&-?R9l2^NFEf!H6YIS_@Ie~e^7s92mdezdQ$9}pj#C$xho*oYA!}|PsXiwkhnvOL z%-IvT5x7F_ltY85_2v~NyVYUiw|Qs0u+QH2#`N_5<%joW>&>8%@y$p%j>8If&xnqF zY7JG2R!aqH<0guZ75IE~&m15b4&L=`U`9qXUa1~yrTnXnt*isi|D;|O{-{2B;FdE} zBi#wLb_}P^ZF!SHiZEI@Reyx4KVj8NQ=v9p=PEq~Z!HFC3eCsXu%L2fFWY#i(*V`!lQdq_ySKs+^rVJ8*@nkf zXcXT4DonqIdl2^y#@YNTdWg$vX?38Wz)B3pjWu*u>6sQi-sp>VC2xv;+&HX0Z;Qc2 zp?e%;d~_7P&ZHkRMDpr;jmKDYw$VFm`B0=bGc^Q}Er?)I-3@sNr2>5@be|jTLYlYC z1f}j_f~=s5(G(ibU{>H6Oy7)w+aL-H{dW@g zoO*Zy0OM5Jy6&A3P4kUyAN^%+rK`!{O?n42(5>{|0Jlf+$2qxa>uIP$_4D6N z6~g#rstj$q-q`ks|0ld-;q)4l3IFs-1EV1u>iYoXpMiu7pog{B4MWU}3(Uio8AEXT*$ z&zpMA>6}<_E?P6MI_$WvvQJ<(!H{p)`zdi+dSA?b54q0Ndadm{ys{t)e*Iu5{tn{B zwV?Q&=<~RU5^DMe##*E+_)tM5{OT76eqBFQJj-yZwu!H(QBJ~;idO19R}9_GjDiw4_7aC zWrra7ZMob*dCSe+`@Lmoimi~ zk$tQD9%p7_21Q#r@o-6yM`1Y%KAsQx$oa&ZzD)YH^F5URChgaayw_u&`?CnkLdJXfOT$@TiQ z7w^y2s-G$2Af`s0dep|FeTv>5}R>_8Z^HBla+P!^Uphdw%bc zqx-J07GIJVeW&5&Za>T{YY#*NzKsGYS076am5rfj^^aI&5P(u|BJ@5J?J_0ZboC(5 z3b<)agZUblxZV3V4m4AcOP!;eRVCKqXwBZFOYJXAb9==O>+^;H<4xZ^y)jgt6xH@%5IV_cCn;i z;~mmiS6tcIzuCG?NLAa@q}c|<<93ws)%PM^Wna$tx>l)kvD9ghI-{k|VySb6)VWdW z^hP*>xYT){@zv#0=XZ>+n;>;wlR6Qp^P zV^ZJQ8R;miB+ge~Q(5x{zj=etyuo9xCm+o9WS+U6otW#7NO)L6f-u(?0jRmYP(mVL zt{*Gm7zv4-Zmv&AxKKip#ay41aEXK@nz_D3 z!W9ydq~`iH60VYv1UJ_|AmM!y-Yelo2_KShgM^zUd`!Yk67G<2mxNm++$-U82#sC6 zX1Y_7uS@u0Ob+aG;jPjH#sPqUex-|tS1z7LBa99%6s zLjj|#LICsb#2lA&)77e-i0GMKZKhdlpLekU1xA7;=D6g?^&EfhA}O`6E5qF$VSnl~ z%^hqgGyFVdvBxSc6ZYq%w$EJ8Ox3}$YLLa;*1q69F7JPACE9&2futj-Msle1Si~IS zgoHR@D@UB)wV#GKp;L(S9CXSj6Xy|XoOXgy))MJVgo4Z;AP2DP z!`HpFvsPm9@F||EYWvRf@;p*&QP@oT1ek!dq|!?xfK`?KWmftaChMY6X4=n6?R|J9 zCWWSWa0~hisAQ%CEVbAX^ilNLhQP%2Y|sGQ8_!I5i1>mc(%NSqDs_2y1nUe1y!e=` z3+kxVeh_B|>UeH_P-$7tENUzf9hfA}!ift<)}&F1m(a%?`=NXOl=%3f?>E+J(P5K; z^9nYB0I~#-cW2zbjRfqFC97RfctLd)_qZa?9&#dXt`C5)=6b(`J_$V%o)E3tgV0Ks zGbcR{p_LY`lB|1h++G+Qj;5($$CTh~7(;o}niFA0Bw5V}~x%@V$j zP_*Q$h&<`R(r>o6B5HMPK`5I#g4m0MxqgR)&q=t8Vf#x6t&R|c;fbe#&DKe0k#_YD zE|{;L;RQ?FU>*3!{T@t!=u{tGfNX*fZ3QitsXjG0ZqLM7k{C$lV7%He%jeiCKAmmf zeKoi?74}o=!saHQOws~1syZ_j)WK{|o-Y!Z;hxkp-!(f_GdZCu0(g1Mr%H>qUUDgKhz;4jBX4Uz@H)nf8N@Udeqvc{jGcD9Au z_FOeORoJpS8E%W`Au%T}H3A3HMkc>ycj_SCS{QU*r|~L}7hC=vW99Z_fWf#ADfN*| zg6N*56@4l73hsHJOdFQoeQm?qx~{7902XXg+%;#4u(stJ&*Wq9zw8Gq8Oy<-x0A|y z-Whq(SA(mrhNBQxZU~0!Ks;!;E-#}MsHvw8bbp$|l#X%>q&gr-S(ChuN$ka2M-7jl zncC(y#0@6z^Hpk(-ND<8T#Ru|#;=|){wVvsKf;N3Tr;e&66}-){oWv2T^R-Zuf~*bChphp{-n zo}d}Kk}RzOPXjn&LX^|5cEH@@i>dzybMO2Ab91jO$FI}PJ=l)@rd1zDZ@7MeL$*_A z9<8s_b957$scmjU%sk6?Np$6XoEJjBrb!ea*V2*#`yUHj%`Mc1r6u`}rB$X&?Y-cL z=7DTBx3W)Xv#GaV8EHlRZU5V7t<9xB=3wAB-XJg48nThvM#Sp*lU__-!BR?=JNTSz zG4kih*C?1hvJyFp1NOa}lasGIKJUmERl6f!8xj5g^2M#sUn*Y@fpX?b((fesVu5`n zPA#-$u#(iKd@nNGp-AsnW)mk^cJRi`8%=lHn)H z7fU};zM2me!lbTI`_y-O*h?8cH=tjwEJ_YiGm5&sc#k+8*`2if- z1#pz(fGx_Bng9-`2dS?WbmyyL3sE5vA8SvhIZ|`!eVYDyWLjVoWb3tz2K{TOwF_(+-+GxdcR$JqT zMRzvktHZz>AE|gIHLv+&5GSv3b`&osFZDNFVXf2_TbWOJpSLzFa{xQ|83DK{U$&gF?rP~K6Xn@{>Lzo@k;uVvESQiHC%$PI>5V62^%~odmNGI?Kzpi7dBSEgDlF#&H*x^Q?5*8*q$=6 zG|bPv+)kO89hp$wUnW{2lgR5jEfX^%KvJRJ1j@AdXBDoT`N0}81wS~N6n zPueV(Vc`}%KhZ-G`v4!#0kcnG*D7Hzv{qQHjZ}b#Y9$#cdIbtX?|=s3jeKYnkNB=; z`+a~?0MwyY#zMV}vmbdBE#(I@fw=wXnRoDvqD#F}}SUe7o026a}Lfr1+Kg8k4j zyjQlqEn^oRNE6#RHt6FuK-x~h!d_5RxFXJyFBO;cRg|YOrj7&wH>R8qcrgT48Akf ze8>+N>HRh8XUhZl{z&r%?0yH*;!=*&*DFN4okYCd524^v4)tDuNAYod?LdEfq0h}m8)U)!WDs;O z-qw#BW&Zw2Z6<5p$)T1u0l09m=Rai%+=Yc413G!}nx?bum&Q7#z~6)TIa6RR64^2Y zC-IyMGu8fIZVH^1*Ev(bW%a4108NHd`25$H0<+H041TRx7z|V3Ca8mbb6^eVci`na zS{t-2u;5f<;ETHb$@DxrOn2LYZcl3rd|fKQ7!WH@CSJeoHTFM6n3l?*dokUKZ+>8M zAC^qdTM&J%q{-Zy|DOtD#H6c3~q9w`|$YVinU~sfv<(Kp>@>q{XfM_k0pdm0C@F9=xI=vg#_0-SG(yujr0ggfStan!xYJR&L z^92rM^(5O`cQAyvsQ5$pAf6RVO#Pw1AEJ0WG#tKjRBK-`6v#a#F52gxd+xcT|KJCX z_*CBw$%q;<9izil)^NiJgn{M$iQ|GTJd`y$@t(yr@<7#f4sI& zlc`8u>qAW(Sm1cqoCepY8tv|(r}^wEK-L?aAy`wU`JA22P@QeBy97g+rd^-QUDs!@ zDl-k16b#32`q|o-8N!qrqUQLmhWtZM;DVyZ0=W0#j)fXFb`)uYe_VB96)nGqr5P;0 z%~ztPQ=W*kXpQc1V3FQG`&FL023K|Ju+iNu2i;_NaP=Yd(e0xN3Oe8`B-U7Ou;qRt zl!W>5jJP#N^>=I5Id09Jr@A$Nh-Ul}V1BAG$7?KWg>+ibgX#J<7qD-n-J|lCwSQAf zhU4EHks8mj<#J!iYu#7iyJ0Hh z-4;iSppBV`BxT}770n&7^v%BO{l%}U$Cq)2j@T@7uHLVXcl{pU=1KQ9g(jX8YfOLoflMuPG3B_L*^r6)GjdZ27~1EuBf2>mZ=;y)rcO zqFD%yobvwsz>+sQv5|d!sb62tARIK$m5trX3t^PXnhR=RXXDh-xTZ!Yma&tDj8bfFcgakQbjHkvHix$D)@W~Bah{a>|;s{VC0W=wte-*5ayHDl_7C=UAa)I zowTmxSQ@}I7WOSD)oh%9$`J8>Dm)Lk@IzjdycXR)CwWd{#UKp!a@}=K;F3Vt1r)2*rD&{`(;F7PYPot6(xRj= zeYopd$qKlFuzCWX?krl#TJ|>uBR_6vtYje^m+P4CXr|BVQu`+mkBRrQ7hFNu$_maE z1ZfmE@0Y&r!A2INGw)|l(GT_YBB~`{o4JytOAcFsPnsruCA+%^Jppl8VOIDwA=_e} zkOaV&nxRY;?@q+uS!>3q6RojFVxxg zBNsrjurcNlw|18{6~M_y2O<9KyRlCO_8IuxP|wTPAVb(t_;C)>gG+e4Bhqiz=NzyN zG%#HKmI}I>G&M++qG}d>*}2&>c#0=AXmbz9B_E8ACtf1ungn*hRkSVv`fnyu7b-)m zJ*cz^=*GTABkUNM(4wyX!ty|Sm1CCN1$slIU~@HGjL+ae#8ynoyA;C+ za2R*!KKq8D^`5$iQsyc@a|(SOT!S9vvZZ^Ric#p~3&~;gVG!sl^G!wdqZ2ME%HC~F#!tBDm%;0It!r8X~4Ied!xH;|ORoNFLZ&d0E zjG+kAr;wIVO>Nw|*3bRhF|jj)>8B{W6LUEbe> zJ*WD#*q8jZ>aDJ~ef)y;LqHz7WGEJNIQ6gqu3m@G`i9SFI&o2|TwR^+ZMa&gWnitA z2w0wZlnHJ?n?A4TNAg8qOa|OdY12jBZ(;9ij)IdBpZxAEl?_^{u@k-(SP-GciQOC2 zJq468n2QjXcp@+a^0EfLc2lsr5kJIKBSQ#3>rSYrCgf=N zJubXCtO2a)ntm8xehS7}+?L1DNBR&Lox}RzX|aCNA<`9}M5HEsoQkfBQ8@0aQB!gK z8G<)8fVmm%YMK(SQi{C62Q~19b5(VsoV+>G18&vf`|g3_ZC0SP>kY3JuC^Lp#?_44cMeIqH7{~LPE^A9aCjF%%Doy@PhbMYUGqOA@ zAn?;uM-ofWi+$iIQTD0yOw<8Ihb2nc`CZa^L^=;zbOI+r$gj0GU<3wDlK_Sq83v1~-*)u=Q9_hZQ za*LmY?PI2imf&zY1nzV}4M5-A6C&V9R>Y zRHc_Ww7Lta#A9cWR;vKwfenbBN-O5tuOB;!R+78Z&CQ`&-iNBtiq$}?^>6p56*D!h zoZ{6VkXA&?b$$fXj|Q32YkDyKpro`ZgCnyg#A*8;#_~FLx!^lD@h9<}`APT&SKml=su!9UlEFTl zv(s2WoYuNH-TUX@G+uDp@eh9uPR~&lpAM%-SwNibb8&j$&%r4oIF0+OaGLN*I9=f4 zw86#cp+5(wkl=J*{a-_;4ZJ>iIy%Wmeo3c|E>4>?P65a+!YHR|+>ngW;9MI1b4O?yhKxU_C zSDe+&6Ac@;*Sfhmjd3RW*UAlj(|r3zR&>R=GUssVV4kQ7^n7DAO22|*XHyVui-lS` ztwvm}v7z(Z(!5QL47pW}FJo{W=mDm4>;mX{eE9*I{)5z~<|K9@)4uavfl6~voaBz~ zQ0cx4^>y(@c~$n0q2lW7T7)(B6Ih|)%EFz5)Mw_{&64uXNj$_3KY#iT6B`7DcIb2$ z1vH)NHchhWhlfv#%cA^6fP5Dgy*m4f59qTU)QdrV+52FS;lKU_NLg(+ zzK@(9V+X!wV9HAdsgfG|GQg;_SJT9hcA!Q)5hwJ<(?fUOKj>$Ah~04teSQS>RcC(= z9b2(b++HkebU|VayS@lrs}6a~pkF)ZUd$_4+zI6G>RKd^gnoq15wj{R|hk2HLsb)j6|L zhZD<~Ryr+B>?WPC9;ZoDm+%qPBIJqe)Y-3-VvwDXyvs8tb$;T|P}Hadjr;o>T=D7X zd)1;&{j_>fUffme<@|pTx7`nwyp;VfsyQ4JT}Ea8m+aPLT!YHzT`Qo2y`vBUoEtL)6_G|mSKh-w9 z1#R&ColFuQ`n`yE4~E%*CwH?)U&Wm_^ahLjd3)E-dwVB#usWy_M|I1oZn1haW6d6M zf?@im=B)N#V@%zmBIwRiiqR#aIB}D$Xi-rx z{WY8c5;>4}62$20d$bt!v%XcDG{sJUa+JZ4#-rnL&>#GIQi%S|;OdvC=0(9{*kP+M zZ!71A+Wr@v>1{_R`q=10IlhyFyrac%^D%1unyu5^Dj${?m9c_&;oz#VkYr;IMRh#Br`0r1 zS(IgL`a?KtvTp0;?@*-j%BaJAy`TtkXQkfip1^*)cgsK=s2A|WsD z=>-#Ph*u|$_#yJI+P9(%9G{D6w-DqoIwNswR-`Ji3&r+zER;zOF_}xAc3Sh!ikzZx ztXF}4@lM0`!EKXY+@&7(V4TH|^KGo+_l$RN&oFTxJM`x|L}%V#fF>s?FRW`Vt7Li# zrFaRWeHZ$oSD|~D(r=?dKs8p*iC~Tc{en6ujNx}d zBSSS~&hUr&#>eYu>pUZ-Kw)&J{t*C93GXY#AH$A7Z22aY=J2qCKVMlKQ59r{gNfRt z4s$q|SJB^CqAz<*{MG>0wq}fkmK@eL{NTZyIv8^c@hLldwg3!8ch)6mBr4d~?|+9k z$nD?CqAbq1{?=KYuJbJF0Jm|~_SVzaqvnU+yb;z#WHs+u25=9w5Z!aQ_9`?Ns%za0 z+SO`Z>jPRvK#L!-ds2Fay7eVLy~wBG)}UdXJ^d44!q*v39Ht|uSOEC9^5+?}1#*t$ z_;MD=P@UFNdE&Pi4(J4NtPvrvv#014r%&3S7HRKwrJZuVrz?AbcV9I=;TU#mC$XDp_VN$t1w=}J z&~#yKVgqw(nZxfJKruLPq0Qn~4pP6=-Xq5ZN~~bzG19#6JjN+>z0bVAJPB(Y{7X0k zr?$b5lx(A?^g!Wcz9ed&#ZHv^fp=-zR69=?#``a-OQ+Kf~T`dFKj{XyE;dyx0z6ELu zm__0cwsJ&@cw?e+KcF5i>4pCi7lkV9N>qv-g@FM{t+MZalf>>%EfPmQ=~itgQK$@R z0aOtK!*C|L!HI4f4H&mFXf!8mG&4F!S&#k=Qn=e;8Y@s}zqn6!RJ=p(?shZ)CARrJ zC)jz{s49HS;z(O>uXIxvw{66gQ-zAScwh5de6hG%NegS$NT#ad_R~`FAbP z#l)XKsi2tz3kiA+_DmuE^Hqzmz2q5@4gHCZhWvx_%}Cr;7|TN%bnsEqS^QS| z?I)m>sSanp|8Ubd@5|L3fc?}C-Lv$HqethX8$f#|&~|=m3)&kJ6RL*PkA)VWW}*#d zhPH9xG{ua?$s05g&J0k`J+sCziR4Z6f0ss)#~BMNZs?ZRfz zQqHSK$3g4@;EZb-Z?G3^G}sF(TC?*`m{&r5Rgffgl=UycVuxRpvK^|jAJ;8T7QN=3 zzXd(aN4aWf=@zC85ba_u+VIR(n+BI2JCW-Qhg!`$M2NLc0d!wf?vMmq9s{Nrr=*fs zTFqpnDentg%~S|x^E`xB^J0lFlX$Dd*COm5XWhMtsk?hvayPd#=H1fb?i(d8E$(iR zI9sS@AH%z8ftYvexV%N)Ebrem`=usBbvNw+vso^BHwPqN!e-|8-9}lnX0r#K**j@W zt%~>&=YgHo5-CJ9UWJ9KpxUls>3xwRWGO?ddc56(L&Vw2psL4vL%gA*GJk@Xh1vHLT*i@TEAgs*JQkEi6mY24AmX0squf1h2nd!#u6vKO!Y^ zn^hPGp?G2*&NJ*L4HNPSfg;iMTjYsSe9^)FlJ0y_o_#OobKmL({uG@L;D3W$VazK0 zx-rt9$9oouwGU3gotUk8z$NkO2JuQncstZS3%w-{e`PWpBUqgiop+Ub7UkPT+(6>( z3-o8~2uI%uuAYLXswFZ3Io2{9ov)a1d1`iBMc#^I<;g)Sjx9`0vzFxJ_Fpnmm)HUT z_LIL5y46{$BHYj0U;GL50>+zN100Y^+!76_S!Ii-5Xe9kbf*%_kQcX$svX~BY8WPZ zArbGsPK{11MrpO3pDPVy2CW@jhTAGApQwf;7E0@1Rk^KEzQZj)M+Fme1>&|``NdDM zDGuv=(LaD7q2Q__Y}T;NnVks#3l4IAM+LM+#*HtiCj7{&wvAl#S1O}_XdI==f8vX~ z1Fiol?wM~!Gu&r%#$Lm$2a%Q7`v6Gu&;Lo%_|P<2_rQ;lgAL`7%?}~ctsRU{Z$g|R zy|eid#4g*+wEmz+9NQNp?CYhEK*GbsEZt#Z-u=M%bHsR~#&|YnT6w!iw$PYxpTZ0N z2U10N+kX___Mgue{tw_PG~V}@i?OelyoP=45V?}d8&s*m=J}-F#PdnxVESc{3ZLLj z^a2DemoZg#j}12`jB9B5md>3mkqcle@kO|z`RG>nY{nl>)nBLOp`^lPwA9?oQy)Hx)tpf;=I3;Z? zgbEI~i2Y+I@;cRHU!kp-=!eNd?7Wks6_$sp#B=M>!8y`_KRX;%vGU->Y==;Pfo=kc zO7uW>pi6fk>L|=NYi*^5yj#MW+Xy-JCr9T$?+BUGEWjC3~^)(qOi2&xDuK=5s;@xbi3;Z5CHX#wV%3T9%>0&98T(0@ zTEMHSwvWX{Hg9$`e?+RP!^xqw_Ea$$eAqiAiy$Vn!f{mHBD9Goj!<>}jr1AlKA*&; zQu@IgGz*fKB=)j+h=Yey*zu@byw;akns-pSZr8h`U;IqVo>OtHt|-gD)N+(^Vgt0U z{bOBOEAI_D0pNhvwk|NM*K9q#8)S1?O@bhP4SRHW3G2gQhr*{I9R z$v(G7U)-ravfBREt0G-aojhFypW#mxy12QwyDrc*?TtMybmLooPimsB*St)>^zd2T zQ)V(GFE@t#xV;R@9NOC{1zAv7>#w#yhUJ5NqchJ;&j!Xu2Sd;D{O+kP0)DT>yei$+ zp7#XdGe@&hk9?%A?ZsOpy3AfEJ9GR7x<9yeBrb1^BjfGW8lL3N&g(Uf&r6NY#5NHh ztMZWjqvwEEY*Uuzp#vYhi31o*?`CN`Q`JnqhoqUFiKNlN(33m^HyRKzV+Xru890tf zPF9tNyWYsh*@%`BGj^n32R}ZggOTj_v&hcG4x*#p?jeW}IgL!F6!Q-W8ME6e&A18 zjCm^$nG!KNqyQiIZ)YT0d$=Kxk^4vV{C1xS9im&PaI4wQdr4Nzj$4(lS1CzVJ3{!G z7pXj`2k$eI103X0UJDO(}lKXne_&1d%tmY`AMTiM%0OI)eBeGP?52%0t<&QNN|f zqrH&4oiT6iAyXnohZF!6sS%9{$;Y9Jg9?Dxi+(kV zj0uX27#&hT6d7?)9D`^-6j>rDGGB>AFjk#7K{WFO%>V&64o?KWkF0n0%Vc0y(?|s| zN`#pGQ_1#2F%*M<*}SSmnAx2=JClx}Q;j2If+HhFhZGP;MjRZA5bcK}O9V&eD~qA4 zHV27Pxz8oy&I}oOU-q^Dbq(&Ga;646sn0{C&%y1)#-4)YV1%Pnk;GWySENUiiQVgV zVMrJEX2+uowhE?~(I~7vTwHqy=M>bdYhm)rE65%KFmBrBI=jWjAGO;x-Gd_5R zgk6*U{;+;52&OSrKvEyt2?`Pu)x<2LLkfU`#Rydsl%WSv2L);;mQXuc%*Sa9LRSg? z2YS!MRuKiG@rWmRO(uN;nt+hHgZO$P;~l(4_#T1UYZjkvBM~_!Ss1pB{Q)d$VGMm z-nxJ-=Lxo4j-%F0Yzwn9u}(JX9;#xUB8;7SK2EH}of+=NRBfm6t2}-TdLD&3)@i1D zWEc!ZC>b$274MT;o1nt@kIp(hlQ^ zy_@NS2(wsm@DpqoU1f1}^A&i2DGA*#A3BEt6v!jQXHn~t9m-5Hu_U!0)<7|juxM$_qj_f8B zWzu_*S|eKUb+<-kr)j-}glcCfN`n!jgCXTD&4{BkUPZK@(qM@w4dxpi45Xumnc5}8BHS80Z>sWKLtFB5C+uZ4D? zn2?}_EXGASGosoV0tB=WEj`H#w_?UXn`$i-I}*2_)v1%UP;2%YXprn~{P?g|C~($6 z!GPV1GqDyFA)(b^XFmiO7X%nl?F{=6kUSzVcK`y@Pme%LmOm7kiLF4GgSDj}EXD;E zBdVQYA1uiutV7^O-(Y{CQzs90MRuOR+67Ql2N>secU~GA*<%x|%;wMhs^sMz;>y%FRONG~m6WNgWqDH{*mlNY zZ<`Xq)dhl$aWc_{X9{{JjuTyX?3G9G{rA&@C5Y@XFe{T@f++dy&Yq3^ATllx8BuA5 zeGny&5YHU|F>rc_1e3iJ5TWMJP2G}7FGdE&orC*OKe&twTt-xyVIN${Biw(5%T9Bd zBVDUgCli=pviS56;1s|ed@mrX+OW#cO$#e_2=N}*vO6$@BKnxo_?QP@B&mJOY)_yE zmpB{xkW4c!I+qb;G3>LjB##!>M^KO&Nm^LH*Qt|{B#7>>XVMGt?9Yn_`hjCyz%imM zhJD~9kKk4h0Jq}w;0R_u9c5uU$~KROIb?s2dur>s-=ptXNckb&@D!NCcBVatffKzq z37+a$7SmPs7saCzfEP(k3E&qGVC{s0Tcr?Zo`bT_VWwN{tc#_eou(P;UBF0~Q%DGd z8R`C&F4cWUyKW6S72cxVkZbG~-*SyE#xBC>8J>jCOLsjIzuyEGstd?CR+JpkujWv^ z=`J;~>oX^bQzARlY&IO92kuwxCcOQ5 zx@uSjUPW!-;(`5vm}mK*EbKd=#!-1K=9$*(2vs{nvz_@cA`nJpyiHKpOf`3TR!}TR z1DJjYVW^M{xT~<8at-$=lSYTo20kXK>U@~`Yr2Zv^J~^13=d8rJJ=10+jMasabZCt zx7vPjo6MGs^a_+=tr6R}C3K^qjg(jLEpBH?wS63m5>9fmw_rlRnnRu*Ib$3-9OUSQ z(7jS>re8u_Sqx2~2+TahqcXmxYhm0WCB9ozh~bRMMRBK~c*?+~s&oE&i>_k#;@gsc zYTy<}RAs-?b@IU5Ie_ZKeejHFntNps#WIMv?bX8`u*g=zy{8GOWG35xurbE;33Oz1 zF!UrZ#?BBCY&H<`=*M$X~texl~|fyH%FFq$~xzlb#BZ*Vx4;mR+(u< zZX($zB)lbu(Z&wrZ~#7KupOKyibOBw8BRx zP!dtuew~eZgDgcr*QGmQ?01V~gE z2XhHW3s-0nVBJl4}1Cb7quT1(zWub7FMJmnEhZe_+-*?l;*h01i8zn(ZSH=F5?b& zXCgX~yDSv$vPfABs}i$G?4RJP0??2+!a<%8o19~UVEDu#4vQQiV%z~!j_5!zEEF&- zQWis3h}ObEk)82<4yY8_xdAajNPOb(2B8ayaR<^QLFpN83#v?iq3=0Jei}1ZFgjjJYJ?f4VJhT)}d7F71G;TlexPZoL zb2Gk^g}OOf@h(CXOXfPy7b)eDBf4N5&*IvJV>IBL0JwQ z69mVn(IG_+IK~}t5kv=qW1)a!5r&4)1@|&8Xk}Lkq#|VJ=*k2k@d@>b(4{Nm4x~av z2SQ?@Kw=SG`Ur7ni0u2!6At?dke36)1i|o$g9d~y7{(niVMGUlVWEIw5l%P|I_zuS z#@}eEw%-OBwSfSZg-|Xuq*`Nw`i4)VLy8=I!?>ew0*E>w9ks?n(Kjr@Ap}BK-@N-{ zmt|!e$TC05a^RRCI6jRIDRRIu?tt?lIuINS1ssc1J3|-TML4<7{_J~%k4x?_4o=gxtpV+Oi$QdQ$4){Ze z4g}9a0nZ}r77@DiymFJvzLtL_QEimvz%fB^d>S26r@mjlBD z!SIP)B|;Yr;|`dY5FH4Hg#v~}*k>U;E&KR$S@?Cq{gMRl1i|xZbV!jyPsSba z&mlSxJPQRpi{Rl#=+bj34*9jheC7eNZx_mP;FusdK8+43a=9W7rgf8X=uo#J5fu>Oap=m8W4OM9SlikPE*Dm17ZuJ4q!}EnujbD z1A;|(l?kDCwG^t_0&xN-HiNf%d8)F1hqoxic-f4K0-MvF2`W`SjShx{O{^GqljYUP;81ewXF(ZSGVCgTn>??ZGTGg&CiWD!m*5uVIU-w*njc`jZ`5oX?t ziaBO7L1yx4bTD+8$+*MJwTKR6CJTj`EK(Ljmzj6`6LK78a=bWeKxvMdOpwZa8XXK> zW-{(jc@?4qsmwy5GK*9@Lwv>u!?Q2N@+g*QEAn#8WP)J$G&-cnVJ71am=;6_f?=V6 zVUcQQ=rVKIe}I`?_w_MzyfCwGQ#X&qmL&)GQeSk4y#hVt7|jG3&8N}9&}B5^4x<|o z9mr@F3Zq%1(hOa*|Lk?ham;?=gIy#_bKGTu+~pIyNQ5qT8F#pwM06l`St#6Pk+K+8 zCGI1!JAdR5dkOM{*whG25DcH#JF>{p2#h;m79%!Fj*OGVt&up`<%~b?#KH5e)D+D z`@GM2pU-*!Iq&oTd_EUrn)>A%d_&h|A=ZPdq& zI5HjX(~c>#S*ay>hs(@j6n2rJ6p;oBS&RZh4TO6QZUK#JAfjm?QhM^&#YSjLP`A?z z)s=r~ok|qsRDo-IRMBd3M4S~7XN9a!fgxw%p7To3IA;-!vq;=J1@fgS1PIPyz_RwR zoV2Kl6cHPRtT;vTRV3WASpphoBcibpsZbOQtLQ^4%G|)X{hw4%Qn58Xw2qepDvJ3d z#F~Rj>u77)MI_2rv0zJe?v>j7bJ=&LnXxR{zMRjdb=uJ-wYX4?qkim@JZw?BmOxgnsPF$pPs`9NOJ>Cd&AP2Gxb{DS(=w{@m# zS?1P3j0~@cR9DEQKasrZ!oBLXpmEhjG}T37u?!3iKbj?{YxXOOKj>FXph< zU%MSQc>h6k=7PDX1bEVij_E4=B0R1cdt`HU;YC@)KhbZHN`AkQZ!D zr^WEUwwd2K3)MVj#^Ij&Bxj)9&TwD~w{|;t$kCdEf93sUYl}(BGt)^#MI@p^F87J# zMHKEuOn}Bk6wyQ!iA6UsoCSR9tN84@w#pcT*)n4&B2Ef9*a3!|gnLc{pm9zj8Yhv` zJ*JS*=HS-w*ZZ;;ID;J6u!j1P_0!MDS`RTO(3|(`r`0&M-I zF~>mT9wVZ8j7S_r0cj(-w=U1(l1GV|T~)z~sE<>a+ifK5syds|M`3QapzI}egnM=RK;!C&XzGZ>XbB9} z2@0f?3E0(X0v^b}M5c(ZBI2u%i3>2~E8O!v3>xPvqVW}}&@D)hWya~LXiiW6H&nil zjX+dBkbfSk)tlObBJxs&T%8liw+G?gOAmp1hQ7&)XkIE3SLJ|Vd${>4w1+dkpelQY zWK&I?6cHzdTxbJ^oP>K$2SMYUL^Mt!*$aZ)Z3Fe}HuUyU%`L&xZ1m`m$p+#Ldz9Fk zUMRgcv2SNnvVA-i`Kux_w8GqOBl!vz?hV}o8aK3vW@wSv2>^x_{5PDq^q;#W?7ee4 zXPW<&Em4pr?3_mLg{>wEyC@+tks>mY!rX4b&_u$$iFSg>+9|cOj1NjHRq8d;{HJ~uJTQIBv;l2hQ0*%*zh*kq4v5NrI zq#`fGZ3}#i>#r8!-4!MkMMc=wR)$u-M;ab#pIR`gMajargHpYFBbm5k3v{Y)1~b*wk;1=OqVdvFo0MTo?n0#K@V3vsUye5_CuV>h{4UdStge<}lC1F0KUy<3ve6(KmP zyL>^yt8Qhu`IHLaf-um=03m-xbq!ISkff@)v?8iog}L2ELP4o6+}G`T(0JX7Xmu-6 zAukxVuIE`IxyjJGHp9f)8C@#!7n0r2$mAQEtkHGw5QDOlLlMcLFt=MU^fBRHj=MqQ za)@Yhh{R`YfuS6m^Q8Dzu7<$jG}J0FRQ*|m=BF^XTQF?p!hQ3*4b(IAtz1NFej*i$ zf?@MJTMVsrb=|kX7_Nb83}sJ?;7ST}y9Gm667F3o4H|bP5zUoE;+`GQj3ylvQ5T{x zw_7mOLAcjpHE3K15lsh?4&+w?qqeSy>Oo;{w_sQg!hJm~2aVT*h*l3GaU>3;9#lT< zS!u25qv{GzXY0|r_$8#76UsD-sFf+?MNW}?D--Tb(+nCnjfiF%k$6247>+xC_!qju zuXIt@{zROY5p97QPKs0iK0NMxaTjbg?kuE)$P$Xk5(;@w6Bt@TxVOXt(6}W;G)suY z`7zF}KbEKn779jY*1Jp@{ZDnuQsp3`60u_@m5g?g$pbT#2a z>S!lGGP7&$porW_AuDr{d`BzXyVH2kxI2kx?j#axaA4?8pI~|AI@;Zzlb!3KMc%83 z*eT?k85pt??%CCW#@UHz>_jT$1)I}r)|FrlWZ&G{{}=4s)gy8JsgEz#=6T5qE_g04tN{F5GiZg2uUvXxv3& zy$iI7iI8YwBIa(WW@4fU9how;2CusxzBFgbOR}!~p>^g=E?@8w+l6CdqQ~6CL>TYk zk=Z6DLgY+(PJbK>t|O4s43N{ztG23$T8l!Co<;JlMYwM*$3eYvqBIZ&5q6qzqGBgK$?zcN#|02n_k4}ZE zf3bYQ4cx=io^nx9*S`qk7BtZM7a?*9J*PibgX;+75{Ds~dDV|7BA-{t8eSyt^TNH) zKMxxBc@fR$MdG3`Fl=!bvOIGxk-ZO>umNgQx43Wo!V|azZc1*mum)>IG*~OdTYwTk z-YVP=*3W=?0sNF$L>sI{V&MyHO&^pSon+6<+~^=_rl;5_A~p&+$QH@75$@US1C6s0 z(b$N@K{ha)6TJ8jxX~9kNTJ6`?lU*)0dsD&6D(3v5ph?@iLx?z?!rCyU7&I9A{uv* zSgZnV-Y+DY_ltQn?^lG1P==P^pHgM>eo5BVeUNIr(@E_K*2)CZ4o<8I#=2y=m{5Uu-TZ1*H2jvo_zxOV&4F-|Sib!UK9EXeKWftyb zeiSq=vxp|MNGv6Rq09%j;u7oDu~%6A4cKOktv~8Xlgx{nmTIN*NZmv^UeQ#Ks2R3w4k3;;q zapS;!8+|;zTIRcwu|-?0|BAu1ghb}%HfzdDczqy0%Ey1Nrr^j25km$m|L^JqLzn7w*m80U9^Eh-P+? zI6VhCe?V&U2&NixjMm^Ex5=VNy^AQfV*pi;4G!}EG1maam&HXH(Snvb-R-zg#kDC9I>B=2{^ zy#X?yaRZ2G1`vs*I570PtG+;s{QYOe={Az1rl*KFDda#O7;+NsIjsSWa}v=wiR5b1 zze9fu3GL`90uv2IgEv2?nn;6k;tou7oHF&f+*?DLN?v5hD`#_%|G(zsbhe0G{_r!O z*J64#nM`O6h>B=3qL7nxpoCUWBHT|#R)Tt=X&Kr{6wxLlB5{%qY)NlZt^I_}J%-Au zJ^erUj7+o~Qp8OWaZ|{FIxyrW+;dw38s{dWaTCeyB^QO_gz}2qp4!%6y-ohvCU1sd z?yp9yh#Ij%j<11YD8+^QM!XQzGxUvEL~Fz%IfmUraZoWFpc?9DIrs zE*!y4I3*dE#E@4LPRkek_x~|BWuXqy%@l;O%K)^Qf)LFV^ql?}QP&Y@rZ5ds)W#K2 z%TvfVc|`JUT)1y}Q$W3f7)2NRM6{MC66duWV$-8CG?eKM$Z6KFzn5m6e z1jY(ElLjU_8f=4dNEw~4$q~ZQyAL0@CqT7okUJ|PcUH*$fk?iw3HR;r34I16hqzDzPQqAnJD z9^kdZ(H-w>ADzBiIbPjZrsOLblpL!Z+Bh(TNvX=^4=?N%PPbqj_{bQsaM}Fg9*t&? zl2RCF1@Ka`A>7O)k@vi84v@_4R-TH?M;(&Le8?gCyy12Ubdw3>^HuScEPFs7Iov1m z`y82L8Ds8Dkv=Tag+}rx%4bRyZ;IqMp^k8hQeT62sJ`m3wbhqezar{(6mp#d7gGl5LipU=naxDWG`h#%q4=K>NKZt1lAQC$|K>u}3 z`r=RX$s`gY9*T&ELiU+}ArIl6M*=j?Lqy{t60bP`ThilYv7fNfH|+nn>lMKM9s>5t z?kMA{i1;exmIW~6E8O!P0FCn%(fEqQE7!o5^i1)+v7GM>#_%}QNKr+^P$4%dfFVQS zp5ZajI71PQp-ADYh`cgPtU0{^#%}a)364EVx%=wS_PI|>+oR-&m@6XY3b|zg44Dh} z%mdIka}kZXNW7g6Y)P+{wx48t!paBoM@Wm&C#;9OBRho+h|Fa(ADiJ$GT_bfzpSE^TPdbwuNWBK7N=L(S|dTI8Oz-eU;ld zJGIDZx!=8qA5R45ycU?~nB$Pt+D7*(cu~ne=?nGmB*wPMXg8?b{wWPA%F&YED3w>U z?}#%vUiRS!@hRo{tA?1pZc&zNEDN8+@1Mrg>8(n;#H9^aF^Rs4_sXWD$;rkV>O@tn zh^km28*9L@iiP_seg-sN#Uff2i^SXWKvoNq;j#O?A0H$wVxx%IC}ejC7_t%W+3W+2 zvk}qQh{UQI7!EWSd=`af{4J{Q6x+*;Eqk5jLF3j!91oFQH=a324&EFA(*SlLzY{DH zO%aKvkX<)r@^fk7UbJ1HanVFH(L`d`4QO*|A<UR&zh)*kmzHF_ z*8$XA+VTZo=*lh##iu>8Ah&I@X#K&fUp;uqe`p|jwLu+K`N1>UWHMS}u zb_yBHfgwBLp4~&BadsjaJCPX4fz9bds`AG5W7wNew%PoRlN&|d$&E1PRY2?Ggs7(VoYk}~lG!^W-gRHCYTEoh_oQ&E>5Y(N0_)ur zk&7#2<4Yv(;=;X)cY?-UTtstmk+_=y3|rqVtf5>@KhZ8buZI@3C`H6hAv;vSkezVP zt^+jAPDEoTQlTi=k{(b^x3C*XcSubyFm7ugRewuu`fe~+)3<>|5-1`G6tZ!nOkQE( zUV;p0TmlhI0+G0%0kk$PBx=)Q9<^yjXw%Bj9Nh5Qa7`B_8E^Fi)ut_9@RXbTvV}vk zYtzEGLISilEkre~=d7mvmYCvQU#Kf<)55K$Z-HbrtwyGZTwEcSGeq)jTDW)d)u3?~ z7tvf?B({)%VVnL8%QRQh&!kn;E1^X#N)fSB$i)p{$WFLtw;VLiPDEoT5+DBtHmAo^ zp~2sDgf+d&xGjJ*#cFy9n5*f9V37ohNCJgim{2CKuy8LyGiY1_5lsS-*hT_cn-&ta zX)%x5v?8==WoQjP_J`q`&Py^bPyp4YEno1w?U~W06?JV|7`IM<)~1E1ruCfFv~Saj zcilHZHSOE9aI5JiNLJIDu_z)JSIAb5NZ!STdl#Px8h3FK&BaCH&3|Cnrnj(Eay9+R zt*Yti(4rQlh}bFQMFwEVPPk_`4K&V9L}Mos`!m3n^mNtqTE+_3rZaF$FHzdZEsc-9 z>6djAMSaD@jpx77V82jOITGIopd=Gc^EyQ|uT#i94WNXRm4y3w-DFTNoS)Z;X!AOe zic62ukcEYwf9+12qp>G4k<_S(DI$+k$kzcx@*XGLdt3u(+~Y(vj}wW385lA;lZB`= z{Kr2g!%u(~Ik+NXr;sfeV8~9mXEz=+&Q3&QClXgUfc)}|jGScG62li41!2Yi-Dj}w ztG9@CJ^7+KS44HLklhPlSm(lho!5cJ>s&;ubCLLL0MI&5ZSvI;F-xl26j8M)c(K<0e7l#ud?wD^hz^I*ncV_%M;?;1?yCmtShkbfnkF-dpcdLXyu2K##mg5phu%O z74B>IIB2|fMYP%#3ElTe_o5?caBy`vC zCERm93L57uqHz|9%NoGYgMZ4x#_4|XN34^$!0I|6OQf$N;;N8u3;;u}!adg`pmDAu z8ds5AceJ6m{xp3R=_OJ)&FK~e4^%Xm^hpf{eV|+f0VX=exlc@S2TXB32>>ij@=pa{ z-)I)HlbyT@qB^ahKiVB1W#(N4J-F!Tf&B9zkwS_{A%(1FfuTaey+VgT;|hsr3W>zc z3LsmV-=?;H#{i(7VYuJ@ByZRBKfhY-<{9!CYqeZO)N&PaX9OtLs$1c{$p1CEJ-r7t;s-R%UqdL{XbE3GpXLLj8FS zFCI`*t6wA_n4R({tvPt_-jeb8x_>>(#}g%4-P@+Rj!ILyyRjV83D#X5H>+`#X)4 z;FFkohEHNLR_v2bGL!sD5vi+?w?stpeTHzaZVzZ&T@g)PkvL@shJD7vp9uSm*Kg9t zH^sO$-K=VQnPJ3LQxg7OR$oJBEqQwlEuc^C{|04Hts}|Lt0b_ADoPPau8@5KU?{n8 zFZoW;xa1<5umbuTAR|39oW z!;CV+Y$qi$j3P3OLiQhkp<#r3!)ybM8%9Jkj7YqT0t^jvZ>t%GjRz7dL)TG6d=#?r z01WvE_k11#jq?%F_=v?sndDy8u>|Gksqw_{quL3fc2lhoF(N; z%5a8d@VDzmlgt$#D#}{S+~7=W5GyIq5l{IcVGzBAO{gN>6@V z3j(3d!Hi#pzFyBqSB+0mBG?crq{P>~myp#+@(e}PCKd8#3NWl-;l6^KLE{xHqE)a+ zT$BOY(0(~za;8R5P8Z|2%>++ODiL}rl?>18l9NU^9@P2&LLRfmBS{pIBnsJG5y|%s z!o4I5K;x2#Xp)G;mIyHH(k8Jkb2Ig|Z8RPehTpDIK6#B0d5uC|M*)UjBiwsU6KLFP zL^Q7vsn9JLE(zNgst-LHD$H%wnaZQ87NV+F$SoRRSk=OPRZjr z{`^5PV>IS#^o+)}jE>WB1&zkSx7m?fRQc2Nyv!^_W>&~;7hq^+;oi(sK;vc>(abCo zuZ2;gUB$`5Rj3dZs*smnfMKD+eW4RUEUgyInqs~VEMsZ)U?VKwc(C=BHUUgs zDsRGoZLze8U~agZ4ECU2sCNsv18g~N`Rf|F{7y-j- z5$>yH4bR4_MMSF>k=Q^6+BjR&xqza%CrAQod3JI*LkGG+_&na`un04Tj?8KN@DDLN zPZUymJ|c5(soqidS5lf~)6H%nobv;*j2*lRx30^O-GXE9xR4){dhYP=KcSw52DWv>|XB3kbx5|>PXVejm3U6taD#OkN)0UY=^uxI7}7JR)%o1*pkew-C4A&5Ocf z?wp7hg%!bs%Fq&|4~GL9zZW3M*u?@ed2{)KpSv9|SB9IssQ|hUpiSO{X!54#^v8V@ zFn$(QJ*TE{gP(Q^n{gFUlTnBliR4Ei;l9ZXfX17Qh}L98qN;)6DD)VsH8%>KxItDu zj2k%nz69oal|C@nhaCZPJyHPXRx(GyT+ek3%=Jyj!L$I>Z-#Ytt4vMa^T%Oq^FfU{ zipZrEa%lw^y0mcb(#JsKE-j+Dv`EFd15}2vP@e}L4!5e0k}6HiaEi!q3b~{rk~f@i zZ@2(7Za5Lma3U3of+3?dtmd5Ip1NL!I|9v`hZ=z*VyBSHD!`DPaL=v}G|o;$VTUvT5w=AE8V7&?0I0ymvKL`!j0tNxY7mEOM^mGb&r!36bR$vL6Qwg%s|Ee1>P@ zLW*cYio~uS(9IZY^8bu+)1Amh;UqT)w?7~D)42NElt!A>6z4 zK2XmbfwjUC(Og<2Hh6$xFFo=@p_eUR7;0-{j?@lU!{h8D65WsU9Ctf_CXiW+%N#0G z!U>UZ3c1~(Y+g9wUbtPLap6QX;Y4EB2BKO*Ssr zAiB;6Eno0B*V(kbHSyi~pa|?x0ZmmQ>LT@={zl^4;J7m1x2peZjTQeLbh?67@*ioFyX%E z+YIX2`<_ok>-j|Dd!oQ_YVw}y$QBPUEL6BJv;#C=sEAgmNbKeS@lQos(_7Tzp1e^` zTHSxKx>M^kSPb)pP-U0@2vO5f$V)~*@s*{8`=*lt^?Z?4otlW&bVLfvWgdN-qAFL2 z%2mkC6ku4ca9{2k(0I8bTDc;*a+xy=SD`{ws6t*M0)~YO_l4d98ZT5tD^w&du>k3T z#Q|F>tu?((wt9~4SWCU(O_rrA8J%{`!*pY<7cMR#H}4?<)i!xY2n@@*X^0}KLxsE} zq)fh*3ioxm5;R_iB3d1a#8wQ@_85h@nJM1~6ys=*Q4!W4%FrD2;-|Lw(B~H<8L#!y zY_!K{`GP5*R0j4K6?M~8VO)O!+B8*&x*0L6b@jkakff@)o+5HRgv*JYq9XwMj+P`zhph3Q$t0{}AqbziFUe3g7#Q zXuY3E{H`}J?ER)*tsajp{wX9z3oeVmMk4S}X!H~}nXM{Z~ zzm+C@&bh{jDadrH6z@6K^>?s()X4kniq(~78%f5jviD* ziYw%D2ryJ!xL3RyG_JUarnpF)zyfI&5*hyz8@e`;TGRW~wVhb1mQu&MnzYF1iio#D z*44m}w{Xup2^!}uqVX1q4|f2=YCiH_Rr5gf^UtZqn*2!ku>>Yp#8?qAR>-XoV8~dw zXS|O-D9%_!V=NMr;k$WGjiy_1o21orX0R+bs4an-+C?7bwZJJIXE|iXI(}N&(t{}+ zS3)X%&`~}dX1SFtMa$B^tjmznM3-e&m}MSWT@-;f zO%@?0i=|5zA*BUO-w90?AtsAukt~+wBA3NvQG&^0StN^PsVx2NUkD(EBnUIar+3Ez60I#9i;!WY$=shg0|NO zZ}WAdW}}FjjY2jyMDoo>xNkNCpz&rSqBR?l*sKGFo#!*Gmz;>_A|iVa(9FBUP7$$F z$le1mWGCFSI|dqOC!(>>cIFHw)J zh=xps>>>bFq~sUwyQe--U!?DzM6~WnB(?>B)|co(MWnbwwgrHp;=;Y+he6|ti)f0A z#I+?Lc9zI=B4R_&B2sg@`UyPb>+C4fmpCVADR#>v!uG%Keb)Z@G1tUe|I)|WYc#qI z%9PBjXV&E1rr$FZ81)B=s6SB1x*n*vQDr6Jn3uOvQBa$VO2DKxJK$~9{0_Kt35}Bn zVd@T;$EX1Q+}o&s@t}T7P;aB=pC@1RlBqAaC0Nbj8#wIMI${svhh7qW}aPQ*VK;tehqPe(8{A?orEqU>8@xZ^8-khE&|NbF6emZL%zBqb)Go9Rbu9nHR zQ)6?;#frJwZ1^Y-MhYt;g%xrI0~jhS+$;PLXk1|tO<|F^f&mN{$A3RX4T>LMjNbgp zy;*f{J6AHu6isz30$+t($pD6Yg?qjdJZiRdy4oTEAdm{$FwBiNY{e= z13Y83A%9dv`YL2I02uNW?)h#7jq?@J_=?1405IhH$mQZo(~vNBxR}ye92VE%qVOfM zetrwjL}Dl+F%+^X01U+t?#0*)8W%%E6GJ5KkN~YF)s-qDKU2seAE+WVVH58CtP|81 zi8Zt?7Sa4nBwkzr;%d&Y-AcpNOri90x!P)mvAC=KdJ(Snf$3_b-oe)MRODcaNK=Ju z697X^g?mjqK;xQ?PUt%nA*$m&E0Q*fcA3MmDXOyT8G?3cB>DWND&RC3R$)TLrsNyO=p6}H5Jh` z6^RQJz;Gz7oaEcfbP`Q{@liy46tXY}hJ1v3KGQ(sd_*)pBC#+BhJ3#CZr@&}kQmjR zMc|{5g*hxPnqVW-lg*h*rhF5~7fty*y(Rc0$9*>C8xPq{`IIr5@>xbr`98X;EMsxe5$+SP z3{>7|zBl&>-*F_Nt0gIh z{|MZhi3S6)+S7sjLtyem?wx|k_gUwCYG`PmjmRmAS1By@!R&lkEkhB>u8^g^GI`mB zd)bqqaoI&Q*+t^>4nXY;b_;RGF`V6tx!We>>|POi3uR~tw(pc3-6wpyB^if9$gHz_ z%NLx@6*=1!Rn+Ya3S)F8vn}3*XlGE*>5qdYutZJqXQt!;xlKvU78Fq*t&n$2fKpQG z3-^8WaZsY+?@5zYZDFX0*eK+M5|KO`;hxP=&^Q|r zjg3hBJO&U$>C%4C$>Pi{41RVwOo~#GJD#fZ-d9qExr1Z&*iT=VeIRcXC(`B^0p;kD zfQhDvL{rFHC%{lN;a;={C^jydh$fmy%qM}i)mzhflkwO}g49n>_z#X~yG3sezG00- zKi5763DxT-5i&hdS&GWi5^RpLAo<{iACRY#=9iwPJjSLuNSEbVG`Qhu^6-oCgXx)N ztmZ^{LRS1x`e1ra8LRW7Ea#;cls$TiOE+JVP^G6M{c>;KnmOHRgD>X>=J_tcgs*u@ z?|!_eX7hRk3LjZek$ZE-x=*`jxY*Ph{0G+xao}9fr@Hd8lFJFV=HNk38mQBKeO&4_pHR_=e^Dx z&e=bqt0;;3yHtSHnQ1u-U-cUD*}@OqJAU|)H>Y%5T9$Lhy7R)ERyg~0-ZNaur7NP$ zUU~oJahI<-z253a>a+x>Id%9*1~Tb`gx;yyj=}k&X_g{#V1;bQ07C~B?j5)fH15D6 zngff(b__5YtSv&-t3ES_Dvitv#rSrdbNPr2$lt z>Vky(Y1Sc7UnE_S_OwN`X_iR5;{>!Rk{(n79fiQ4cn!AE&B<Pbgb*zu1HW&7QE9I6h`U_CYf9!VDNmV7tJgxwj&+jY2jsl*!vhxVKFYXxug;nr%el$5nxL1|=jq zgA()T3`!B?SBB$W)9G86DvO>jh@pV zmnXn@5iYm(DC5n0ttZ?;QlzRPQdJ?lNWf54;a=74pm9}2G*v}vACa!#sUB02mSD8$ z!TX#w`4;#v?vWfZR74CFG7thohQd9=M?vEZMKp#Y@!KK5mf)dg*K-YwsQKJ)RgH6x zx>?0TkRy(Yh@(QTJOD$E!ac_aLE{`nG>#$_7Y*WW!g6~?gi{~gaAoLVkNN=!@*^9l z712CJAzK+D`Nk^TH`cA7o}X{5B3fe=i9QAxGMac*IJSOfA{tYdy79M#91&AR#8e?0 z7b1D4!adW?pmC-m8dH(D%>WFUew(F`8_-9vvb%Ms( ziD>LZ;x##7$nN+#II4~h*OM4^d=`O^LUt*DAs^wMPX}n6kBG)cByKSPLq400&v9Nc zU7MO+v$aQCL}0ovlBAcPfFo;vNceUxpR=36!zPcqIE&E5DP%VTD0yTN;l7K@fO>iS z^h`wS;zVNO0vMT65t&jU8yCP(Md4n>HK1`7MKl#fVvhnCdAuU>c!lgy09B;q7w$d& z7EoWL@7qN*j~9tO7a&fr^68_Lrb)3z!t_L}6#RaMT3`7R`nE>8+Mi#hL3G97H4v8&9Ba1>dLx7>#g?qEF1dW?rL^Hcc z>Ex4|u?cMsezraAYx(6haknEVA?#9061`%woUD;e6_HI9vUvgwZ7ST`bO~tOrXre6 zMdIQFkfA`oLKlCdu1485j3fX`GhCU$N`@l?4FNJS< zBAO3~#Jve1ZY(Z*tPh^SyWT5Ts4m+H`s#Gtxb{Lh=4LG69rHB#XMQ@*n@`9vipVeu z*{cDDh7s-!GYvFu7!l1dBBdwGExU!b2Jioxcgvdmm(&hmg6jV3-0JhEkj)%H>=hAv zg>2!73AyhYt zsBRRp$pZ}QM!2t=2GDrjh-h^q67O~cnHuHZw4Z34K+IH?qbVYvSI7+vk-X0f_dY)! z)HA?5b_0VH^LdfjOaX>I|NLd4s_!~qJ}(Wqj-hS&#rwSQ$Ia(WihQjemR*I&t_s<%0fu%J?(JF)8n>&6W>=B8 ziwMN$#ib=ZO+J6cw72{Gcdo?e$4`)pZw!4t-w9?_U};_Xl!}vFLL`?$u6qDOxrBSU zlAv+9L^QcXO3#tw=Y=*0^ZqsLkI&_8R4)M23^41Nh4lX;ODxV)KzV;cMX92MsG=0I zD+CNHO1Q76L7IEKqC~Wc5~+PudV#elwuf45hzK)k3!t-R{)th^8(Vm0OdOY8#);E=V_<0hO~k z_zkl)w@o!Ay+r9nrMCn>iqh-T%S}h6w+7z{(=~lPhA39gGN>Xls6w`eMDo3gaBt9~ zpmBqWXa*Ij&@C8x{>NE-xnAXa=g7hCMuKv;3iO2BN{9@rkgXqJXjtLiutz}Sh858a zD-suAWsqV~Tv$5RxAMV}yeKq*27+M6xqONw-vOD|izN!1KNjsDk9f@LNUOLPv-FYM zIO(d46Q3e@I!_ZoYK|(_s_QP;O-;{8}UIsAQK9a&ne`}C{Uaw zlW^~I`#?QsWYP>nMDsb3xHbf|{UIAadWc09R74h3$jV$KZ$aVSg1bQD78KDeC=yq_ zfT0DqvM6$j{r0TTmULCIHmVVOC(oD|(o+%XsgRpjB6&T9dp#cqjq53*=_wL#KmfzG zH8v9CW{Ck4Y@-Ro4C^RsiW^yIggw{}J+Ar`B6BEY)ej8KA>5l|J80Y-BAPiw;%8-m z!{hZfVy397O%b`0LRR@Ac~=tdUFlI!&%nEqh~`QnvC0RA<8{Nup}p^X=dcG2Fs5;z z3&{H3o{0?^=0ZxBEDBlw14CJads&vy=;N}8XtIdJ%pK@9aX!QyYKv$q_3G>gIc2oy zZ1!JQW@m<3TdLU1ye!>8Ln!8#lcPCUJT1Fj9K4UKG zGZu>`iQPm~b~;yo6HVz%F-YUf1K=zRC7&*!-A$rIwzj8;+MYs2R*`%^Al$dT3~0RV ziD+$4Bz7Wzq1%sVUFO{CZ^y~A#XYQuo{Q9kZXf02NP72vw0fssW_d4AI8rMlg(@7-mA|SVRSBPkLg`he8sM_a0Xp1lQ znSgh4u-?DEPF}F@E?)3Ae>ezsko@eygH5osLtuTD_B@zuz(fLUz|vjC(A^zhb(O}n3H7+*fvX>2Igd$4)(aE z%~U>!~mOc-y7)0 ziu0H>SS0+MfMWJJ0U`RFfG4}p2`FNp6R>RhoPZGSrvs&mzT+<3)UMVL7O`753HLH4$x|AQE470fy72o6ZZH?>E>`ai-!@4a~#O2{3r!W=nV` zYH^CF$`tZ>7hqUr!hMxBgT|{&M5{89_`C}+>_t8|%7z9m^3=Wc{!lHs4bQ37VLWt@KQW+#TGp6S+w$;iAKqyqSh z{oKv)gVE33EF>Ru0cT%NZw-cQE0x}Q0c7`cH_90G|CUidck{oEzW-OoVz)_RKX;?- z%;Egc-6)+e@RG(p8<3CY3TLNow~4I&eI_ZA*c?O=SwkTogb~R*h;Z*9(?R17BBD8n zNW5|c3>{=9YcSWp-_L1XVbRf+^iG;{u#SG8wM5xAT_wGJ|HsKhMbSAX(g&4qndK{g zG5i+|y){EF2oQ zadyqg;@GpjH z!#enTq3I*C?N82s`w-T4A-3I33Dgzy)d*3v%`Z9Sry`>e(?XVRa z0||X+*%dIQjKR-Wg%x_t*Tv~&)F+J^R_FkIYG?!L>uhkD1hZN^EV^UyBcbUfl5wob zSY39MzU6#mJi+_jUb1vr`F=x}&i#?HmYG(*9}nmAU-3%ct?Wc-bG#@V`!e;aB$|SL7;+Ki*f#r;p?NB2`KU6 zXtND|lz3P=c%$w#NxTl9DC0JiFdfQ;Sy)D%5(#r31s4__Z*js*v^=;)`aubEix+0t zqW^Oq!d&l!p%%UWy+*GV>X|prUZlfigf&j2qL^7f@x3zQM|g|bdXc3At?fyf{-4XJ zbBr1~U9ODsHwf&k`s67{V^4lmbjM=3p=RerhFZ&{xloBvDCAL{-BWGBreNn=|6w2c1op_B3~C+4m)LbDN$yGnSZjPPC~3^>9j z5!}P;3^fKB%dR@>lSVtVbYq2rIcwzg~m0ylc&+BV4v`4b$mXewET9Qn|B<5 zL)kMP)(h6&W3L@1b77$4lrWQb`XdaPp+OFk)fwb0_;Zhg(xNwqk2wQ9UY38sNg3$4 z)A7q?gv*UE;0X7L;2yrqP^;iImVNHg=5%5gcGyO@Dmx5!gp)X+@Bbp#0jXIHimn^D zvW&~qe-?W`RE!rPJziz4w6e;FieHVVta+|1#`{>KypRXq<|K!h?}avzzRo5idEQxk zM;U#N331F3{?Q2P9i~W-pV0Zoj}+S^$nKFSmEVSOt#{8q3WiWplw;RKdI8U}bw;Wt zaKUU98ce=lWpPEZCST8E#o~j|8Qhi477{|ro~pK|UZI!o%0Hw$y9N1}`#-^gH-dyp8fT z{%Ck?QYO*^a^P;!jmOih0h)tvZ;Be;(`0H-q}MB`Y6sPklCrzAaS(os3}`|Z^z_iU zdTU>u%CuW>NX@1Lg!3ppt~9buAsbCUzmSV|jDG|$h zu}mj-V*w4NQA=4!|LOFyo9mTTVnvs?ly8s2JI-+{K&@Gt(+?=)D9h;1@Cv`VX-{3^ zw_j^Y?AzXyc+bB#C60ZgDe=fRn-U-Sc2nZ~?=&S|eWEGxy`4>oiQjEXT)Dd`@qeFc zO0@MhC2rl93m-U*o^xH%*Ci`Cstcro`?1U;95z ziPijnpuZ_Gtpx4&O^MVWni5m^zyDZMV%zbi#H2Tx5ONf!v6zj%}VJ1igRWqJ~Cle;_7$1|Hm$$mDt7qPxxPR#jM2YD`zG4UNb8( z*fcBAK4(_q9rI=-8u|Yy|KFcKD=}ulti+xCzs!IBx><>T{be zn&@u$l*C)=!UTtSmtqt>N?v(#eYMOhO1bVA zZJ%h}qO}HR4AX9h#$nVSU6(wyrz`&uIBz~1+-7jQ!5u(07twt~ul;UBvHL+HtwHKt z#)->)L`R6!9CS9A4P5@RpRCBdGkp+2VtEgny;5FqzGy8L{^u}uIa*A;{vx*m-Fy5NUY0o!gq2}D3VkO%)^wM-}sY(i#sW$CAihit7E#54_b5jF!_SZ z88w-srU%O&I%GCW(FZK8<7i0N@T*&J9G+qy$+WnGW4yO(VJ^a0R;I;!(E|06j-I;Q zoHscZf8B!Kozuyu5K!BH2pD_Z3vuwZ$i!9?^tUG5vD&{Bt|$}p+rMSPeJRO)YdZin z3zc@?vaYM5<|%7E`R8QxB}hIIDP(lvyJYmdd>39ykXh8$(v!(m%qfX_Dbrms9b1VXSwt^x6qX<%Wvq2hQnzl;iXP55#tHvjPEhVx9J)F_+q}W z%*Q+rUO-TBaHus7%E!@~@?>XuR++IZCP?wD_}VfNBsad!80ovkciY%9g)87&=oYsP zd(^yoe>XbxyWgAwleP7U%vt)aR`37m2UWz!tcdDTo$p-IJCu5ZE7-O3+)n-YUm`O$ zy-T#IMoXp>zaa9Oc_d1i3oZJCT+10HWcX@%K_x|x!u@(z&%?xij-A1&lxDY5;RM>+n zIwLWSQ9}6q7vI$L5-xmxtb3lCnn+Fk^{Qdc!V`(Lymqxlg}FL%bDB?Appvu8l?XS< z?83pPu@Fq?*KI7?pX8?-N#Tk)u+b_pa}J-#BZh!VY)K!K@tn0+$rVlGs z+kZHISY7)4)kK!UWzU@bNM}{{qs8vkdcsYhy|jJ;eHQQ3L*rN<$c1s?-CKbCa8$Ws zz9puQi0LH9)G6Bu#}ePQQUUtoR=UUD)@tMyq0R5DhEIMgDO_0qCNkr=%c6Tm@aVOz-+ogu;1LY z7pBIqnh#5}_j#bnQ5K~*&CI|f5Bt;+^j2^ ztXzp{hI;9DdlpZVKaI#qthK z3RP3p2UJ6esXe7nye*fmtW4mZlNrctV$Zh(m)LGEJ4XYhbD^_w;BB)MvvEgd;(6AC z*qb{rsYP)7^TaRCer`7Wx_B>hK#eG6IwF6hUzzlp`a0=5M(wndG^%0HnvUv5&pR8L z{NtjaI`EWBTY)u&rN?v}PVLrh)JK|BgV!S* zEr?^_Ih^L&(QxK!O|xi--2eZK^@6NiM^GW92GnT|zH74z?U~yDYHV@avO-5g?bH{as{8)zM1Cl9W?|$q?g!r!mVD99fuA$68DUx%uCFef(bC$S zK1y0}HXD?jYUGEq)w%t3*KRnueE;l3$MeJ*Vht~bIX=35AS2VV4oCtRMoSE z9~S;x_~X=`*S~`0G7Ytm$IqL+pbJ#b-1DnaN=f;iwP&PPOQPS>FVV-|yy_;Yw_-2U zS|VV^f5XuU%w$w6yBel}r5_zVJ2CaeWnD-VT+FPia12{EzMegMS^6cF_YYPc)>UyE z_UY-pOWT6L4tbIqG^*$w+k&4DC;X8wx1C+inzGAq~XqXUey1+HP7i(kxl{-Jgrkf6vh4W zJvU_=3Z3R+&FQUjq($gy&2*=7hptrE+%N@~D&BL(li!tmnTFY~KX&t~sXbu^^V(ss z;phO5FJ5X6TuYJWz{`R)jCSU_`8Tp-mZi78Fgwvdlbmhs6~#FXx3yo@99)CEiY{zu zYHw-@E>kpk+-4vR>Dmd2#P=Bg5{nnNCziD*Sk=7DA~?wZUd1g@ale;*OB!lh+v}GO zjY}|Pnz0fC=MRz&R$r5U3hY)Y_JU+h{#)QOMzMN*v95S0u?=tCia<4=e*k>rIj3Wj z{UhE1ByxsD&Q#<{76XZ=5}?Ih4G)38{@AUL<$9`eeS=S`tH44Nq5RA!^au?w=zY0T zok5|ux4#nF8L)Z%vBJUJ%T=#Gih-*!Q}Ld3TE{zC=!|vYWy>vrNOav1QB9MGLXh&_xRj&H-wKYb#_^`8P5jdN^5qt&YO8 zXS4;U)1+49d)hKo#e0OWC|#XnF7&RVc8(Zz+ky{FvIax6%Ge)Kw-aLY8;2eR4|j-%ZmPwlNd^0ldr@!Q-^XV`)dB~C)h;U zuBG)A4zI|+Skw7sk{YiZ9CK~ru7!oQj6REl%P#VoWUp!q)=ZFiD;TmaE!>nUTsyd+ zasTa=h5gNomj#pAR#+Uo!8RI&77i~C&ahTp&!BfL5>>TVtjg`L$^G_Nnf@8{FAPxJ z`OJU{v!dc!mIc402dALL!H+4CgUtMk+4JMYKpnQ^ZN8-JIk{^VjJlR3XFXt(yGlLQeMGRg-_?&Xg0aRMlR)%A4n>*rLcZK@}=9-F1n~ zL@y{qJ!pn{erR^$j^%}uy?;n9TTC^mn(Hr>xNPBNMqt6x70ZHO=s{<+nkTC0tGvx9 zbXo8QjU;?@4H>E8JYV(ZmpzC6nw_rw%MuAGUo}omevmHI8>ps}75PwG zaO6sFq@*Uh@8kV#Y;xiMkE!Xz&j<}o2mX*NBfDp65AON&-k~d12Y7JGeqDCOioNtD z$-cWTASr2gZ>W~+8H^>VOs%D@@+JKD)SkWOt!?xODK)rp-XY)L7W^KM;=#z0;)(iAw{n<6LgrVcZ%*yup-p@GADM=G%^xDNw{Sqv z6sD`WX#M*VnF(#dc-m8QTYF`2Ii_i^Oiw?`&Ua;SKC#@s@edyy$!^8iEeXxxI+BgO z9hHUN!nAxJ+P4Kdf3jy^hf8}!Ix~`sT$RCZi1F+y>pwJeT3cQ7jkUFE%0JEzb*&v_ z36dSf%LHG=y$jj8TTjfZuCBfQM?!r8V$jpU}2Mce~ z6AUaHx@vK7K10|gYg3opo2+;r4W{Z>g|&mF4>m5UyZy4<+PXxcH*?C==T2nn3cZu| zG%p^yvo?74DoMthftjmv14EhjUNSdTb+|vxLF8#*V7}cg}YU+!HyJ~0Lob1XTUt866bF#f+ zaa-`#4CC9lm%aRs8w<;-Z#}UmRgq0inxE`f|4;cmk#uQk?5q}D!%HJ!ixt+gF;Q=i5KYPx%`EA*De z#%y}?s=ewyhQ@W!is_V6L*woSD^*VI!I#Ex*h~p4F#cZJsatWjrI*l>g4r`6Onn1; zaTeP6U)lP`{n;do=})#b2d^|H5+@F?IJ;*>Q|YG0{oJx^<`K4vy0U|r2JV2iwJ^qC zaJ7VEb~}`vUKp#2&b?WQ1>PK+o%qIxpAuiso85DGQoAh2W`Y#w9&2MTIo1~3XPVVA z_&ZzXemo>|Hu3yHzD$E%r?myYqYKc)e?PLy9AgNrm8=~>eztMuv0RdtttaT#Zyldl zQ8$QV4acc8d*1~@zpZkjzj-1xQS-oy}Ifeh@@YcRBXgpl_lWX7D z_^ROj%%;QUJ?U2!40Q7vZ>qa}9?S1BZNU}Dtq%SkwRU!__qx{pr%7*>Dhq#F#@Hln zmNB(K8@2cO6?0RQ4mTdS{e9{wF2Up4YM$b(X@H7YVa@+CIpVzf57PMaJ?kVV(j^#* z^Ud*IV1m~7m4yS7jA?c0e}d`nlQh|iy_!;Kw6Xu-n`X?~z1-Q!G*s(9c$T7&$Tzadqd6%g$wCG6T*xfXgzV#ClrLpAYl26bm z;a3#)Q^(psXt_pxCv*1H?R6Xagy%(7Q!m1_4a2@=4!)N!J}cUW_B(IKEFNL)^(+5L3@mlYCkL3hL^9H`t;5|78r$bdZa6PTCQh8 zt~Ytj>X+Ex`Q6m#o;)Vvp28npKVC>$KVC>4lh*Qs=Yxo z$E@qGQ4J(ABl;hKulWzNkm_Z$ug|nCF1*0xsP4pmmYWI9RUH z%Ur~);}S>DmI^P3+LHTqRc5Tq0QK?@W?$FR`NmZ@?>%uq1!Ydxqcxq}&PlkG?5pn4 zH4r|See1?mns42_x9iN@f#h|WZ+v&?+vTA+Q;R4KBQf{3if8sPqYplTG3vyoE=5>Rg#6V(sahS@xZp7QZ#c$ zaoTmoY2Oi!1seC?F=9q@GJCvOech^Jbd)9a~|;KA2*h`+*~&W>%b5607GthZW`o8XW~RDv}ezu#`! z)BB#-BX8$*;>xQlvX_nS$-L|84_9O_8hs>lPH#|q^{mS5J4rn4>JL|CYiY{4J;~8W zvdld0QOIh#WIXYoMai9MA{+jc7_-+NT{bEN)2Wj{^X zy(|Dqo4qI&;L*$2U0`>-mW3jd_h+m2H=evR)i_Xd-`y1N+h84yH}^_a?#rdWZo$ITrIylsjKXeaX*}#tz%}Q(`T&S>*v}%wk{9pL&rjZ** zZJJlHael?7d6g8qaeifPe^u^)75+?Ac=5X7yq2qi)lBX{r9}8jlxvGCZyq`3i?TVQ z@ccL6_aOgU`QOZcC;uJ%XZT;ke__u3N4n;G{s>_}7!V#MJW6;?%v;R7XRz2Y zW6;~bVc7m-|NQ!6gYa$cfXmQ{7qD^yl(NG5c+=I#B-O|A&su#b^OiLDM*es3ziD38 zh0kuBUv)hN-yq99QC6(v^7P?4dbKk52eba>vYcDW@*zFi`MP?wD)$G~Xw7{eqT!T1 zLD@-!sph|q|MC1c@IRUVY5dRUA3Kl7&f^K|3F`^#2mRp5CF=?hr3>{-`)>NTp8d-CLY> zGQ$2GVS^siLV{Dc#Vnkc75=nN%Z96l7FD-p-d$jdbA9se(S=iMo~W4Bb!ur83;Bzg zCuqDsgK>1`=*$SRW?xu;aiXwy)y+5Fw6}3>D*M{h7fZ)%FPOzt?wak%YZDds*3>*P zs-3gtU$Qu6k5SRW*oWw*HzjA~`n2;=HNW&+%@gmPpF4SJ;Z>FnCnsf-icftpETftk zOz@y9V9dkr;oEY3Ngf_sOn$kza^4|5Q2KH1&zBbVW_b-=M=Y-6U4#Fuh`Lanex*w7 z#YY>=x@M_mz5;4o1vG{g@c(W53$guK&i1Dc+y0&*X3qDVETxL~{JB(Byhp~a_T|5G z(`mDqRNS)h%=wo71 z{7UAbK63Nkjh<>V>fz;rn@HEXwL$gb+{XsAFS|Ci>Ad1y6|4(GgHua;RcRC1xKO3J z8Y3~Pv=N)momV=v{!f?kRCZ);QC($e#QHx?%8n$RBz817i`u-IAwVZi{||d_10Pj& zEqtFzCSj6Hm;r)D1sVCUVi2PNO&HLGd=QjCFpv-{U?ho2gangw_^<>9C)7-iQ|)tm z?`?0tMA~~>+o$!my-KUq#2_DPRm56ay^5_@PaIm~N0T6tdH!pknIxb-z0Z5^`+MKt z`+Emg_SyUF&$ahnd+oK?UZ*3d9%g#(yNib=-c=hj1E;ffjzhg1Q)rQ^yOI}f)6*BO zQ9+`75SbP#^X8R#jq{0UOjPfk3)dK~u62$QDT6(xY{|S&CX%OI<+4Yd=aCP0ssVEc zf+8w^&VWIW;MrhbHfQ>=0h)%yI)7}`degai2Dhs98$3_+mRrA(cS!I1uJxCB+paO; z>B=%(e&eIo3=TqLbwG1ckl>7@cz$Yl6WdPv&ww97-U50%EV?p~2%EhT}#!hZgBnLMS&T z;#B*q(c$qQsPD;6EGES>QYx*lQdIT2-b!l*55jfI)_z^@KuLPO?vV}fU7!as!@7&Q zkxs1R6acQ?%?T!g0CnUMIF(>rTmM6sL%+%_ahca;At~Q^X;rzTz3>u-2Pble_@pFq zgMdDM<|iUg87CsJ;Ijx5T)}#$7D`?ZmHA?ClS5tksiu&soPnHIbE0`_TeGuluWVdQ z=fgBE*DM9eK|LD=)9Wxi<NAex}q`~aBGd8zB=(Bu>BWz562CFxN5YxsKJbR|9$ zNKLv%SU0R$uP_m#lfOl7`&wL)NzB%k(tnRB} z@Dt?EDKxzH_LIxLkN873TR74AZ}HdK$rW$Lf2jDaa_bE7Om0KD%#={siSm`!p(`j7 zg#jvToUrRUmJksMlRL5e8yuzN} z95!D{vSkF+@6Ii|8A*2OLbm4Vi9KDV7j};C%D~Jl-YnOA5uhUVGdx7z1JBOz8${RM4+$y$3s?s6$o5<4e zo?3*o4Ni(f8bA35+9qkXdg~S0LyVP z(=MmGNy|g_&>#XcOba8n+OLqXPmWRbYplN`1)1!VLs}!fVF<2J-TbSLq{=~2rnQa} z37YJQAH4p8xI ztIRXOgTq3^M>HZ*KbK|y8dSKMyLNqm$3}(!nTVaqlN+VnPZXgvIOVgu}f~* zUvwtL5XH7jE{I$bzTt$5F!K6a`wx(S7|9Z&8V#vobFEwC55s1K%lx7^^s?fjP)#5^|eDir=3mLhYa_P>-?{8NibheM5*#9c}PP4 zD}=n_|AW3k#2j}z{dc;I{NQO{+Z0ho2$;_v`^(@fm*~`dS)$XpRBCorWLo&f6Y8~k z`3t+=@?O>aPSNc$?{s1CH?-V-cA86Fq2(^nPIK0xaL3hkm;Vo*j@=X@%4fG6b%xzX zL+eQ43X#EbXNU}zJN?UD#;skT4}^A>dCv57^4vBn(C$GLGlE}gm2$y|FI=?0C?zv8 zTSfAYqFG{9JMsTYT6XN+aEGdRihTGWlpHF`h6(JCx;%RZdB0aipWO9$O=_5K;WOty z&M579)00^0eoPBM$FzJ_&Xv(u?Dr~3Ebo+Zm-5C^=6i$R>y+NL^ELCmXG#n02&LY@ zb_RV)@K)y;6@nIK)M!MDB)ZuheMJRDH+x5?ifAvWQEyIGW8N7+^UOS~B4!;9FPm_3 zWwjKUHf?bRH@Py@bWu}E*t$j1ynXUkt+%q#I+-!147dYl zpenrZZi(DJ94Dd&eX zkNe*Ut#!3sz!Wk4Gs=c$oJo7ZNDKC6_}32eqV*kIW4rkW|8a>n`K)M3M2o!bKWVh*KlA#Z6N50Xi zW~_OG%e+e|?S{5HMIZPsS7^J-(;-AgYP#cn=I{HVyPTmLTp^TyZ*YcC3bt!k+qEp& z89c-MO>3WhrYF#zrgaixq{%r-zgg=RXuG@#>d1ae2ch1ce2wDmuA4_Qq|97oF827iiWNW?Q}+yWL}#k-k>XL9*mtoLgwV?{Z6l0!09_`3Q0##6f&NAo33x{ zmL=}ya7VUU;~;zau24Ro%5mKQdQLYvd*1ORZg;B%zd=f7CXk zuJrNNh2bUMVChga*m;s8nP|9k80S#_a6b+x>>PfNy9A}qLjn0ri3BFek{vGXXX|+g zk{e#(P8wnib3{h8P=PCagF95}3KckmwcjbyLXUq(CSO-cVb|d^JssVUp3dckMq1G{?NeE~>J9(vg;5L63-h6)6N?GaAQ|WovV?Oh#DY#;Ish`Q^ zHE+pN;>Xb1Vb53AQ>%eq)J|9MkobH5ho1Y2d17eT1n+ug#K3i^-lkKmr)8C zY?~Ha&l!B-We&CC-!ChE7PVr|Y?7>{j{6d7qmI&UlBtxyE9jfL8 z$Co^>*z;m?7G2F03N3TUG+gZtmpDR;5hGtc)VBmAqUKVF;|VVijIMRhCTHg8jlmcc4#Pq#3Kd+`%`Pe` zGE8IK6A#NCdTN8ucP?vf_U{?+bhriOR|s(#r8oJ)g#T8w0X-eR1;kl3XMCo#MzH$_aUitB(VKQjIK6#2|;lpo^M@KN^GLwZ%Ep^71 z0HMxk$fc_eiK~K`3JX=ionG)Oi=|>1o>1DtTL1Oh?(3!IMxNQLn90NvufjZAEvYw~ z)M-IaG@72vHX4Bwey9J?mc$VEv=G*nx%Bki5ovVrJ=dOB+kYk`!hGJ`;?(B^w`WF; zOVL&?@ZBtIj(f3S^kaq5_iWb~x6;BoQncEyDv2tQ=y%;GnjN;-g+sw#3F0cvXZ!`; zElK`@j8=C0{%7=SBY*jU$GFPu{}p3J+x>PF^6vkj)hD8~(0KlO&BOJ(-_-iEdP3u~ zo?6#4T5{(cw%HIeQ+N;P3`6(RSwwLb$0V!@@W}nj}pR zE|R}Kgc)Azdu%$D;AG`W_HnA0s?18^**qQJC5^e$75+-5kB3892ZL5-&k)L=?!>43 zr;uK@EigSWHvVUKT!>EEmdO>c$-krpj4akTLpB2Ioxww~9MpoP(zPD8xgg|$%e~>9 z=xPo5huA^2<(T9Ay*n>K?gKpQ~qe(35C+s!7ypoE?*o%XnJ^RU!*>4P0TC-4- zmdjw^;U)9go!MdL?dst`=SM_|hRdCy^5I`e$1pc194b(qqp%a~aUmu)UI{IdNfN$C z5brV# z;j_(BZ)deDyy^m%nsuQGs?@Aw@RXiMj?FI54DXgSqG=Z2s$ivrdu*)v>|U$Pyzn=K zF!(=UpJE=8eZ?hV=lPxI`+M8QIVQ|riNHHpLmXWg<2KvJQ79I6Tl(nSGI4+v*4l z&r1jg6;2Pft`0jVpsJ7>$kmL*{K!XW?=9{s&ge`q6a6o4&GPqe`9dsie_IARB{{jt z#<={z!emW96)KdfZUFa%u25oDSq25Mvvu1ACrprK^^5BinNsQ=m0XR1q;YuQ)n`{)FTR6_tUmoO z!TL;*MF#6#a?}7pa}VSbV_doQ6Jij=4tn>=Qh05f6U`aunzp3lRoM+2Cqt4I&v8yyU14Jt8XW#lJy>WZ!v*Gt6%HeMhr3vT0Y&686*9Q zpykr1m6qxg@p<-C^Ey~I?CLAGADn$l><35Rbvy*hh68=`?U01NITCXEa;(2%O~Lvr zK2BKB)ANKU+EJWxbaSH5i4VOz&lAtG=WH-%mf4%KZ6D$V16lT6f{u0CM;vA1nhNt5U^MrG?6f^xb z=qy2pieFPxr^kF{`JR_N9WUdn59U(vGd$(zN8UM9{G7xH^!n)D{P3^$b5`bmCe%LU z3BN!%y0PG2>pRMyv9+kQ-^|@%EbsXNUx>F^M*~_%^VFl`Y2i&NJ{+vj1MwerjI@!L@87Th5rJwJ4 zQaftVMoNk`v+v&on{}^A%X! zZF;@L&c9v564;*F5VBLwK)miio@9h8N1&OkXA>}y&rx(76~P1B2-K66S>SV z8my~eh1M&KbUM-z{`D`#oJjjnmG#@#p#yzF-GWx5r$dk&w34_`&I4%b5Jz7r6R_hG z(v%YRuPP2R@(8I86~B!Bf)-hr)pK;H?-zvFy|3ELuG8*z-31}mA;j-z_4M7RlJ(0; zG^x=P*4Q}(z&*rJ)7N$tzkIOx-E8Md)M&w;)>#~hl*VF68r@G55+d_ezg$EQ^3GSS zr_>`dst>s$Nw^_ysH&^oAZ*q(J$Kb(ysG&pf=GqVeokHC2r^q{y{Kp zejIU{{pQC~F3Ozmpy1!HwR1Laf9%f5`Zj1DOgm)o^cF+yQO1b~cgy-wV@{Sgx}Qtf z-?*u~3YMrlwEBP*oB<&<4sh3~H#=%{bH?rzz$n!(V9OuK%QmQ~kxrz1{0AM`yb87-=gx$%QRdp=f!=)mQaQv-rYo+9WFTZv zk6DqFf!+i?jZh!mLq{?qPh=TyWf>oF`e<-$s;Eq3q{z1ZgX~BVY=2GD3qW-Wf~P?zUGx*1SEFPN@S!wbUEm zEYNQJCl2y}p8fAQooX`d5m=JZq{zTHGVpdf;RTbqP=DCrC z@M~>vR9oAN)QiJ%Rnwi9ux@8oa^#o^WLQ6jwnDjs*G2VlD#ETmAuf}9)NZr)#>%Qa z-8(NO@f6v*c%DeEDk0UBa?6M%yIzv@-pJtjBh{A`-x<`LrUprgd0d=>7GSF)?&oE_ zyxm&_Yr?+GBd4Fy7lqhy2WAZ{hOOcgUL5^mZ%n%oP>KPvjcFXS9Vlah@X z3c|*eSxQg%m^fUv+5I+s6fh2;4Mk2Tx~{`3>bCM&Bv!R?Gq2-f?bzEsmylw~!Pf7P7)Th-Dt7yey{%n23`4>^drYd3 z*Y48SHzlp%ijT3(R(?q#Sm_}51$eS`lDQHRIfPN-D#kM_lsh_F2w8tbi=bGMe;JMZ zEgAQ>fQIVGBDp4%?abHZ^J#(H3q2jbVNYzAHH8vFi$vi$a$Z((eHt z+)-v*lvskEjst}MAm6j+ad8v$RJRYMmcF0hb35vP=vJ4CP_6mx#Zr6{N-m+~=$6dr z7ImRS6fWo+SZap(Mkb|xyIJWTc$!5Ux*|< z`E?DQx)sj#fj93CoVpv0iRXQxO84%a>M|0C`^(k+C^z?`>?=yFW9Il$%CVLF*7b^d zGIra7-QJWEx9Hs{O&@i7#qBdR)T{jSWe|FTPs`=AU(jzKcq+lTZQ!X=eQH;J5^99!Ma#TsxF&{IIAXS54i;r6rP`y0 z(PDU4su6QojTmEr-Gfa@)f^s79vu&%bm^A9>!??7XpQX6z>r)M<+ZjoidAbvWDu`WSmb`KWO&Fx$vqXb5c4-S49MX*o z)AcmeAfv@z^;rCjqdTQs>Q9wCcQ1k7M!aBGr_ISf$fuDBoyl44ZU}?ugMI#R4xTI$A!vh02dobd zKn41%Vb@$u7g<~W9bPOnUk2WxBpDArFk;Id{QYeg24vujj~*;ZO5H1Qf(KnmO2+U< zE`*~>KlwOaDYx<$!(2Ztm@S%FBw|sy4`F798=U(!7$|>#c*ZL7yx7d1=)0Wt&7@Y#uUS5K7Brv#-5`orle|kc;@8rOqYA!Ct5T z%#L5>ylOXg;qhpA-f^RB&#MPZoV$&rrhzq)RI|5K&8_aglJSdVj5rF7l=Bg%#)@&z ziqiVfb)x5y99Ztmk8txL(MaXd6>;)6P#8R&xZ|5qRq^QLaxxKNYw$pkS}-g83KNx8 zZEfaZlY?Y+-*RC%e&5nFP;`~kp>r$na!48tuI3t;y22qeEV4otc0^aQNJl5XCN(@B zJk8LuM`!FJVhX8=T^;e6;{vtW&QHRSO++=HH;RSee}uVMXrQG zZO8k;Q*UInm0ZZnh!KCL#Eoi7$hAfYzh{pSgWw{`k}LBf6>PeaRl=GJGK5F-?8zXkVOc+_ zMeo5ctBdZQ4(Su6P-MN|6Pp2^j&}*HcuZ7I5k^?sE>csERa1uWLEa(z@^t)~he~T2 z@{;h5>}Yk@xP`YEG$g?ZZY z(T=7oE6jfDJf2`#pz4HCtKK(*f9pwsdy zYZDm4>cSQr@(6EDh@^6Poa;Ae(e#S~MAKYsf?Qztl75ApT%-v`WCYvx3v7hQZA|L{ zg%CKHp}xC$tg^oQqLiEjJ1-@RafoUTB;jzmoO&l#Aq3x5)^=ivsSo^RQ0Q0qmEh3};$5jJF!cjAm>xxGecZ2@yf{Rpi7gYc{S} z(KyJxE5!#-KEafg`;;{mvBE?jyO0T0QFUp%ggh#KozO4)v80Gd``lkdw-@E5k{kjTkAqu9|=8(GdcxAbD z1z!K5>MdB63M|ZBWO%AjlDnAnpci%~iK|tSV`g%=DAy5_r}oD03-}k=yv3KP6-0ON z)9kHqX%4-y%Bnw~4COlg!jaqB=V2IN1;Km{z_LnssP;cytxu`47RWP1%?*Yaqp|hY zv?%`1Rn~(L5Hqn_sF}9s&w9#gs}w%AIx-o(fX^Xo@e?k^>*-Uu^?d=HoAvjg7SZLahF;BHUHhqOs@9T~J$#JDa;m0lauwhos% zI6_*Uxs;33%bh#DRpk}dgWNn59<$gT$$`%6=b63cv*)gI*Z>ojk`01SPnV1O71meT za*~dmyUJXhu1E$V_+r<3$#TU=mU->&^_;Yz!OgvaVwYOkA}+-P3q#3W5u2JY+HP?% z+TadzP$wEYjy2B&Rdee4i2r_)vDhbw6gT#pmhO;7_9O7lv2;09}_PRZG=7hc!&wggGYRk zM^&JRyhZ}Okp~BQ@{RW3k^IQlQ4}}Yf^VJ)zC9c~lCb;v05KzX?-!Byp2J3U+Tp%d zCS}mNO-CR(H)y4a95~s?A9%Xk@CSaA-&euwytPBd+!%k$>E4sraakA(K0hA(yq1rw zkB?SGNve;_d8zLLo&&!L^i9BR_#Q1++%Od3E}^f7p*Q|#+vVC0Mo%+r8GdN9JG90b z$_%Y>h1N_7mD*+{%*k^3mx-41XVm7q{lBf+xz?PjROU~c9{+Fj$pZ!Mpq`o!ljMJD z$H~a`=DZ;0<%XJkJ?|t~A2GDK9%81+;Z!{@z{D{ zEQ?GN&gjCJU6hG2yC@}pibuGm2{db1m|F!`4&;NObZ!hhNpB17aiA!XvEzIdCpzz8 z>uZmo=Pfv@4$gd7i(e*qT=Ex0U>?V12^%8pMu(3Fa}9^go{q^fq)#V-qFY^%uQh$5 zh!#A}_Gy5jW~MJg;DJRG#5W=JjA&Qx#qBw)-rmn@WKRAXe-n>Z`k!f^%r)4oqg;gb z5hQ0S2i-RqgGg59e~W-cjPq{c{KONKk-T}){bPc5OVHXyUmX)9qSeR^i%?Y>Nw`OX zu3Z!!6C~?xWags##smo+k4#vE9T2FlU1AqOQB@Io>lk|osYdm>h)bHjk`TIopR`vN z=oDH0Cci~zLNP=IIezI^?()Vi{Yq=ky7cSJ^BR9W`_3;x>dLPoI<`?BVXZGk}}@;rj=IcH>o8bk2`XHmx(k3<8Y zw@5+g!>#Vvt*J+y1(BP~!_d12sCo~b_sG$KqDn_#9XjQ8XSB|;;m+buxc;0HsQUy# zvS_1(%Tn3hah$voMq!u_MOoLu24MDvH7wysujkR?)EUKY?sBlSbKdVwJ1nRE9B3d) z8+`LAuU0Ymrg>c64%W`hNVK2cOg#2QUI`|Gi#9`hwF=Cwpwc>2*w zK{PX!hPgV|rr6C)(K^@4?SOC@jis51(o7d0{ek(8&X=lL|ESvQ1M5GO3+l<9M=*(z z&fiZwkDxhr!j;woKPBz8_dacl*!jFDJD)#JGu>+EGf;FChGAB@HJ`aIOu$Kcih7>C zt(iFHLVHZ2gE+CAZxiufnC$L`Z7{3$H#_#pg`VEM2lz{W3R3|w(81stJ+U11VtIX5 z2vX6USM#P`1_4H=D9Jj8(8ruFcSLfcUC9f2^@$4?K}#yF51t04Xj?fVR@nJ#q-aPl z?)o=jO{@JMh7@B4;YzUverp&P0w3hW$h=WX;l{ou3w~2Uu_kWh-(X>WEK6e zM8}?ym2ij$_^;~3PjaUjN7hDFC9Hq{SAs)RCA-kY>(?Dh5>}87*A)3iDdeo$Pp0-y zloMBNiz;LHEcVLfm(YBTaPtf|C9t3*-=L9!TLE`pCId+s-U&N9%dPMKLK+4Cid9Qj zlgqkPY8a1?95C$saydII_%>3>IZ|mz-I-axZl7G5v6*O0X0zy3R0c0Ww9n0hb_~f% ztr^W&@o|N&WhvvdF_1gmDC#PAUuFvK&N4ap_G)s$0^2h z9WNP)r4cc_=M2dvUWuC|@#MTog$qR=TY2oyM-vVeyQEz?uLg2& zF`W5mo=TPGaMWSU5*cr%p3c>%>EUt*)9%;jvz1*tVJF9 zeQTfws+Axt>gYRPyiq+d$mQVT45XuSn6Pr?-c?NNiq+;7&oOJz|9ur+gn?@0pfA_& z{}8+SNfJX^8@Vhx`2exZA^&N6$8EoZI%s_?GE6aa7YrS9Mk4wQ|F4GwZQi+=91@<|bIGxAs2SJqiOwWgwTerU-Ae-P@f~kl{7a6TZovx6)-Ksk-%6tbFV+v@wzzd*Dn% zv^@)*p*!5wVk!8!=PC=Y&R$cPolU#3X)aBd3p>o{!F<(7&z`#}f;~2pRs=4Pj8NgQ z+2%ICgzc25UK4h23GTShsp-X)tHXDAqpR+7u3bkCY2A9xwuQv1uzrYSKgg#~?(kMt zSg$LOi)8E?u>)Y$FmO%heW5}(X?3 z%4&MWWzIGWrj(lnnFyd`k!aywxxFVB#L^j6mj@U909`Yyhx2j;WsG;L-2ZMJ=shQ3J>3JKnG4IOy#}|3Anp&z>nnjTeRv z0eMhhdaOWO@oo3VQmUupeg1~`+(ISon{x;~)YUl>Op1lC`4AIJRxcuy>S{ZvsyzH_ zNn&01BwqkW7_)H8Z2L{Ql|_)8{>b~FSxU}Y}-Hl=dO}y z&XEO6qFbH1bLrB-qh=4rhHP6{Bk5&-|9@)#K0uKXmyCt8te`4nq zfB(O;e?P~2tfOMk%lOzl49lO`BaRp68LSC0to7s% ze?(FS$&wq0!}5nAQnmzR_64npavXm+cw!oRgV@HPs|b@w*g#_T3&Y5kYAr%gwIebn zqM_ri-+d~oZOvmfGt;{Hm<0A%dG=z$;(fJKbK@S16tIiIjJ2%dymcS# zJNoL;caI)VJ7Rn^_#yf_wKFq`QH0^Nw-b-Hj`tI9tE+XKpSW8b%X3~rC@g!tSaHu) zNYq$yDnnJAYzyBvpF&--TootA$}xvC({)a9hh_8lRsMKmWw|M9JY~7IxU#7GMOZY) zb>X@P|A0!-A2cc4mPIMed+X63K!Q~dcXKC6PY*72yABm(iu^1x0gp3WkiiRrWUb?l zm8cVk9KyO_03wHLkH3^dEYksUuMOWX>>+x*Q;O#0s7(@s)_x^G=fa zhHZcX6geyH?PgUQTl&vBX$vmADr#I4TWm!mCWA{JSa9%`>aJ2_Qbp585m!aiUn7YX zO#{)%t~Z%e<3dxivHAUZ5@*HeRoV(5Rc))s=zc65F{nCDX>vI9YlFE_)CXg{#k8F6 zti!r@sqR{8Oe&X>%cbP<(UODi?C9sqy2nhTwkhY#p#kQQBkb(K*s9k1S!xk7yK=ho zk{)M%aA(~<%($0+udar7T@8cRb)n~xXFZR+Kk#LHFLiO(&5p$#uj&)g{l*MK+VgqX z81kYZ6G_|C9Z3{lg839NjHhE_WVlGVm7iD;L6^*1iA~-zOdlI=_BOeJkNtX%?EBK# zzZCFVzalcVplbr}*nEu%J}>faAWzdB>YZ^|GE5~yvxn;i=s{kJ9a}lRT{ojgiLQf- zq(!4m`o^om8PO!n38P9;&p=(^dE~|TF7v{!mDqK9NuTO@w41$?2riz=D|YJ>A}-IP zFQSaDy9*)*b2#?FaMM~OJ1?SukoA<5IQU|`$dk81rvi0RIdf#wbcpkNzMcUq>D`%) zG;3!{kWbcJdayW(_5!@|N6K(U7U~F^@v&IWKq#e04r)Hy^w#Lfsjb=4C+uQVQMmYl zb(L^oO&_CkX*^&bk;C8n2lY$BB~b?Z*}|2;j-zZ2l9!kI2Mvz)A3+VPK2-b?tt__^ z-zAUYm#ahBCVz8Y^$&(io#9p4&YjnC(r{W%8r~T>PhU9HwZ!=Yui--VVq7R8lFYT0 zU~06m097mh>pPw&iySN|VB_iva>;o~PMw2i65E~T>ln*U{G$I@d%7fXMHd$YyPc6g zAyIb;TU-2ANFDh?t{*6u<6*nK=-D+ns_>(6$F40yW?;X4ZWc9O#z_4$53m~?{fwo7cvGwBXd;Wb&QJbSuH zUDEe^{_Yj&53ArrtFm86q%vXR>G(%p<-CeKXNEb{$Zsp z%dNkEP&F+>n&#QF8kS$|k6mLGewY2irCPN;Ufop2KDLy;rAzvr!o`5` za;~It)(_dtGj2tcCT*5gc?R(kR6H-rIp`8%BGrzS*ncqD*Y{U8E8t3`G)#A~ie_f( z*GUD-ReckC$zZ}y(QrFW&WVE{T_OA;f*+z`rWpGyx2_y5Ir0Vqk@4i|M~hVnlCZU6 zOWf}G4)vQQC`T_>uHD#F1qCU&n8Ate{0D@iu=UvFFM`tO`~xh4mXRhK9gzW#V>1=q z1=rGj2H6TnJEl6Vg*ceWT%2BRP8EivieFQ-9J9I6W5_z*)2~}?UAk8t(aHx&^ed~X zR+lq`uTe2T)WynZwbjLDo|}0hE#x%U*l*wL!?p}F;jawX;7L9;lAxtR8f%q9u~5dA`2MrQdu;g%S9ZMNH@8Vl_X%ByBd|WYA(t>>vq@*MxDiJ;W0W!fx5I( z6xE!@HY|DR1I6wHy_s`kBqh}>kxU!}?o#_v`dl|f3=%OckY>Lx)uC&5rxSoi%- zMPz`V$2I8-W%Tz~SOpA6rShRq6k%9}l`@i_5b0mNLEU6%ULdv*7-q$8m!5`>5}JNK zTStjmrgSf`4z&%D!Dm{B%4BWDI@I1<8J;Xzy~cHdNZB7IaOz%2IJikYr_`Zbd;-B1fI1!1OW14riJh3s2VubDY)-TFON-8#$U zR@7^J1HzII<%0D{nkYzPMoJ{ETr!9vYn_crDO<~gjm$`{WC_AE%6Y@ck=BYhGF%P)P?EftDVW!u!L?tdFQ!A6DIA2NMcs>*OyRYj8R%2Za^yI*OQtTaMmJRNsJ0L_DaV*QI9rF;pEjeTYK zhA4*=+^j)U{QadU0DOpNosq=Ok&XIOvQG$}l-UP1tWJ7XWaMfQL}S3yAvb`Tj~{wE zD&^^={SP4W%*)nWgWcJS7s=v3R2{K#KMv;6Q! z;dwVP{d(SZJ{11W!_dtC2Fpf?-LflIw%!;OLY;=?02%P_U@mk{yJgqdiPI|=c=ZB*dx_{^jfUa3NQPl6$%ryVZ98W z-6u0xbh%2ycPVV{X>=&a*SB)I72WCVNID6pm(Qn*KI$s|;NTwd`M8jAEq7g4f5>HC z?!@?ewob+F)8i^?!G0e5gouKyyRpWJhj{gTa|*+rKV zM7EW3X5WRrl#0WhH2ZDk$ZJfHE1vGBq*rm!*gH2)>^xk>yN7te1Gg~S!%}3uIRPDe z{XDztyyuaH9r;t>0ePwA7ZiYiCnHN^SP2dlv|bP# zx_N6xJg>un9$#mt$_c%jn$}6^1#BH3&+c%b&lfon&y1{|K%S0ec~K!WCN_Oy&7m~7 zb_tNNVjqCtOVJ#FFK&2|Wg|LyjnE8E_qg0Je+r|f;Q+x^QLJC?lbCvW!!PWBh6lvm zcRzvASN44kXRka%l+KI3D2Ax?@p~ndfTRiu;j}I@4y??Q8-tl6s>l#Jg1?kwyb)`_ zw)`KlKi`Ww68+#O1%tm|(N*mJhY|NP#$X*zP?gVQ9kOF99tZtj zr#wvX82MHEg=;8BH;!7=(p+kYX)t*onNhW0IEUEF2KCa@A*B#9u)9p5$af4GyQ zMif3}jPUgb)`*O}wNqpjl(o+Kx(W^zPuVMpWEH$9MxEok2UZu!z3*S>2)R=8ZQQ)I zW0pX8ffTaz?D;xHve>ZMNLbUy7LMh1%1-Wf^=*`-gS!gC#RuR&AooIKS$jHG%8L(o z&Iz_3NNAlNE`BC=?KAp?9JVhw2CG}R$*E-3YrN?K^7tTtCpuSz0FF~Inw;6|%0Wyw2hQ&XeG=ORWqMo89`wIg2@iPmFW0 zx0BmYtD6?dI@yM$Oj#!ftJ#mhFc>b~ugr|HV_)a+e681?B=$xPz7YFOI;wh~X!c@g zcNOZH`UQE5ly2_?tLJ^$@axybNj?nE9^_F<={Dy+UQTq0HZCs?2Se5?RdXS+)JT*51@_YtX>2dlG+UDb)jLjj+bKltiJ zuMQrYah%~c`Bu84(t7eMR0bPMCxoKMw4;@-^A&P6vP$#>GOX(mn!snXY2o89UCvw- zdM;*BxzOH06Z|{#U{;c#r)Nl+Chr~NkMt{(Ag@gO3k8c-G>0hd>UO$wM;6l zRV(l7%qWpKvqQg$K5KmEXlY=eb*U;06Z{lFfM1Q#{f$$w8 z;hqlJL5ebtGV!CtzJwnFXq_-Xt1|J?I~+D*1=np|h-v5|dqEBC1Mu zNu2+Px#U!wMmNuo+9*EnP|f|W%0)CxNosTieoSggM~5~3nXZ^tnCu~Ama+AVE3E>=gp8|K z;^Q@qHhvr7N;L*6#1i(H!-BS(&k>%7SM@l%mi0L0%F%UQJx^!>O`8R1c{*BrNr5+a zMbdZ6_l)vcQzrzD1Z02GnOZ+f>rOnlu6I;~8;Ri~Ud1s>n>qrD&T>N3;-^6)=iMAw zx4Xhg4YF+T)p*1IaMX>e_k{k^ zh22x4C|pP8?H8t#@6t*7FG%`nOStFy0sZ(KFA!K9a9U6Cgqz!||A9M($D<=>=+HL% z{5|c6r{nJ>KBNRI5u;Tre6--_H$URze75V-)VI3E>6cK>)RHB+!>!4=uWe08csqB9 zr{g>w%spVFEH!?YbA$%m_)Ew_w6$pP_YpP%QopX`wC=8H`i!(!^=TzbR#L&NkqTa7 zR}g!@lEZIvj<6R_v2#cm{C(`uUkGtraS~p}R-G*H-20Fu9=h3c-(Gp>_Vs;3@?Gmv zBBmyX|BZF+v+~r*;m$NB%(36fAc>^LK4h?F#zAO==uXysmhPlSbSIk zeM@Q@H*VbSi>DPgKQkY(tCO3ZPHpoPc@}$DuGn+3=Hs6o?j+o+y?9AJZ@nr!{v3cx z+Rr|rmkxQBrv!)Qw4W0kJbUH&Z~YuZ7z@I2kA+11W5J1kEQpMEEa3grFP?uq-*|rU zeB$Xvflokej0gyWBOo+gATmM&Kkc1^5)N;3;4_@E~v- z@JE0Wwf_O!1iS=X4g3sf1wH^$fiB<%;2Gd@;31$1co(=3_$T0I;19q8;8(z1z{fx` z@MWL`I0#${{4-DwybYWO`~y%4yaHSUJOXS127vLvSAgZf^T1r-CqOgs7vN&xJHR^N zb>KSS31BC127r2KyMY3r2e<^-3)BE_0uz9*0xN-|z*WG%0(S!M11UfVSPC2gW&=M2 z8i79G0^l1!HSl{N5BMdp9XJIf0egUA;AvnM@O_{T_zz$*@b|!K;J3hh;NJiP_$!bO zgn=^PH^3FZ{{%Jxe+H%k-v-tK{|+nyehst(p8%6+!6ZkD_IJ2{hg*SLfqM-17;X-3 z4(`u!e~#OR+lKog?uWQ(xM{d1u8Dgi?v1$5;y#O;g`0)@BitY1-hq1uZUi@idlBwM zxZlM6Chiw;zli%P?yI8>?dk^kCxJz)C;2y#~g!={D zFW~+Q?!VyPj(a=qJGk%Qo{xJz?my!GBW@LL74GkFe}{W5?zOm&;y#MI6?ZG{AnqWp z2iJppAMSm)D{xofzJU7z?v=P#;{Fu(r?@S+Ex7ODzK1&vcN*?@alebZ9(O(N8@O-a zUXOb{?vuDr;_kxTg&W0<;tFNR2YkS-fEOqSvVqNj3n&FH0~&x#U=5H9Yy+G?5ik>| z1u}qDz&t<)63HP5AR^Uzff>L)U<2?cKq#$Ojp8KoP9nb~@<@U%B|&?Vpf5?#kR<3t z60{(R`JTj_PGa6BF*n8dKoWB-iPj`BSCZ7f$^13`!l{=fM1{1<;}HJCVQQU<@t{LYL0&X4^v&-q<& z&hNs%@w@16{HFXDe^dX9Kh^(9$@F_lN@{9ansldhnRJVw)*Jgxi2WwUev@K9!Q0rM z;Bf3Oj?cIo$7|d@2fd&2o`ddBdH)9bFZ^5RXW}UyDb61V-y%FqoL7;VDZGjBBI5y6 zyO@_6b5vtqYS0S}nxH`^G-v@lAW#n63Ty@fzym-xZ~}<`gl`&Krj#dTNjXx6G;PDC+PQVx>a-0ln>N)n*UrV&uH2w$g)7P`%8LsncTM(` zPjnP$F9GYnnZ{z181~dv{Bxr&7 zN~Fu+MhrNzjoNHUqFvT(Y~0A>(v2JIZm-$syKOtXdt2R|MqTrUI^GvGw$^RXTUxjK znp<>V-KNd@cCEx{-k>+OG^?P-O`A8?ZK`Y5>uM#xQHjS9gcxL0#K6*HDLzb@jTB_SDvGX{6Os-?61HZLZn8xwU0;YolyzmR`BS zx1pt3Z*AG=YuQ}aS|g|!tph>Ls@%5E3iHv1Pt}Ju8iGNo(^4?!tBoUF>ZqR;Aayo2 zG{mc_E!`wFt7}zlC%vkB-L}Ryy=^RxRl8O<-_hK%brgw8?|+98(JGTGo-ZQZFL)b^)0QNYA7exu?4NS)0DPY@7rVL>^A#aT1RRveY)Au zuWT`NoOmWn8H}y1#%6}3uRcCjH`Hw0Nd4n^#i};qS9K%jF{sy8#Cul_bUd3Hbs6U5 z5w9+L8E93(s#3v?A_U?JaS->m8r7$BAsEU}wuMn3ju5Xe=_ zR#a5jA>!34mM&j1#;X;rC@WaHd^F^yYqGD-O;5c-@XthJ$TGYd^+pEyU3I>Ox|+=@ z8%^R}EAiA69@C+Md?w`9#xV)ia2`!}&F7|T(`)}X>E=ti%|>gTZ%bpVZa`Vi>IqeV z)N9`7=D)tBnQ^RN$(+OS>C(iJdR>(#=|Y}KC6?4P=3Fxb*81cLmiYqo07XU2_Fk~Yu+seWS%#WmmV+uYLF ztgB%_2*lRLQCZ`L)|R#wXkcYyn{-uSR+jIk*Z^JDcpI~PyNusd24y_BSmx^`sj205 zqhwjs=FXj~EsVEP5q!g@IM+#P`zPz-Y_4tDs+B=oYHqJv+_H_Egl%=LIaklERg*lH@A%^d+C)I| zZO7dWG<+nBzWqCZ9Ls$InH+Mq`0pfPxo*(f7znr zzg@Pt+p%P0%WX9q3pTW>Lu57H^x}si| zL+uqu*;)SiS|RgVualR&+04u+(AZ^;h8AcW9E`SAtZ@=)Im`<&>f&MLHF^X7KRL>b zjYW-HxM`bEQKuIgt*uPb5srx%=ShkZI4nsK%OyjFk?ShxKk|?g2J`Z|ZMqc1c#XfU zfQD=LtGB9k+Sk-`Nn>kUEUI>6@lDH%m&Hf@j}x}G!J;(l^#$4kj%Cd6rJI-?)M9l- z@lEkq6!6LC8T!AM1s9V1eoxdtoTlTQ}N+q*Y5#5H7LM zexaBM)GWrtEo-S|WJOetb|gFG89PKV{>vJhX(vV*>hu^+H0@IH5!Kij8;@Xa=4hBS zB{mLHB(!*xxL3kU$r=YO8#IWUV{xC2 zQ0fp)K<0%Ssy|wW+L$7P2?f;Y6*q|n6ZSl4Zb(@7*CR>$apK6I3=*VeH zHX3aWQsQExzMdhbA={NkjX_Zb88_cfwm<)zH&xn8303SO3L9!#SG6!Z^~S|)XtZRh z+ovuuPky-g@0+EV4QfBXNORyCmqWQp;tB*h|xXPFYndZESC;K zu1kIeh2@%dmE^OcxJ;g}lV_<)L5%I!o>G(|w#bv`C0b$2rp-02bt9!rKRbkSZWDZr z!RF}5t+C(K#t83cEsp;$4EvK_p#3xRY};=^K0jvI0 zpt=4CJ#=W=#egRk{_;EAg(h5n*hCo#7yn1G@JT$&nTp!CG{b)(P}s~wXtkM6-;ArS z&Y3rVfp1A`%T^|bkHt$?!OLdV&i2)_%dV@PE87KadBxI-^=vRomM&Spnr%kKs)A+9 z)?=lje8o+xct2Buik99aasO6XjlxX()RwUMc5?q)@nLY!t`ccxRuxn(t)M_31i*){ zsG?l?*cCL}k^tJ+W^867316-nF%nDa8&ChAsIR?`f-I}$+$Y@kZAz@brf60SKh15m znp#>GutiX(luOwzT^2{8?9JH@ua~r!&8GgbxT9e{*+jB|*vifTp+WQQdc&ewwF>vK zxJW$eHi9>U9jtKZx7FQFt}1@^6?t=fSIqG(n4@;E_Lf?;d2CwW^jU4weKi|pYQ(0!X)Y8&g3 zAZ@Is+*TL?DY< zZPYiGw-!elRT)WVH6f?YbqmG}tawQ=nlpyp zOlQhYpQ8p()SQhKCo>ep#bb_?s|cG-8>DV@LalagyjZPa-b8p@>$}2t zS6wUY;q5dE8pL{ag)CXnq!Bz;#Jbv+zzVTI7FfKZMAge@cbS$t3zA#Y%ILX$R@;J9 zXSRR0Eru;clP+*D$Mq1`HUZ1FiFJG2_m@2k~Jm^ex7357R|B?|h=xQOTZwbpC&jZa+XP1C8qbg>eOBD!HN`$;UoxT3Lf&V^EgD%sTj1F@fol>$ z>T5@vciGN3epw$tx{R_`LrvXTZF78M+KhB4)+s)_incUQ7Qa~i7f80}W+3n7l!8~W zc{qz*fu>2`gtc-?fuOvW#_QP%L4`RA zsIPCU)2ULbwyb4?y=+P4gk%b1e>3#RmBOAkm2v%Tq?)=jACv-dK(pnEeyO! z)HE&DENyN}GkaK8Jn0Zb81jy=)ri#!Zi79G`Q>eiVma;i;;%3^s4aOsFU2L@Mny-` zH0tqsmc$q0HXYS3n?0~+{G9kAvsrfdb;4COx7jO3T%JBUhjgR0xvo~wz&_JA63&5w zY_6qa!+T@=NJ*V(ERbbD){e%y zw$U}3mM{ik=@DoneJ!uK9T9b7o9y*#=WuX!hg4|{lh8&M>LnB@UR9OH=a(59@#hr! zdGYJEFoYTqY%>95!yU($6r$4jE>o0jy**o?mt(ynE4$4(seXfBVp=c)4PgRfw3<0B zD=ue0W%cZcPvmctITUbkG*{EOG336Ex+jP&+=k zc!@9NsrS=hSU%{XgefQc7?8d^QHf_TG7fu?T5CARma2Yo(rm|I@z! z>IZ}d0=C0n9<}c7Zd`f6xR;^N_*V{pWh$K0Pp*}=V1bDCuVQulNx4a@Z=!N%{m$}d z2fPW1V_vUZJ@M)VqyB7%WBP*+#r)H!&)1v@3m&rl(=~1S^cjT-583|d)2I6gn2uN8 zC-|mMzuc!0+4f&O{h_NLd@x&LKQsd!(&-O9D388G{ya!d;>>vH@_my1)tZDpM0PVC zdf@Veho;-v__PGl_)_=9{3MgAEqE}&jxSj}L`Dz#C|~9K(B+cP)#6tHSBv+d=`+Po z!iOIE5bwU}F@&V`X9Y<1U_!pUMPZ`f(|xG8BIG&;t*Tc;&$rD?1+8IT~99iGIf4{zao_7zblv7{5TjhNDHh?V)pq ztng|>KtFH-=#GIr%ll{m;ANCZfP?ho01q%NI^4Z0dPZ*8$!+b^fc+!ce|r1}V%U{5 zXa53>eL@)P%Hc1M|EJ@h495J%Z5!i3qPBHg=a_(TTk($u;2rB1?-;-Gj{3#BD=Pkg zb`o^6`P6IJn5g~T7V-;elX`NjQYaF3K{`vabSty9%k z{I0Fk3h%Bc?|Brzc!xR(u>Hz=&sGAI-+oIgI%NR3q&Y*K_uvp91&P=8Z`~#ST|cVNA<*-LCDs zA0T#L*Sc5j+irEMOB26>*0xwI($%)K>vks_YST&~YGnSu`#jGx84%iS|9f5k_qzT& zaPmCo`#$%%&wcK5pYxpidvl())P8SHqaSS&La#a-z&cWv*Z25b91vkaHp%-y{1Ri2sC?p-&;b9KiizvQ_T zgdVr1)mp6DUH|L8QZvm-P845e;Y8X7LY~w^|5;`oC$2~QW%@fK-6~#w=2I)OBt1GK zAd}>iKkAu$NT624V(oyuxcE*bTVDQ~em&e-04SIGE#QQSEO6QcGXj^iHQ5N>`MEeg zxS&^7Hcg~BwG5nw0zqt^5ZjEjG3c2W9wEp@gs?x@1n*-Oq(hDN!n z&F=VCX8MsTA{s)czw;Yvi4AjY=MT7$lUvMQ;eO7uQctwWw(YMrVt>oVg{PMdW21!c zNyQ8!ABd_e0D~E^`ejjDER(DMxCwJ2BQyh}LEQZ{jW1rud&;!P9hvI($;-Tnt=9NB z#LX1~Rr#1_uUZtXDvDJtiSC}wRf4-+!5Q2WmN*)%TE=&;(Tdq}UjjFWFF#EwfwDju z7p0GLomr_rj6f`2u4=2w3r*)UX{l&zu6zbVm<-NnRUu8vZH`tgiMwF^`Zu>5^y^>>#cGmGJ|<FXB7#*bUtH9jkKD z8L_I_d^jAdDk>FQ-hCMb!_{I$v#?;8%cTSz(;W}o%Dx+B+;6*@2Bd$AOBVZXghG1LVcU_NPEatiDKY8?0JH*J4W3J<)erY`DNZp)yX7H5V2% zO<>2Kmy)IlEV5MPmktLnmvpv*BQ+FD=|@Q*r91jR22^}fj}2OBxRiH#YkIWqG=`{4 z)T^5d9Zz#{!$f?;e3D`;`UU&V?nx}n-s~PvKXEgbP6yuNl9bU56QeUsjQ)&yAF{YO zM#YBJCn)d;IK&QQxby%p@ zaX1?PbXk(RqSk$}dTXMJ(PA4O&EiVj(&65(M0VS*=(|!3gVoy|hr^N~lD9`A+1T4H zgY`Lyt$Bl0&Q+eoR?KNYxmvshje`18|Mb9+W8h~@_j9UjBbgAO>I(okDmN?tr&wJX z>`&wKORe;XBl0nxu_`C`oSFk~7g-(O;$D#C!28AYCUf99p0aYiX_>0P z3ofAPxjNfRLiyI50 zRkJa@5{2zPUofpDdIM)xpfnlT@h_|FT;<1IopPIu44D?0U_KAMq%dkOXA@4n7WS=k zYj}0(5uICS3b%GoL@-SZ3vmpfSrc1Tqn}_c4j3buf&y5e4oqa|!!d^*M&v~RjNTCV zFbUx3S_=DUI;`NPD-eE>_vY| z6QRN`x4XG*wy~pA+|3@l(*|RUx)oP*e5=fIGjO<19ovFbXd8GrS{Dz^ay(U*rs|Rb z&MY>%Sxr~*Gs8~qeEzuuvnhHK>qt6-5fh$ghRgK(Sk4T)9Q{8fa3o!*XKXlDVM_(| zpNRS+Km{yIg*7$|kR$1|QjjrIAtM(6FF?cEKd$Ucqe0r4o7ztMNV?3DqvLQ(Y3jfv zy%4?A?s%%2X<{#+jQ)tI3)=d!4CeoOx2U$-jkc=kZDoG!m4YKoId>wwU}XjpS(#rj zoc`PxVt&DJmjgMgNQUaG3Ex7(%j<(&vDi!gNcoSjTUpiVL{93*$#Of7U7Ybb;?OJ8Fy3*A78F?U?#q^Ux)5P=G?{RAw+ z*2O|@tnQR>=6%!mX01rLPgUcWG8zg)nUoN%JC(Q-X-KXQjNGV=W*`*_{P+LY;r~<; z{`1|kXr`s!26jiE*VBD8l`z)SgkL5hmvv9unibh%vnAYICqJ2Nq3bf$L&AAmiiGXj zJxOR3qZOev_Tz%ss}dn!1yyn2Rlg3u4u|+*$mw=BOtp z>aoQ>ZI|njR!4q0%@e&fR+gLS$%)6f8;mw9E_`lH^6I1ctQug{H^s^jB7)Po_2@e0 zZCP7Na8mqe&((~a>MA6=esR5itLZ*%X@(Ytxeh!kc;A_q>v9ZyN&1S_E%(V!3!EF3 zrAHvwWd5vEt8zouz~tCA#p}1{P#st6{2;pBz6M6$oO|}i(G@I`Y&$)X_Z;`#NyxF2 z(N8)(q>Gi=WtnsK=se9?CU=J4K+7H*{u%s&2(f_i%WIFnX zd2%6{HSob*(e?IVI#W;}d!qnmEB%4v0rom%w)yytWz6r^0WLxsW(3zD-eRyfHUkS* zj&DtmR$C7yQ6dgggL zX@L~A-Zo;9`DOHWg1IaWT3N}pLvq!VJ@Ubap_$}Vz(wx1YNI(M;sUpH+7ZF5>A>64 z&opJdo$LHpsoZmZEfRtBM`XL5i{VDpx4xtQN)L=EEgRCYG~^%1Dy;x|)ewamZTMs^ z7DULO$Q3{zl4zkES$}f&bEK z?nQfx#G|b;A3Z<%U6qlh+D0@w*(l_ff1n96)9Oul_M_FE*94gs^^{+@Sjv z4!R$TT^aj9v}qE1n7N_payK7*X6tWcTAt`*ojDnB3^u*GrsSHCtvd3bRxT1dUBVj5 z{WeMpW~HXdWB-A|>dL+=2O9_X7c6z`eGSOO#>H!d_r8O5jbEh2g0uDy*3Q~ra4x#* zb;sVXks|$U^luvJvFNSEFINYzC_a;3yZ9ll_N$IQxLCqNzos?CXH;uSpGQOp&W=4e zAmcT*zHqQ#y+s$r%Fz_ojTgUJRT{GQ{xH@*OQmRM$*0k7JrqO_<;FUGU zPL{flvKn3==brn5U8mAVO26MXtDHa1*k`Pm#dz%`7bsf`M#jcs?tCt1k7>t#$$jU8 z%Zm0S4nXCO2RvU}EWb|1bP43CPb*|Ve zd);%8_C}7ySwnq)_`S4(Bkj?;xv@G|)c#o(2=3X@+?e~MNc^8Kp~QV+(9|9ajoy~T4a?McQ0qfm+-L7_&lP_5@k}_8;6u1fy`08?B zJGswp3lDoD?s2QYQJ2#mv)UvPC;?Ex$_BvtW$cw>@ly9&eOC|KBe7ks^p{}J=P=Km z{sTgLe0|`v7bI)&N z*W26?`5JG557vx+SDuq&XOctPABII;baZ2ChOx~W%@bSCeYSarMXjMOOP}p8>n+p# z8h@Hwyz$$mmKX97nOBP06Rr`jR8|fqJ%iR~$fz!Tcln={JYoK*J0LxA+1b{!u`J6a zTgX~^ZrgP1Zek>2G6=g^gVmQL!@yv<&M{y~%ftK2glV)m2Hu5obv<~*H=#Wvt?|+v zT_27uCtVlr=EiG77Y^$h6_yjQ{quevYhvf#{c50R@NgNUXYDf+4*=ivPsN@K!OpZbB(V)1X0FuMu3Ez#s9Y|NG&^f2V0gTKdH7G0a|$oYBBx)rmYU;N($K*5 zv2$w!8G7DB+sPpIbiICg^N&l`6!ZkRyYlCvX;CWrh}`NssdV%s8PaeHW%$}+*-|fD z1ICao<;bfumMwtDYfda%3XXDhauRhZI{Tv72GsWU((l6i&`WPkk8LQ7t#lUrxby_W zU9N4;VwdBCkX0mo%f_67=c6mp6fa@kzQVgIv2__&IiuImcO+KMCWxzHAGnIWTr7fC z6z}i~Qe{0UQ$kvXs^zqW)aH;8UkZp4`F1a{ugkEunZHbYwr3uFxD10C*Wg1^ZSg<)P#IUA2C3M8 z{x5vIg00*Bt$2fY=iM1vPS0ucQA~ycl}^)e=oF(f=69 z<9~IVs&w>w=#T;Iu+-HY|2%up{znh+I`)&;RxCMLcBR9|RgnLH{1hkkJgVHdU4ddB{Q^<@s;rOvbvBn` zFUE6lFK=9|yxSVQA+}gbX9vy7#lFW6K1>XEX7|sK+H7MtC8K9VmOn&X8k;EC@t8{Z z?`*M2&e6Acnd*tZT`J9?FFW2i zi8-Tt^<)MTKS?sol1Q>!Nk-RloqW+}&Ax4p|1H@@x3UJEg5yf^w8R(C8mL7CK|e*J zNgusmidMOiB^CJ~4FIfA36H<#5q|m*RJAU4olr{9=I^2Amc%g{75}W0<}u2#uysr| zLats8T}j4=N&A>3xHU3vAyT!Sxb%>(cxc2emrQHQ$U0WvH7!hn3DPSQF}C1}LH7xd z2z&^8SV|!RQbb4Y6g6H|4r+lx_h}}O6X;{#B9`luha7)13>Q!ttn?#yzP?O#7LSMB zfbvxyRZZD>)r7VvSR4G+G>2Q-RfFZWc1rZWy+?(~d*E{a5FPF{sq9&bXV!G|&t&Ma zGk6;lVvB!>45Rl8%0rX>Z{mr6aUrXW6-%Yr{xz!%u$PmK%W0jLG zr0t=MlB%2_+R5`;d0MR53LjeEfU_Nv zH1a}GVypAa37wFx9hxVBo&&;+&an3O-Z+A327L^d3Hl~nj?aG+elq$y=65X93=QrY z$9NPL9Yjvo#|DGOI`}W5b{`oC^0yK~dH1UZgIft`Eq=cM!Tl661hD_$8B__WN(O^h zewbRBrBS0$d<7MjtRD|@ll*vMmQYE_dPLVkf)m*?8rdMTgf;})5}{KVbt8Vc>}Z7+ z#g;#e=kQ+I6tDyw0SBvIcEQnpFg}PG8@(`3@C}TF(rc8Hqw28-Gxb)fFsXa=n=Dq< zW*oC1CdW?fkrPn&$(Ck)PU#8O6{@MBRYtz8)|U9H+Zk=FV=g&z@?>CKIC3)e)+I?t zFA$EMcFE#cT_qC1GIJb4P{t_4#_|b9-f3gx4GithWK)ijw~K8Z#;0Aciwx36=CRSa z(#(2vdNwWAoP!;K*pFEj!E5yPmj2k_1}qPvO|R;0zJ?p#eT!);`|4}uws)9U#P_zW zQ@jSNtV%|E<9|oA-Y6N-SVz*Wx=5dY1EN8cNFPq!i*-*r`oC;OAj6U+9>OTnBsN~L zaYt!%ZlCm^?C&dfM`XNEk3jdy7XL}HMCH;$s`aE3X3}`vqDL&m;-3iesMvPcO5fOK z@12P@DprF^c`Jt&>|+^yI@)Yz7fl*VSa$wLQL->F4T5i8B=ZP(wF_Rk7F`&k)h{yS z@X4%<@J|?T#Lgy`$B`Zg%u4~JAv%0O;=Z>Q`uqRG|lmkE5KwtlBmqn zjCx{`GTNBM(VKv^Iba>j!=D~n^c~5d@W#faGk#QfsLY5vA-X_1y{a1LRCT2`?!gRz zUoIS0hO3aXYKQ-Bc#t>o1_Bi2Cf=B0tdHI%t+k0YgPnG+8-ED@+UR;4s#2+L<}->% za)Z7eZinB|8k*i5?~ov5AZ3S%?tHa}?tG4oGfLN4^GZ@oaqSZ2Gdrn3`J9SR$FIl3 zoQdV+_nfPWU*7lXs(snQmUSL^=Ev8*JTJjexbX+8yzpyk7k)iYUJ#!4OFCiO@!Z=5 zO_hv`%k@4}k^V{=KbEDx7YQ>ym@klzo`5WYRbfbxjyJl?9{&Qu%G$MF8YE~8FBdqp z;8n2^-Bc-BUblU#Excr1Fui(=15x&{OB)pWh;&bG`l?X~&NV zlo6h*Pc9g~Qu3MsjUtf~svL)!a#X-c0!DwDt~w^R+Zqorbc)|xTe3m;A{`%OKhlN@ zIFd*UZD#s6I(ui45Y_>JMowg&r_-5S9Q_YbQXoyu*Sh|&8_tD$5twGZgysj>7cdq_rd~nv|;R9b0s`aY3 zhk1+mUSYlcbadB{C%XQH_7V3HXJ%qnC5UYCTlYYT%a>Cbwv2$!x4X53l&v%WLwguf<4>D8cM@T4H&`LyW)z#~0Spt0x)>Gej4gJN?mI%^g9DQ&?OGsj zgi0|u6)GulJ3}|IdXWfG$i=Z!CR!cht~)RJ*bgL+qI@}%JS*ul>zhq28|elyKXX=_ z5a1W>*>3&y;eY&Ts32C&(a_TDQ^3#pglfBZ#>F!;R_zqeY4KQNWwW2hG#@<~Ih7~P zVF8LD9&oX+I-;hbPHJHaUB-b?SLk+i_%%jVVz()u#T6}6#~yi&jU&aJjtA0YT-Zz9 z?NRjX zMjFqcee0n0$f3s$$ZCJ=8`9!|pS%4U++@i3aI9Tj0YDqq`X% zXWWUfqd$kYi0>$BU6yHsyIv2tM4NjQ!$)L}Kf|$du&~F+qBn7$z zC#5(xsQ~z>C;lnw#rRd^+_|;Em63BF23JJRr3IJA+;3s$X1S`Z;CU?K2ocQ+>wSA= ztnMvPRPf!>;ZPQbXd~x72wpz+dAKy=Fd;^mC!`f}WH@;F&ATQY(c8>$7+ylvd*o-- zyX*AYvGr`5t)JZ8d_gP6y{i!I^(KPMAd5?zmu8Ra3k(C2t2y6N$|?Mr>L~Bz*gsLV zRH0xHU}B*O827mJYEqFOImH?BmcxRE;snOlRHw_DgI*sod%7k4NXrF1eL8lXbhO%@ znCj_cW>3E>_;*kK0}pz8m`7k5J)t`Lgx=Y&8=d`qX*_#GoCD*aLETAg;>n4D`;Dev!ivd)3w;0 zqjz8T#CK8=_L1q^{K&+I!5gsz7`#3fI!UgA5G*7(vjD+*a>xELAy&5FLQa+MmY~+&)#gqu-{`%gJhUYc+}BSQGnKw%Bu@L;@36K3cFg@3Zy49J~&Tu=dz^!Ecvlg{JSTz0$G*v+?hSmukU`vaz4YQ4!b; ztin0PJDjpZV@G8S3`7uVi=&lb1mzkmggW>#B64aS7SQS9JY=qnIMX@S&2tj7_6tFb zf5WvebJ^Tb*}f`E6=vD2yq^x=!To+!ORf)o5WZufW1ydI+}CWW3cv3S-L$XXGFW9< z`rV)v0CUe}SpPvv8T%A@zrXbP;44zj*l*e4%dkaYmRIhpw+>cWjr6v28TNlfDEWT) z{mM{Lc(-MF=$7#AG;OddEjUM5;o`#2GWo0JkFi!w9|s!8K({n<@x=Yi5u$9QHEM!< zojQ0|YDm$4)1+s<31d_1SFh*L-7M?%MgMn(W}u^NiT&DKT!~)`=D5SVG%fUA>94m= z=Z%$B-PpTfAAILmO-+IHrho;msD+sUCn%fc)gj^VA;(C@lT`Bp)sOyp8kc@B%kL#Y z>5GSKf)KWKr(5J3IpU)1hLlchwTeyoK^$o@!pRJqI#)RQ7n5E#ONe;-Q6|s_bwg_< z^M|PLkOYP5yzxpj6s0e+sqjU>ie*neMx7(kY)Rwz{49#tmo4o-Gi(iJ>YWo_E-2SR zJH?vXwsRTZq@=;^lVfYb%cbwMP(#UljhEn@fTgLa$)8JVwA0WEL!;R6DlOhkIti6R zJzKA7^53-*=_k;gSga$tpB#szASN28B|{)9m?-_w@%gjxpo0=o`l34jw3mc>s~r7* zFUVakAZfu49Xb4+J;hmO8B^(H2L%ICb+BB={S$(FD=j`ac|SEvcNn!e`hP{S(j(L~ z`g7j(91ly5AL4ClN-P$PnOz{0*g*-147m=;6c=|P8PNQ!sj^GvOAU^JFOVN@eVxq4 zL3j9$jeI~tkkGPY;GcMlyp*=&dPo1`yf(+bc)bQ1=`J}Rple4=BImmweNW>km>Ro6F>Qo4}((Ho*?Zyr3 z2ZrtnIt|HMB&u1mLQX7}vJ$iUDHfx-&+$Fgy1X2m^O+C9^1n>-=dc|Byh{3iDMJG0 zvKS`4-wqa=^dV=+g=!biF))q3P~(nhZ?T#lLc$(2Rg5tGdf|fw}Y?ijhw+ zd>h72BZfA|XOl`{UT_*)E*!$YUqGj{*+7aas<{cLAl91(<>eM9JUj|L&3yCK($WNP z(Y52jxg|iQP7BU9bmN@M!^*DM(^a}$EY@k1uLuz~$7_Ot0B)SuI3D~4W57VuDm5I; zl%p%~%9>!8-3e69hp*soXjTBTWWXqf(OC@cq|c%udr8P1syrzCCD8VzwTGXjQ_j8@ zJ91El+LzA0huCGMSivdjnN(#)KwiPq?3XWTly?X()5&@|T?w!`UXz-egDVoVzDaa! zT#;6yD1PL3$lLxS{oqcxu356v>yOn_YM{gH>8Hsy+6t{I0@d00zVM&Z1httM|J=2D zZw%DaJUva1E8aozOL7?yg0~0-<-LBKhfUwpUb?oT0=WyeT zB7sge>*>5B?$a7=#nft|Coeutm7u0)eU9nO2@!cyd03+OVQ%UaE+Z?HaBS7 zx6-n5DaVtR+z`BO9~TA3Mwq-V3%@rvn7OaoQa1LRCAmTC-dt=SpIdT6>}>E#Cd$wU zoYTo>B3%%iwhSVyANzH{stj(&e}h(%zQD70{kVS!R3?W(=%$vvD4W$zpp0GXW6sbO z6l4qEu`XzBKI5cnAIwsH z1$ws^3-a(Hf9#V`#J?hksw@dT@y~x|Bn} z%&`Bhhe5flB_pSDy-l&sy!__KhiNUL>klr1ofW?++PEJf-hf~at%zPH!5kfUlk*6L zPs{KsjR);}KD0p}aBbnNzZ1r{=N$g07XlGvG82kI{jc9wk z*^FMPf=c|gyO#%Y?h-blg%%tZSDEP+IJF9KxGfLTeoZtUEA-t4F;Unn9qbjjJpw zL@Z}F835Yi|HR>7)ud%ADE#zakXH*XGAQsXS1Ae%=BZe3#$F=LKK!?zn7yBASuF4< z*h*gvWeF6)+rdVTROS?KC{v&a&Vh*%n7&)5Wp4^eJfs(QuxuE?;Q6Fzp$d&&r-wQo zJPH8hcYJr#+=y2u5RdmJO$};ZX}c&SuQnb zj{YHnISk_$GH*%zC~_`6G>^}7G9=p3FPTa*q(2;=6RFaJE%#)~H2t#&NnJ~7oyi7g zr;OI@w^XkR-UOzx=8UiuVvOZqziIaQ9RZ7x1Y$07h86_UjCP^yA|nzFt4L0*8==Y{ zWT79h(B2;*%M=gY#oC66D{{)I#=pxP|J8t2oRH%vKLQu#_+Ku;jQ<4Z=JR6L2@3ao zDC5M@|5t!$G6E%dtM==pq<VF$#HeD%HTN7hopTv z$6;r#IdP1J3%!gkVyz@aN`I6n@PjL%O{Y$qdP0LXogUKZw8=;Aa{da(gmWp{#MZT{ zM+gxU%=tolIvIuv+v(UsOXv!t$~vZKMM%wwAE~Ic&{9ld>tK;I-x<0^{Kt@sDUC1T z_5N2C$ngQY^u1qdpair3ox0#+$V;K6iqEKH^4E&Z_r*gL#bhSST#R_mV4aGwS}PEz>qT-U1PaGM4SyrPBc{slRV8q9 z%6z#rk=jM2s~YtNo-@EF;@cEFZ=l2&9F$a1_YsaR=!v3rN2Bi72i-?JBks38*Hp%r z!6yKY(Xfb8W&7XJf0PN{D4&tGL~3KJJTYsTq;QMk#~HJsiC&e1&l9sHR@n@+=Ei^U zpZY8pI})5x9xjn>qa%*{AEbtG30p@se5-qgbLqP!F1USFw9cvTvJL)=Kw2q0Y7*8q~f7z&o0mpJ@v#`6@hE_k^ftWH+|wJc!BmP{*t!=sY~$3&#p z6fx0b^6nUT6{NJtR|GooM1XUOzKkjRw+_-AULw+qk`6hq-W*@bU^-AjSa{yYzg|WU zzTjN8G&DUtuaq!t?B?)t$*?ZuTDC4Un=vh0f#Ih=E@45tf|)=Cqx%KaaN{^Rkro$r zlTQbLeGY%{^?96c`yF2!c6?2~&I@HbzE*b{H_li2v0@tFqB|X)lEPo?~HcKokFwZa*%Q_gZLKNSpJdyVpkf|(DGzvIp zNl&fgbAsjKGltlo8DC;n-IffRXH@MEQzA_-WEwrg*vgh_)CUjxD9EOy@Id7ZYv>9c z?4JDi=)W6in@L6_FaJQY48-nS(O;;v@=amnB^e@)2YVQkAUTlf7i}X=n)M_-(cG-2 z3|fS|b;js%B^&hTJxR@ufiAeQm~Q2h1Op#u zPkidyp<}-&yYcwhf4%mHE4Z)a@?+(r6uanMJv}8~c13P!5UyVDN2#U`*o_bJq z#GdzLh;mm6jZnxx&I`z2nM6K(3iLZ2{m&9}ND4N4B9wc6FO{fd`$(oz7=)Vx;qDIL znXS44+L@M^8$R804rE z1sQW96r#H2%O)w31=>$(bVTPntYBmmnIPsEV{3OHrQ=Ti!T_!a;G_p~wX8ZkS+%z=Q#imNHDL}IZpHC;ntj1zsT zK6n9;CKK4bHU-d+n}E8051`h8Gofr9`IVVY%f(0X&aVnwGTpH<$Y*+yDUa7Y*`1gj zKh8eGT8TlHmJ=Wb1C8l46`3gH)bBU*z6s2Fo~<^2GzDG7L*boydGj5AIaHnZo5)a3 zw8}a91>%=4;!kK{>{&&OvSzHNS~fXnRr2)1TUemZs#UY^tYth#H<2MSQJ~+|VpPe2 z8mLtN&VqwLk@wPq)8#^$frTV~MwVM%j{+yLH7D^#c)5hk*N?Os(4wTag)HrYnbU1Nyg)C30#@jN~$t^>ZOR6GgVGYY$9}>oP-Nqt}u*}^bi^_HTjs+ zHw!)K@7Q&Pugo(B2uutKh`4Wbn;_ed4N&SHJjac zZX?-{>mM2#(g+G@uO(ia;A$|o8P}1;;}sT~m?aeiZ1Ns^@k?vZzQ^gISUkOIwj347 zCyq-)S_)niUn4#`mQO`hCSH+PMN1~fB-Gb6>+jn0f(#T9E|$yJ9UMprWk;6x%d4Y* zfGBd=^;2Jo<5EIwB5^!@VoyTEkG{;4x*x0f(e z2WR?EL8{ct{4er|G|Z!P*^wb6e_gw{{<})t8vO^`kylX4mXnB5X#|623~pS(zch_b^6wZ@zDv#?scrc!RBQen|T0V zMta%1jKw1#Qj6&1_1!OXCppG-e5Dh?9*>76=zEf~A;w4%E~uwvZK}s~5~CUvt6n$o z^6o3rf8dv^pjRb&*2KT^Gu86*Gr~CJoC2d-HnExliTFPBc57oN))HftUVn4f)dI9X zj*JxFL*v!gO|O%B3{jhiqY~j)5eNa&(O0s8C#Y3g64K=B0`5TxLs4+o+O^MF(GsC0 zE`C!q4QY^a&cQ|orRa!%2fz@MP(LgDA|;rjh}C7-*m9Ax9RvI64fRo46EX)zVg zohkny9L$c*ELb%u6NaTRuP`#4lVEz2*w9JG;r(Bry9W2l-{>s)tZK>C!3C%ebub_X-UCBAyFji11cF8tG=7kT=K|X27Y2?ZDVuQpx{tbLA3x<7^{{VNt0uy$%Vll zsw8<(_N-@vt~H?Rkf2ZvG8*o9iky6Kzsl>kfC>+6h;b(ZzSpaeL&vabBLQ@^tYy4` zbV)T^l%sEWS>(v(nf{)Ze5blxkGIJm+aLwO8K{@)g;b=s)C5v;P(TAjM}I#3gnn<4 zEG*Sr!c*oFPArlHk4z@2>qisdNQw}-G<3()^2K30GRz{!z`qgW_0T3N62y7WXF{qC z=c8825fzy~eN6jnZ^ka$;J%>T#~8pFUrj({)d4w zx{KM%4j8fV(zC(&{s#%8zNe|LbR?L~CyV--Kr}lOgdZWiWY>ga;1J#A^~ex7H1}}$mnGv!)UNRB!1QA?5z+G>T|v&-ndR+Y-U@7tSWFLEfy70ToT2v_j^eYyQ_20Qn8EQ8gS@cW{U z+Mc#;nOs( zE^zc;4<+emJrqTT=iU9|G7jcgmgNQQdo!!b`5J8WH_SouBB3Gc-psN1vZ9^WFDtq4 z8pq+GNW92ALk?SeBf(c<-y%KgOaEU#Abo!fpPWk%t@H0CfHa&8G!Kyb*Ae6=MR;n* ze7(v(8C}o40E{kF75-XMF)qx$R;S37%GU~#MhlJl%2a)u%=)g;*^_^ns?|JbFnSJh z;oA!6QdF$*MP_m|gDNy$Dfn6nN zPbO$)I(k$R%rFvYDuLTfa9Okev_O!}I!0O-$K#3LWJbH11J}gAgbzHdUF#V59+Z>> z>Llktn6pe2{)RXOmF=K}HIH4(o{Sm!x*6#>C}GW!p)}9v!xSKuzD0;9{&gdXV?b11 zexX4B>%_#L!y8_%D3a4Ni~NrfsG@atXS_a4E16!^k%Vam0UNpaBtUW-s8H|FA598o zGaqo2&l0q9An+YIypYb2k{E`f+y}xSaSZ&5W3dDq7bD0SUf9eVf%G+F@2HCq)j`Ni z#WS+iVMq>Ln1>-lY0*r_;WXnGWDZqKCW-zDy23BGHHkh{1f@gWnpKl?$y8(KYzQgX z;1t4FoXbW#)r%0lVqU9OsrzuqTl^*;tV}Ru_Fk`V8Z6H!)55{|QY-mEKoJZOZkr{V zVtt2!Q@lZrw4&;rjIknEm1EqSvFDVXnaYb!w)o6l&DI|570Eu2!L3bha}+%5=kt9<{Av*2;d;NgBlIY(dMbiFrryCFZ@V z{vP4)|NQ>%#lUSlHSL|xU|j|0IMMC%*%KrfK_e_v3nTPvGvxd2nU8 zMYw$2mAI#IZ|~5wAL1UzeHr&4ZYypbt`@fhcMI+s+&iQ{iF*Z?h8ri$j~l|tPtH3B zaBFb#yMyN~xLm{UoO!usn>IZ&E8{Y&Jv}>ZhQ&du1WG_F@^+>+4VinomZe>$WnXCmL z#y>G4(L(`}Qiow0^=DJ_)!H2GR;^rX)%Iw^*r48Hv7}kjEmljW#b&W%r!3dvvJ_d$ zEO(proApUeW*wQTP0}i9m$XdUb{XppJGEqMEgfC0TL8e4gOtK=Nd48S-nqap_lnAI zNd48S76tVe`D+LFZIm$^dP@GF`Pxrosi-d*qP1OX{|?etXFe|beY)=<6gcl!@O2gt*XX=CPq?S%5o(($dmCoQdiQq$S6&3TDBQi9t2U?=JfSZ zzAasFioJB+{bpU~rTB@Zu6wJ2ulMvGXbqA&P37FwvxE1KrLFdDAr;0+X-0Rigyj;} z+9q{t+Rt>XDo?i}6*`eA2*FqhAcb zYFewnh%xVmb{+mF)0(<4U*Fu}+hznEx73~IUz~z#VtVLRfnMr@HMezd>r2H=y@Y%H z*lv|(>V$KLgh@lo+uFo(t=Oa1sUbDzT9tE09|meug5S2(VKcR3#g3q_vAYGc;1&MX zUhPiz>Uwu=@ofv*IyL?i_r@;0jMf*B%<=S6rprofYxXC}2;w_8E=eu{x z|3uohz8=gX2iwcF!xkfaMfdh{tw{B0cdu`Auh{9;3+37anz+sIXrE)`L2BJQjDUt@ z>smXzH+x!pTekpJp_EkFxw(c0HZp3q^*G~~Vyr2-^kzE9 z35Yr>lAZ9d%Dqy^%w^TA&> z!CW>0Yyx?@?-S1tYPuo4$Kje3HZP*Gc+%9|-9)f^ITuUC|rr^Vf8>DfXhR ztgJDbc$a0hZ?j^Fclvf{pAp}xkgs<~b8BbF=Y}w~UI}Z!csU6q;IrbV+Nl&9R2hox zlBQg16Td!5s6^%3r&G!(*Y25$SLxfu@9qk1QNHrZ=5mh-p7sgNTP+*}0D8fibh_4y zn%LLbi9O^^@ZfUoPSVisI;;#c*LifGu!XAL?kzQywHef!-p4o6+oxg~o=vJ)4Yud|_ zs%9!pcc;(5be4t*>M7h(w4|9xN8*OWCldFGWu?c$W!iq+-MDI88E#Hj zUk7%zQ+VT2SBL;tt8Qsqx53=z!;E#0aA{?-8q0HYTndYwoh04V-P;@L3HsU=m^Pbx zeVge*3J(YJU76!M{Q&`gO5d-q1ky%oQ1N++d>`-t? zW)MWzd}FZS(uOKt`yut?Oe!mED&_*4*r@>W-j}30JV&cvcE+#EW)dvi&pqP6UteH3vyYwa|U1F=tRw6d~HJ@X1)v<3uu2z(DP;c6ifNDdd-$Tw8BluxOF%t~=+~F?V!# zttWi0YvXbrCVewHg56+y3q6$*2Cyc%leVH&`do1D>hpEBYcBWd)eWnq6m$^%W$M|^ z--93{z=bNlEO2@P;1Y`7#`|+Kx@Wu0Efud^6I+79}`nO8A66KOKTb zbn@5CzG56DL6iLR7|1fPl7Rw^^ukicj|j1@)~#>=5nU7k>9aQ!E%xjUx)eG$dX=(x zC9giG2t`sy+sYLM>RGo!)!BBZdRBz`g56u7^WH+~5TpWCZntV(YbV2WOHX$fZR&IF z=nlEIb@cgDs#>b0z!Kci1JSpeU?k&GikJct@RIx~g&tM=&gW73n9)~!(tlfeWQ~U) zuPt>=`9vCZwfTbJN%cuMqg)G5FW2guYPEH2FnDm4IB%V|v3zx7lZX7?I?w8cm8;9^ zyzp$d_s+%!51JQEyGtLe>$CB!+s3rYq`81UMA28v=k*a`uA4;exYyU)uwLOtC3YumoMmYZ|^}a^7XD;6=J#Ks#SxL^2&R9D#f_zs-~KXJ8R3E>MN?X za*wC7ys^BphH>Eyw)O^Hb-pfiDhl#CcYPE28r^l$1kJnFtJ1a9)T?JhQ=@v;)O*#7 zdyQN9=aIj>ih@MY3e5*zUB(8ZIsv28}OMzV%ll#_HgnC7cHADgGtXR6v z$Zn1*%F{7fRa5H*o4`fuw;}EQ!SdE6F{7p#moDh2K9q7U{j;KtLkFd4VKzIFt+a3k zPxwW62G1vX@<{omX^^>ggmAGU57VZ6%`22ZjY*XTk*a!V>YW&A6+TW-6kK$*@C4Wxf%Srk)t<0{KiC5^2)vV=! zdWxChI;3?Mu2t(o?<{XV)&d=ha#VUXRwa23|JY_t+|OU3Cv+_;?rPo~maDXP(j`v+ zS#1Z6e7RbIyJ|CrtLEmuU*_|2kgMwK=No?OLw(B7OHB^$n;pG_Av;_eHyQ6LCAV3F0C~ z9Q0uH)1~`YG+~>xMcTQPHcYkeYT|6#hZl|eD;0OCw*Q8`k5rlwkcMnW!t%_NKWI~j z)$`mmGhUe*6drP+$15zCX{XY+Fse6!gHE0swI0THH{86Jw)XL_7;H&X&kvO_ zp=*77=kop=`Zz5W##IN)B#p*CQi0{Oe*{gL^fp`d6JM7k$EcKMwi_Jt`(x=%sFAsgy^eir$oJ)&Kyo`0B5>33D% zG^pnxVBxEW6uuxMO@mf+0<&m37PORk#Hhx2gmpI(rl&tDXFrol#%zg10_-zFlm@hh@e=05Vc;h8&k zv1UzM`nc|&%Q|fCjTLE+>;AcO=eh`(i&x^)Tyy8%;?hX0`)`~3_-&6oQY5J#zY&f; z_wh&M)s@blM<_`iH$HyLAu0YgO+p{1xEmioa7)_bbM<0eS{iv=S%(Zi*#xwukFYr^ z>G?hKI0Zf8qJCBGX}HKgAP(1U%4j4jcYu##E?!p=O_TLHh~+*ox}|pPTnP61~A#Q1c`7K z@=wD#a5p3-hwe+9+YZTn8utNC|H;U)Xf789S~RPYl=P7#^e=LYIFtUR-i!Sx>0-hE zrLdXF-{>!ruQPw~i!?fP)q+r-ZlMQg=<8RM$#j8t2C4; zZB_4*Mo%|WQ%@DDr>7Jrc?AYl7YVOd!#x@L%HH$oYpKpJk7xzB`B(M062b zT6ehoty@LWhC}(Zt=pB~+1k6=ce6{>Tj>7SYwVWoT&4KS@4Gpx)7KtEK_U6ckc^&E zqvWsjb)nDi>_opP8pG}`-u!I(q2UpYp0Ox)m2AIxK^73}x{CR_o>KHSx@wh_J^FSq ziS#to+PA5PDiSlx(%1oK_mtW+cOSTvd#kEn_ zMN%!FPkuHLyEY5FQ%w(cCrc+jMNg-yr>*n)7N9}rL#rUl!erZN7du|<9h?7{CjDXf zjWRC?MR@7CpHR5rx(Z7X0U`LaF3k6;5%k(HU@5dzOW1=Ib z1Nw-ivqjA%yUKm2ekr52rovtCb(`5m(blQ!`1E*BIa_hAo>n#w$li{M$K_Kxb2Nf_ ziu#6%hWe_Sm7upz^md|=+teA7y%bTAEn}Ze>Cv{d-V0%M^oeTlj&-RG(#xr+gv{?H zyP43nNjeVF2BuBAV&=RqB%&4lYP(7xh*4yt7gpKkYZsE!AAKrG-;OQ!ba%Su>S1#g zhNNtre8`9T5X7kPR+E5*5?!L>E>r_?Q)`#(SGeYjW>8egx(Znp!{$?4Yi}FP?+FE= zyR0VJqFzeD$rjy}#P>oSu?v&fTS)sCnqULTde>b#V5((1sd0U3Ny*N?OZs>{)oCuJ zBLv>I`4DP5+a4jdc3k;>z@*#y*uD~MF$(WtgT3$OrStkEo7M$WSs?jE`Mpu^%#BU; zqE;)ft=;Ht@^~6nHx_D5v|AdQY(w9+4mR2a6I(e^VA2ikXNy5sJ1@wh1`|}Nt5Fz@ zs0&45=HeaJv6YSfHrK~m`{sA_L97(&7b>ZwvlK0* z00{UVU+XaI&lTnE zW->_fO-fxagm>!#S0f3!dplr&`cO$}o@)ylaaUJ&P>@9{dwqg!u<2_n)u$aZep6>_ z#}>-trv{zUkM}Y?Db(r3(;^cA3tTnrs(_E81~6Lng6R3S(59fY+||12-mdO#Q0`{g zQvhA6TqA|6t$R~Q!u4H>ZL*sN#CjDJWW0#VHK5{!Q`QS zXmnwvi4URs%?g*U{Eh{_1+KX!%b9!g0++sxDBHcV_aKvmo?mB}?Ci*Fp2ge+ULau`AKqDcGxHh7mTW@A1K-v(!$lbRQ$Uf+J)F z6)<1L7p;%2&=%p=;P{1Ew1ru9hz?%#?_qRKVJl9TdGeuF5lA-bT>Ivw`fl$=SQ*m+ z)yr(L!?lSi*wg(t{mcA)l&m4(DV#+Lt2G^+F-KPa@{{I{T1@%wRlOx|}t& zx31T@)Wrdvpx$Sc1tAMBb*-Zi1tUiQWRGSGXKZD-2&;z4843xnj?UUmn?J@_*^d|H277i2?s3-|Qhm1;B)A)@Ao4CBl_fi(h`a_)R(8Yp*{<5`qk+Jv^HAZj3gbod zOJqnReC8EtdADkLw`qCB7|GD`7HfI8Yk42n@|IxhLd!F^uJX*itm-=}R%_LF*4FW- zqKQA^Dk}I>S;-$yB`{Rq>0Z0BqPE=Yb$d6iZfI!KLuwl;%4;{)l~+{P)VqyDO{--K zY@?i}(nI9Udw!%o;p<_QYwI`4ew^;}xK~#-tgb7suW;+3nkHxbAjM=)Y?1SN>{7ad zoMWR)w?TkHOq{{n9qXIHRBKYZchl!##Z()7`LPZB1*esyd@KMZ891J5fT$w?hVFlX>(uHxHV z_jYjjT4Y-_{?AJR~l6^8=^EL7Z^Bd=aK(?lML6+J=?Ff-fvrao`K;N z$WO7HOXEM{($rZO4w(I^{4+^!$ue}vyW86}IU~u*qYA%o)4k>d+}?_qpapwFK0eY{ zf4P1^g>eoe6y($|>k?hTV`kC(tiv=;$!*iRSX1??H$}GuN&71GBPYr9DuK$xSp><; z&&))}c*&MbyJF?aUd~;?5N0Sy zPTe9M8ZoluZ)H|u>~IQ2q>&5KwQpWNujuwQu6y)nmNrM1Z!se;bq~LWZpU z6%``0=|Ztdlgrp8Ty}@HT+`)d0ZE(Fr_Qubm1X)lz8B(jOdG_`vO*4FGK8r6BJnba z<|rLXTaw^K2Q(F?4iqYc>1;A}WNHnW7t`eaUug5{gT%A?9r2RnM-pJi<>>m2z`boK8M- zSn|v9Me(JG6r9IW3*98H4L=9sv&^^}gahrad2Q=m;8gHxq^ax>r9*EPJA8c0$YDWQ zr$lP=Aai$=xdV}qj5oK#l zUtRf{n!1`#xhsg{$2wkmMWgr1IpuOU}*;|B;@a*EjzTeQ{N{Vq^J=hSiO$-Hof))~uvmZjCUN zS3N64Vy~4jmBjFhf34eF-yrQX-&5jhSO~b+u&$^pZ{&cxN+V%4^=c7tUf8N8w^s#F zj-)|K@JN|F>KeR_DzDewNJjU{)eTMcvTRZC)U2!~R?f23RH{bsG+?NyG}=;A35+$B zw5O(0HGn68OEzulYaMW6a1#l4<+FT;J+P$g=6SP($v|1y(az3CP<@T7pC31;cr`t% zv6Ku~-$@9r^|@OjTVxQE#T%3}#zq9kB2(j5a01n}_}1HWwW@H~HaT1D+rEkAqfafR zljW$imnf%lTX!!_nu;asGGjE#c@$s}{$-qlhg^j+@0!=Qo-8tq1u6wEQ3_ro4sgwA zV+=7h_XaEEl)SNaRbQ~djnJR5pdxjfZ@a?HpE7pzaXM8;s7sW4OcHW#RaWQ5$Skjw zuh|*b4fTzy8*0_NdyO9Et*)t(HwhGXVVPC)@Ad7_N2KVA!8w{)_6nvn6CceJ>Oxc4 zy}1i^+UD|i2a_eFWV)~(;UV+yP}3S%RM*wNS#(W-&DUsd`CXDcIC4*_VP{t>4>u^(x0oVLH085E#eDoln?a9owW~u&l!5>N| znn_7xOczp^07UOXCCle^+<8xyCI@{tmNz!8u36F4=-z0|BfxNec=>8HFU{_cgjd&8 zR=Q!Q7p8Bhs;U)D&4uBs-Q|@H^|fm+4CnYWC!s%DjvS9}SY5t)Em4{YoC%Csxmj7V zaMGFurWPPNF7=f%U4w9__}mIn6E=499aooZYiZSpPCC72X*KH0Qoe0vcTt~lU7rwk zBt0u>m3DP%Do$Brs5#zPQpg9XdXCg}3o<}*sbZE_)2=jdeXdV1R`e>gicY?@(}Sf- zksXpg_+SNJ8|Bd$HHZ;;)tZ^FyFBbbb@2sl?}f3FXG@QsUS;CThSpBFs4UOBOivbb zb8DNj69@X$n3h> zUA0;k;zIi(I08HAjC1N>UWv_~}8_ z?Ej~|^AE1-xbFBuH7t(2FI(>V!I%m(_ySw+?yFc!J&+dx_n<+nwFmv>>@`h_w#kA6OT1n|C z!LLdsoF4zbD_yFOOdju6x^xb=XOPSUa{NLr&SH-a0#Vz|s}0d&68=o*(!0iBTD#)g z6qe>P17%Bz;)hFYJ-9ZmZSrw9*vDV?8z&Rh(l1Xt%zKqB+wxD)rx(s|)qq&3avMYH z180b%Q(DFCC(L~W?!~90pzqxfWn_$}@>|2_NvESFxR3f{6Ki^T)iT6DS$UWZx8iK$ zX=@Br_GD?Bxc1C<4NGyd-Z};UGtd)IZ_UM80{9OgI~?MHwYVO5jf*!18LT__-sSde z)*_47wg!GlMwWx$K>T^o=ya{@rE7vr*I)Qfhs#6HLcw$_&4ciI?ny?r6n+)51yGeu zZt5R9Fzv$L4I0aG0bXtCTN&A#@NLLmgU*KDgunP!hhZaUq4C-`;kDT8HK^jreHmV3 z!2QseZy)?a$To#|y1ov6DRk=FrFbXcH2^;fjd|>ar|WS^kV)PHuTErBCf+)Da4xqB zDyMjj@bjR#OuTvUx}Tbi?9xAYT^6A+U&)$@cP=A44c~(7WQA-ovJ=Rp1Nm0?cIcuY zQ=0GmeTP%Y&OsGNvcvF?Lia-zmIdJ^c%eUQgACT`eYpqPhAcY08=oey2$|B8%fV}{ z>%5A1I$wuOdB{zj?QrX%m!Oi#zX7j4`xR&`Umv`7`Pm4K&r;7wHo+^9#cS)~=OU{K zGFW%YF}2rFr%n9c}^i3^Y3FPp-DERKAm(e;=~fps~zH;Xj4!FjVzTZVUV-=*Eof z@)fb1kR>hvJ|N@SCnc%$$iMb;0M)AeiNKL%|LGRaluyP=CJWDUp~ zkm)+TL$&Zf2S4?9rTe%DFI&mCGcwg*ePo}>$WFnpM)oRHWtMA$*H`TlXml#eIsy&I zQeE+$-iPeAjI0h`AGuS1TZ(r9{{6__%E(T_|1`2!GqQv5zldxyBO8U68FxQa@1*ix z0Sb^q?``5_o+_HD+XIzTV;PM0N@q^*jlG7qSVc$|<)Q{=?99(5UA&_>UlK z&B$(p{~)sZAk%wr@vl2rHG^$4RM$q??eOQ2MW<(Z2Z6I8p5&+DKLkA$;_2G`@Hu3A zgG_0T!q12HWn>%S^I*fS&z=#5!QsMi zuU5K0+go7nw9pe*_!4((kJB(hUw+Z%G0r6`Ek-A1pVHWxJe;&XoGeTHBzzNN;8FG) zu>Abox|8i|L5UTVTAal%$ljqaI#`GUoq{Zz3Tb4@5O4scHOzhknlHfeN`w!G;hjD? z6`Txr^cF_Up2BQ|6um&iWsLEM}CTmDJ@$uD2dzZEO^w{AsKIyc03$93h?qj{nm z&nC^s=9%90p89&n!`+~zr+W*{ElZayUDDjr-tl8(o94^hmt$$MJ&HKX>~%PkI>X$X z|G;u={Zo)3X<=}n;O#E_1{`q$R?kRKt{&)9gNjv}aUP|Ol@ z|FYbRuq>`@2@s^I^$r($$NigRd6^0IXm4Eap60_HX;Q;!AS(nDt3 z!?`@@3-35}P2ZeDJ7sS?+^kbAnDTV@_WRr6p0;l**oS8>KTXc0e5YNnee*`N!&pJa z7=`Tvg=hF$A#K}rjCRt4(}@S30|9MTKT?Jl6K)ismuQMBNx?viheY#C;ltfA?V5mX zBvc1AE&@Ol&F1eT2BNUHg0e?w=ltBh#Y?~O!*%}Koq&Btbj4l1@=1xcCdyvLRJN?q zPkkg|<|FYlA4!<_NaDmt;%7aQbkZYPWcTIwfGO=5M*bxoG^xy)xe6owOa33;DMb|KHyZe-(eou>PxaP8&Ve#uXXwR zhC53}(iYp#sSziiPQY~r<3e8*fdct#Gvi7VC_Rrm&{xk`?{ayou|wMVjEW<(YD(c@ zkMO=H;eAiy`#w_(sz-Q3O=V_Ice-EFC&!9aD8rYLErDzpEk788dJW&*3o){L)BR;@9V#`n- z2{stSQ^IK&Q+iV!D*scx1zt8oromhFo(01cYmt3BY#p_A#eH2PbU$Y1W4gX~)SB&h z4fU_fS!+l-!b6pwwYAgUJv~y*so7pn>AaufH>O4|i7KX=Y^%SqrYepv*TBdSGw$05 ze7~dfezu%C;tdXHaQ*v~8OB)M_jW4EE1D=Ixkj3bu*)0+5DXP^-54GCZRfn8DJ=)r zdm9JJqI`XN)V4Kj7KW3?Y-BU7YcO5*+T?8It2qehJIod*j3BdfxJqwYGB&0hsZ4<` zX<)G6&siH3=VmPp>r>Uk`W`iOqnWwm@T{70YGSOCX~(V7{3r8K0lZd&7OeHWZ1c3-Y7~qdc@SjSlb57(xJ{7&DvEW@b#qI_Vl~ATceRm8%yrX zh7=lHG+}>fHbO3+R+wo`gz1}j);@%$7pzKK-`L!FS)Uf)3Cq`ZM`djb2D)3jhI$LW z^4g0Qw{FWKTe>FpMAHZP)*#2z*EOd1X;ViHQ&!&_fauP&!wcE`57G|xzp}@(n=J44 zN|-SNP2KB^*C6-h)}Y%zV;kEH4#Y8y+T1d`6s5%@wLRCoa{C9K7BuQ5eyCplzN%61 z1CPAeoPo`y*EpB=(5${eeYg4JztW~#pWL!W!OanB7R+oAb5qi|vU%akmL*C1!cTLT z<@hgcd;BEzO;k9~8;Ow&`@_cZujwb+;F(Trp^1%mF-R+oufk$D+VFx9Mh()R?&g9N zhlJ0U0H024=$h?+iy1fQOF%Drv%Z*FDWp~_%38ck`D^eAMxzSJm(R?x z7>-GP5h)67Vv4H?zX^~h>*N^dV0YH>*fve&;GV^6mQb_i^4XQ@aYZ%a;Lhm z>c=v_pqdxrvx-F3P%o9o{TO!%QD59L&R_Eb{&ZO?w3RcZuXpI7Zy>KIV##ag4g(d)yTt=h)%Cvd$IPaU60-*Sq3+j%VG=8(eV%$8Wl0 zPq^X}953=i6T#iV>^Ae;vznb|s@-^tYtzPAI~N<8;+|ukG_&~HUN@7&xuY#YWVIJbNblnuPK zehdVOx%pdrK{9XR=Rk%*dcl+5KMHC=D?4u|XeM**AJ_r10jB)3+d*JRz>pVxid-pMZQcR6=Q(5herb6ud0RPPUufYyMoe54076$~P`4a5m-bpBJI zjo`^2?E@JGH@o|@pesC;hNnTT!CpSr4|)hb_wi2{TH)@w$51KPxW(;K`ZjhDvl&Y_ zW%?WlBv`_NanLYuhJ{-}{J<^v36&>>5#HAg;z?VvXaGcgu5-=LfG~ouwJb1%#4Wzp zkYcyQ-U(-ri;_2O+u+Ya+(0-&P@79_KCA^9|H8y zNuiRsHA@&wiV;eLdkmCsRLsxo9~*aq9Pfax11&xTUBB3Ots55c<1mDupjUhmdJR|n z)#AS5uNA*k{9r7M{2BZy{0aP*@rpAM zXg_olz7^kyugB|ru%fW_sxnZK-2?U{W_N}?iLH$l#kR%Pw_;NxyAoUfkKK&znSdRO ztqm8IOjPT9wVwjEF6lX?t7}EEwXr;87AM)QcLx=!JBcwMsr zuXs-c`YEW=|7E=L?#Ju=Gx!{S2rqk@VZ6$Ut&YW?fU3;91Kk7F`7hv=o=j4dj!aCN z@V_6zFGE$H<9Oxwhj_(%9k23z6R-2%#q0cSC`J0|=l$rxZ^m!Lqt{b9FNeL+Dd}78 zw=?_;@YoWW`;82LAj2Qb@RT);k10&bV-Az@*bv!s(!KA;|IzH_=B2I5qY;}de^j2C zDZC2%nRh$(qSMNwJpOK;Mm+TEN7r*?Q`qB5$84U$^&Ii~9J=`b?q;C?tf$a>$z8$r zNj`VeiAq-U?NnsDrAmU;KW%?M-kJsc4)sHI_D$$G^fl;C=yB+C(8JIv=t1aJ=ma#nyS~%zX7cg8$}Kl*c8yi7 z<5Y+(dv@-b@5SzG-}B7Nf8govuN0M)Yuhzp^cCX&)mP7dHRn%H`@j2&7qtcYr`H+3 zJ;eVr;(zPdg=4q7e?E5cSpM4S?|Rv;SWiQ;{`_ao=Un0ZXV14xkN@p+|5W@D27nEtnp=^Nb9+2Z=g5(RCa)dmRylp^k@^F&?VOmj@S$4|xk=;)Cal|^bBIQ4@|LSt3D4oeIrW^I zym{#60~4HzVT;et`Nc5V>3W6rkITz{t5oHg(3uLiPj}{vZD*`tKP*K$a0xyeR>Ilv zPvE?=h)(7E;pG@YX$nu2!n)7NEu}E0zkYS