Back to index

lightning-sunbird  0.9+nobinonly
BrowserFrameGlue.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: Mozilla-sample-code 1.0
00004  *
00005  * Copyright (c) 2002 Netscape Communications Corporation and
00006  * other contributors
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a
00009  * copy of this Mozilla sample software and associated documentation files
00010  * (the "Software"), to deal in the Software without restriction, including
00011  * without limitation the rights to use, copy, modify, merge, publish,
00012  * distribute, sublicense, and/or sell copies of the Software, and to permit
00013  * persons to whom the Software is furnished to do so, subject to the
00014  * following conditions:
00015  *
00016  * The above copyright notice and this permission notice shall be included
00017  * in all copies or substantial portions of the Software.
00018  *
00019  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00020  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00022  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00023  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00024  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00025  * DEALINGS IN THE SOFTWARE.
00026  *
00027  * Contributor(s):
00028  *   Chak Nanga <chak@netscape.com>
00029  *
00030  * ***** END LICENSE BLOCK ***** */
00031 
00032 // File Overview....
00033 //
00034 // This file has the IBrowserFrameGlueObj implementation
00035 // This frame glue object is nested inside of the BrowserFrame
00036 // object(See BrowserFrm.h for more info)
00037 //
00038 // This is the place where all the platform specific interaction
00039 // with the browser frame window takes place in response to 
00040 // callbacks from Gecko interface methods
00041 // 
00042 // The main purpose of this interface is to separate the cross 
00043 // platform code in BrowserImpl*.cpp from the platform specific
00044 // code(which is in this file)
00045 //
00046 // You'll also notice the use of a macro named "METHOD_PROLOGUE"
00047 // through out this file. This macro essentially makes the pointer
00048 // to a "containing" class available inside of the class which is
00049 // being contained via a var named "pThis". In our case, the 
00050 // BrowserFrameGlue object is contained inside of the BrowserFrame
00051 // object so "pThis" will be a pointer to a BrowserFrame object
00052 // Refer to MFC docs for more info on METHOD_PROLOGUE macro
00053 
00054 
00055 #include "stdafx.h"
00056 #include "MfcEmbed.h"
00057 #include "BrowserFrm.h"
00058 #include "Dialogs.h"
00059 
00061 // IBrowserFrameGlue implementation
00062 
00063 void CBrowserFrame::BrowserFrameGlueObj::UpdateStatusBarText(const PRUnichar *aMessage)
00064 {
00065     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00066     USES_CONVERSION;
00067     pThis->m_wndStatusBar.SetPaneText(0, aMessage ? W2CT(aMessage) : _T(""));
00068 }
00069 
00070 void CBrowserFrame::BrowserFrameGlueObj::UpdateProgress(PRInt32 aCurrent, PRInt32 aMax)
00071 {
00072     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00073 
00074     pThis->m_wndProgressBar.SetRange32(0, aMax);
00075     pThis->m_wndProgressBar.SetPos(aCurrent);
00076 }
00077 
00078 void CBrowserFrame::BrowserFrameGlueObj::UpdateBusyState(PRBool aBusy)
00079 {    
00080     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00081 
00082     // Just notify the view of the busy state
00083     // There's code in there which will take care of
00084     // updating the STOP toolbar btn. etc
00085 
00086     pThis->m_wndBrowserView.UpdateBusyState(aBusy);
00087 }
00088 
00089 // Called from the OnLocationChange() method in the nsIWebProgressListener 
00090 // interface implementation in CBrowserImpl to update the current URI
00091 // Will get called after a URI is successfully loaded in the browser
00092 // We use this info to update the URL bar's edit box
00093 //
00094 void CBrowserFrame::BrowserFrameGlueObj::UpdateCurrentURI(nsIURI *aLocation)
00095 {
00096     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00097 
00098     if(aLocation)
00099     {
00100         USES_CONVERSION;
00101         nsEmbedCString uriString;
00102         aLocation->GetSpec(uriString);
00103         pThis->m_wndUrlBar.SetCurrentURL(A2CT(uriString.get()));
00104     }
00105 }
00106 
00107 void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFrameTitle(PRUnichar **aTitle)
00108 {
00109     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00110 
00111     CString title;
00112     pThis->GetWindowText(title);
00113 
00114     if(!title.IsEmpty())
00115     {
00116         USES_CONVERSION;
00117         nsEmbedString nsTitle;
00118         nsTitle.Assign(T2CW(title.GetBuffer(0)));
00119         *aTitle = NS_StringCloneData(nsTitle);
00120     }
00121 }
00122 
00123 void CBrowserFrame::BrowserFrameGlueObj::SetBrowserFrameTitle(const PRUnichar *aTitle)
00124 {
00125     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00126 
00127     CString title;
00128     if (aTitle)
00129     {
00130         USES_CONVERSION;
00131         title = W2CT(aTitle);
00132     }
00133     else
00134     {
00135         // Use the AppName i.e. mfcembed as the title if we
00136         // do not get one from GetBrowserWindowTitle()
00137         //
00138         title.LoadString(AFX_IDS_APP_TITLE);
00139     }
00140     pThis->SetWindowText(title);
00141 }
00142 
00143 void CBrowserFrame::BrowserFrameGlueObj::SetBrowserFrameSize(PRInt32 aCX, PRInt32 aCY)
00144 {
00145     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00146     
00147     pThis->SetWindowPos(NULL, 0, 0, aCX, aCY, 
00148                 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER
00149             );
00150 }
00151 
00152 void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFrameSize(PRInt32 *aCX, PRInt32 *aCY)
00153 {
00154     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00155 
00156     RECT wndRect;
00157     pThis->GetWindowRect(&wndRect);
00158 
00159     if (aCX)
00160         *aCX = wndRect.right - wndRect.left;
00161 
00162     if (aCY)
00163         *aCY = wndRect.bottom - wndRect.top;
00164 }
00165 
00166 void CBrowserFrame::BrowserFrameGlueObj::SetBrowserFramePosition(PRInt32 aX, PRInt32 aY)
00167 {
00168     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)    
00169 
00170     pThis->SetWindowPos(NULL, aX, aY, 0, 0, 
00171                 SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
00172 }
00173 
00174 void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFramePosition(PRInt32 *aX, PRInt32 *aY)
00175 {
00176     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00177 
00178     RECT wndRect;
00179     pThis->GetWindowRect(&wndRect);
00180 
00181     if (aX)
00182         *aX = wndRect.left;
00183 
00184     if (aY)
00185         *aY = wndRect.top;
00186 }
00187 
00188 void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFramePositionAndSize(PRInt32 *aX, PRInt32 *aY, PRInt32 *aCX, PRInt32 *aCY)
00189 {
00190     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00191 
00192     RECT wndRect;
00193     pThis->GetWindowRect(&wndRect);
00194 
00195     if (aX)
00196         *aX = wndRect.left;
00197 
00198     if (aY)
00199         *aY = wndRect.top;
00200 
00201     if (aCX)
00202         *aCX = wndRect.right - wndRect.left;
00203 
00204     if (aCY)
00205         *aCY = wndRect.bottom - wndRect.top;
00206 }
00207 
00208 void CBrowserFrame::BrowserFrameGlueObj::SetBrowserFramePositionAndSize(PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY, PRBool fRepaint)
00209 {
00210     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00211 
00212     pThis->SetWindowPos(NULL, aX, aY, aCX, aCY, 
00213                 SWP_NOACTIVATE | SWP_NOZORDER);
00214 }
00215 
00216 void CBrowserFrame::BrowserFrameGlueObj::SetFocus()
00217 {
00218     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00219 
00220     pThis->SetFocus();
00221 }
00222 
00223 void CBrowserFrame::BrowserFrameGlueObj::FocusAvailable(PRBool *aFocusAvail)
00224 {
00225     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00226 
00227     HWND focusWnd = GetFocus()->m_hWnd;
00228 
00229     if ((focusWnd == pThis->m_hWnd) || ::IsChild(pThis->m_hWnd, focusWnd))
00230         *aFocusAvail = PR_TRUE;
00231     else
00232         *aFocusAvail = PR_FALSE;
00233 }
00234 
00235 void CBrowserFrame::BrowserFrameGlueObj::ShowBrowserFrame(PRBool aShow)
00236 {
00237     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00238 
00239     if(aShow)
00240     {
00241         pThis->ShowWindow(SW_SHOW);
00242         pThis->SetActiveWindow();
00243         pThis->UpdateWindow();
00244     }
00245     else
00246     {
00247         pThis->ShowWindow(SW_HIDE);
00248     }
00249 }
00250 
00251 void CBrowserFrame::BrowserFrameGlueObj::GetBrowserFrameVisibility(PRBool *aVisible)
00252 {
00253     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00254 
00255     // Is the current BrowserFrame the active one?
00256     if (GetActiveWindow()->m_hWnd != pThis->m_hWnd)
00257     {
00258         *aVisible = PR_FALSE;
00259         return;
00260     }
00261 
00262     // We're the active one
00263     //Return FALSE if we're minimized
00264     WINDOWPLACEMENT wpl;
00265     pThis->GetWindowPlacement(&wpl);
00266 
00267     if ((wpl.showCmd == SW_RESTORE) || (wpl.showCmd == SW_MAXIMIZE))
00268         *aVisible = PR_TRUE;
00269     else
00270         *aVisible = PR_FALSE;
00271 }
00272 
00273 PRBool CBrowserFrame::BrowserFrameGlueObj::CreateNewBrowserFrame(PRUint32 chromeMask, 
00274                             PRInt32 x, PRInt32 y, 
00275                             PRInt32 cx, PRInt32 cy,
00276                             nsIWebBrowser** aWebBrowser)
00277 {
00278    NS_ENSURE_ARG_POINTER(aWebBrowser);
00279 
00280    *aWebBrowser = nsnull;
00281 
00282     CMfcEmbedApp *pApp = (CMfcEmbedApp *)AfxGetApp();
00283     if(!pApp)
00284         return PR_FALSE;
00285 
00286     // Note that we're calling with the last param set to "false" i.e.
00287     // this instructs not to show the frame window
00288     // This is mainly needed when the window size is specified in the window.open()
00289     // JS call. In those cases Gecko calls us to create the browser with a default
00290     // size (all are -1) and then it calls the SizeBrowserTo() method to set
00291     // the proper window size. If this window were to be visible then you'll see
00292     // the window size changes on the screen causing an unappealing flicker
00293     //
00294 
00295     CBrowserFrame* pFrm = pApp->CreateNewBrowserFrame(chromeMask, x, y, cx, cy, PR_FALSE);
00296     if(!pFrm)
00297         return PR_FALSE;
00298 
00299     // At this stage we have a new CBrowserFrame and a new CBrowserView
00300     // objects. The CBrowserView also would have an embedded browser
00301     // object created. Get the mWebBrowser member from the CBrowserView
00302     // and return it. (See CBrowserView's CreateBrowser() on how the
00303     // embedded browser gets created and how it's mWebBrowser member
00304     // gets initialized)
00305 
00306     NS_IF_ADDREF(*aWebBrowser = pFrm->m_wndBrowserView.mWebBrowser);
00307 
00308     return PR_TRUE;
00309 }
00310 
00311 void CBrowserFrame::BrowserFrameGlueObj::DestroyBrowserFrame()
00312 {
00313     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00314 
00315     pThis->PostMessage(WM_CLOSE);
00316 }
00317 
00318 #define GOTO_BUILD_CTX_MENU { bContentHasFrames = FALSE; goto BUILD_CTX_MENU; }
00319 
00320 void CBrowserFrame::BrowserFrameGlueObj::ShowContextMenu(PRUint32 aContextFlags, nsIContextMenuInfo *aInfo)
00321 {
00322     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00323 
00324     BOOL bContentHasFrames = FALSE;
00325     UINT nIDResource = IDR_CTXMENU_DOCUMENT;
00326 
00327     // Reset the values from the last invocation
00328     // Clear image src & link url
00329     nsEmbedString empty;
00330     pThis->m_wndBrowserView.SetCtxMenuImageSrc(empty);  
00331     pThis->m_wndBrowserView.SetCtxMenuLinkUrl(empty);
00332     pThis->m_wndBrowserView.SetCurrentFrameURL(empty);
00333 
00334     // Display the Editor context menu if the we're inside
00335     // an EditorFrm which is hosting an editing session
00336     //
00337     if(pThis->GetEditable())
00338     {
00339         nIDResource = IDR_CTXMENU_EDITOR;
00340 
00341         GOTO_BUILD_CTX_MENU;
00342     }
00343 
00344     if(aContextFlags & nsIContextMenuListener2::CONTEXT_DOCUMENT)
00345     {
00346         nIDResource = IDR_CTXMENU_DOCUMENT;
00347 
00348         // Background image?
00349         if (aContextFlags & nsIContextMenuListener2::CONTEXT_BACKGROUND_IMAGE)
00350         {
00351             // Get the IMG SRC
00352             nsCOMPtr<nsIURI> imgURI;
00353             aInfo->GetBackgroundImageSrc(getter_AddRefs(imgURI));
00354             if (!imgURI)
00355                 return; 
00356             nsEmbedCString uri;
00357             imgURI->GetSpec(uri);
00358 
00359             nsEmbedString uri2;
00360             NS_CStringToUTF16(uri, NS_CSTRING_ENCODING_UTF8, uri2);
00361 
00362             pThis->m_wndBrowserView.SetCtxMenuImageSrc(uri2); // Set the new Img Src
00363         }
00364     }
00365     else if(aContextFlags & nsIContextMenuListener2::CONTEXT_TEXT)        
00366         nIDResource = IDR_CTXMENU_TEXT;
00367     else if(aContextFlags & nsIContextMenuListener2::CONTEXT_LINK)
00368     {
00369         nIDResource = IDR_CTXMENU_LINK;
00370 
00371         // Since we handle all the browser menu/toolbar commands
00372         // in the View, we basically setup the Link's URL in the
00373         // BrowserView object. When a menu selection in the context
00374         // menu is made, the appropriate command handler in the
00375         // BrowserView will be invoked and the value of the URL
00376         // will be accesible in the view
00377         
00378         nsEmbedString strUrlUcs2;
00379         nsresult rv = aInfo->GetAssociatedLink(strUrlUcs2);
00380         if(NS_FAILED(rv))
00381             return;
00382 
00383         // Update the view with the new LinkUrl
00384         // Note that this string is in UCS2 format
00385         pThis->m_wndBrowserView.SetCtxMenuLinkUrl(strUrlUcs2);
00386 
00387         // Test if there is an image URL as well
00388         nsCOMPtr<nsIURI> imgURI;
00389         aInfo->GetImageSrc(getter_AddRefs(imgURI));
00390         if(imgURI)
00391         {
00392             nsEmbedCString strImgSrcUtf8;
00393             imgURI->GetSpec(strImgSrcUtf8);
00394             if(strImgSrcUtf8.Length() != 0)
00395             {
00396                 // Set the new Img Src
00397                 nsEmbedString strImgSrc;
00398                 NS_CStringToUTF16(strImgSrcUtf8, NS_CSTRING_ENCODING_UTF8, strImgSrc);
00399                 pThis->m_wndBrowserView.SetCtxMenuImageSrc(strImgSrc);
00400             }
00401         }
00402     }
00403     else if(aContextFlags & nsIContextMenuListener2::CONTEXT_IMAGE)
00404     {
00405         nIDResource = IDR_CTXMENU_IMAGE;
00406 
00407         // Get the IMG SRC
00408         nsCOMPtr<nsIURI> imgURI;
00409         aInfo->GetImageSrc(getter_AddRefs(imgURI));
00410         if(!imgURI)
00411             return;
00412         nsEmbedCString strImgSrcUtf8;
00413         imgURI->GetSpec(strImgSrcUtf8);
00414         if(strImgSrcUtf8.Length() == 0)
00415             return;
00416 
00417         // Set the new Img Src
00418         nsEmbedString strImgSrc;
00419         NS_CStringToUTF16(strImgSrcUtf8, NS_CSTRING_ENCODING_UTF8, strImgSrc);
00420         pThis->m_wndBrowserView.SetCtxMenuImageSrc(strImgSrc);
00421     }
00422 
00423     // Determine if we need to add the Frame related context menu items
00424     // such as "View Frame Source" etc.
00425     //
00426     if(pThis->m_wndBrowserView.ViewContentContainsFrames())
00427     {
00428         bContentHasFrames = TRUE;
00429 
00430         //Determine the current Frame URL
00431         //
00432         nsresult rv = NS_OK;
00433         nsCOMPtr<nsIDOMNode> node;
00434         aInfo->GetTargetNode(getter_AddRefs(node));
00435         if(!node)
00436             GOTO_BUILD_CTX_MENU;
00437 
00438         nsCOMPtr<nsIDOMDocument> domDoc;
00439         rv = node->GetOwnerDocument(getter_AddRefs(domDoc));
00440         if(NS_FAILED(rv))
00441             GOTO_BUILD_CTX_MENU;
00442 
00443         nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(domDoc, &rv));
00444         if(NS_FAILED(rv))
00445             GOTO_BUILD_CTX_MENU;
00446 
00447         nsEmbedString strFrameURL;
00448         rv = htmlDoc->GetURL(strFrameURL);
00449         if(NS_FAILED(rv))
00450             GOTO_BUILD_CTX_MENU;
00451 
00452         pThis->m_wndBrowserView.SetCurrentFrameURL(strFrameURL); //Set it to the new URL
00453     }
00454 
00455 BUILD_CTX_MENU:
00456 
00457     CMenu ctxMenu;
00458     if(ctxMenu.LoadMenu(nIDResource))
00459     {
00460         //Append the Frame related menu items if content has frames
00461         if(bContentHasFrames) 
00462         {
00463             CMenu* pCtxMenu = ctxMenu.GetSubMenu(0);
00464             if(pCtxMenu)
00465             {
00466                 pCtxMenu->AppendMenu(MF_SEPARATOR);
00467 
00468                 CString strMenuItem;
00469                 strMenuItem.LoadString(IDS_VIEW_FRAME_SOURCE);
00470                 pCtxMenu->AppendMenu(MF_STRING, ID_VIEW_FRAME_SOURCE, strMenuItem);
00471 
00472                 strMenuItem.LoadString(IDS_OPEN_FRAME_IN_NEW_WINDOW);
00473                 pCtxMenu->AppendMenu(MF_STRING, ID_OPEN_FRAME_IN_NEW_WINDOW, strMenuItem);
00474             }
00475         }
00476 
00477         POINT cursorPos;
00478         GetCursorPos(&cursorPos);
00479 
00480         (ctxMenu.GetSubMenu(0))->TrackPopupMenu(TPM_LEFTALIGN, cursorPos.x, cursorPos.y, pThis);
00481     }
00482 }
00483 
00484 HWND CBrowserFrame::BrowserFrameGlueObj::GetBrowserFrameNativeWnd()
00485 {
00486     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00487     return pThis->m_hWnd;
00488 }
00489 
00490 void CBrowserFrame::BrowserFrameGlueObj::UpdateSecurityStatus(PRInt32 aState)
00491 {
00492     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00493 
00494     pThis->UpdateSecurityStatus(aState);
00495 }
00496 
00497 void CBrowserFrame::BrowserFrameGlueObj::ShowTooltip(PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText)
00498 {
00499     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00500     pThis->m_wndTooltip.SetTipText(CString(aTipText));
00501     pThis->m_wndTooltip.Show(&pThis->m_wndBrowserView, aXCoords, aYCoords);
00502 }
00503 
00504 void CBrowserFrame::BrowserFrameGlueObj::HideTooltip()
00505 {
00506     METHOD_PROLOGUE(CBrowserFrame, BrowserFrameGlueObj)
00507     pThis->m_wndTooltip.Hide();
00508 }