diff --git a/embedding/browser/powerplant/source/CFindComponent.cpp b/embedding/browser/powerplant/source/CFindComponent.cpp new file mode 100644 index 000000000000..1ebfd1b022d4 --- /dev/null +++ b/embedding/browser/powerplant/source/CFindComponent.cpp @@ -0,0 +1,648 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Contributor(s): + * Conrad Carlen + * Based on nsFindComponent.cpp by Pierre Phaneuf + * + */ + +#include "CFindComponent.h" + +#include "nsITextServicesDocument.h" +#include "nsIDocumentViewer.h" +#include "nsIDocument.h" +#include "nsIDOMDocument.h" +#include "nsIPresShell.h" +#include "nsTextServicesCID.h" +#include "nsCOMPtr.h" +#include "nsIComponentManager.h" +#include "nsIDocShell.h" +#include "nsIWordBreaker.h" + +static NS_DEFINE_CID(kCTextServicesDocumentCID, NS_TEXTSERVICESDOCUMENT_CID); + +// =========================================================================== +// CFindComponent +// =========================================================================== + +CFindComponent::CFindComponent() : + mLastCaseSensitive(FALSE), mLastSearchBackwards(FALSE), + mLastWrapSearch(TRUE), mLastEntireWord(FALSE), + mDocShell(NULL) +{ +} + + +CFindComponent::~CFindComponent() +{ + SetContext(nsnull); +} + + + // Call when the webshell content changes +NS_IMETHODIMP +CFindComponent::SetContext(nsIDocShell* aDocShell) +{ + if (aDocShell != mDocShell) + { + mDocShell = aDocShell; + mTextDoc = nsnull; + mWordBreaker = nsnull; + } + return NS_OK; +} + + + // Initiates a find - sets up the context +NS_IMETHODIMP +CFindComponent::Find(const nsString& searchString, + PRBool caseSensitive, + PRBool searchBackwards, + PRBool wrapSearch, + PRBool entireWord, + PRBool& didFind) +{ + NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED); + + nsAutoString matchString = searchString; + if (!caseSensitive) + matchString.ToLowerCase(); + + didFind = FALSE; + nsresult rv = NS_OK; + + + if (!mTextDoc) + { + rv = CreateTSDocument(mDocShell, getter_AddRefs(mTextDoc)); + if (NS_FAILED(rv) || !mTextDoc) + return rv; + } + + // Set up the TSDoc. We are going to start searching thus: + // + // Searching forwards: + // Look forward from the end of the selection + // Searching backwards: + // Look backwards from the start of the selection + // + PRInt32 selOffset = 0; + rv = SetupDocForSearch(mTextDoc, searchBackwards, &selOffset); + if (NS_FAILED(rv)) + return rv; + + // find out where we started + PRInt32 blockIndex; + rv = GetCurrentBlockIndex(mTextDoc, &blockIndex); + if (NS_FAILED(rv)) + return rv; + + // remember where we started + PRInt32 startingBlockIndex = blockIndex; + + // and set the starting position again (hopefully, in future we won't have to do this) + rv = SetupDocForSearch(mTextDoc, searchBackwards, &selOffset); + if (NS_FAILED(rv)) + return rv; + + nsIWordBreaker *wordBreaker = entireWord ? mWordBreaker.get() : nsnull; + + PRBool wrappedOnce = PR_FALSE; // Remember whether we've already wrapped + PRBool done = PR_FALSE; + + // Loop till we find a match or fail. + while ( !done ) + { + PRBool atExtremum = PR_FALSE; // are we at the end (or start) + + while ( NS_SUCCEEDED(mTextDoc->IsDone(&atExtremum)) && !atExtremum ) + { + nsString str; + rv = mTextDoc->GetCurrentTextBlock(&str); + + if (NS_FAILED(rv)) + return rv; + + if (!caseSensitive) + str.ToLowerCase(); + + PRInt32 foundOffset = FindInString(str, matchString, selOffset, searchBackwards, wordBreaker); + selOffset = -1; // reset for next block + + if (foundOffset != -1) + { + // Match found. Select it, remember where it was, and quit. + mTextDoc->SetSelection(foundOffset, searchString.Length()); + mTextDoc->ScrollSelectionIntoView(); + done = PR_TRUE; + didFind = PR_TRUE; + break; + } + else + { + // have we already been around once? + if (wrappedOnce && (blockIndex == startingBlockIndex)) + { + done = PR_TRUE; + break; + } + + // No match found in this block, try the next (or previous) one. + if (searchBackwards) { + mTextDoc->PrevBlock(); + blockIndex--; + } else { + mTextDoc->NextBlock(); + blockIndex++; + } + } + + } // while !atExtremum + + // At end (or matched). Decide which it was... + if (!done) + { + // Hit end without a match. If we haven't passed this way already, + // then reset to the first/last block (depending on search direction). + if (!wrappedOnce) + { + // Reset now. + wrappedOnce = PR_TRUE; + // If not wrapping, give up. + if ( !wrapSearch ) { + done = PR_TRUE; + } + else + { + if ( searchBackwards ) { + // Reset to last block. + rv = mTextDoc->LastBlock(); + // ugh + rv = GetCurrentBlockIndex(mTextDoc, &blockIndex); + rv = mTextDoc->LastBlock(); + } else { + // Reset to first block. + rv = mTextDoc->FirstBlock(); + blockIndex = 0; + } + } + } else + { + // already wrapped. This means no matches were found. + done = PR_TRUE; + } + } + } + + // Save the last params + mLastSearchString = searchString; + mLastCaseSensitive = caseSensitive; + mLastSearchBackwards = searchBackwards; + mLastWrapSearch = wrapSearch; + mLastEntireWord = entireWord; + + return NS_OK; +} + + +NS_IMETHODIMP +CFindComponent::CanFindNext(PRBool& canDo) +{ + canDo = (mTextDoc != nsnull); + return NS_OK; +} + + +NS_IMETHODIMP +CFindComponent::GetLastSearchString(nsString& searchString) +{ + searchString = mLastSearchString; + return NS_OK; +} + +NS_IMETHODIMP +CFindComponent::GetLastCaseSensitive(PRBool& caseSensitive) +{ + caseSensitive = mLastCaseSensitive; + return NS_OK; +} + + +NS_IMETHODIMP +CFindComponent::GetLastSearchBackwards(PRBool& searchBackwards) +{ + searchBackwards = mLastSearchBackwards; + return NS_OK; +} + +NS_IMETHODIMP +CFindComponent::GetLastWrapSearch(PRBool& wrapSearch) +{ + wrapSearch = mLastWrapSearch; + return NS_OK; +} + + +NS_IMETHODIMP +CFindComponent::GetLastEntireWord(PRBool& entireWord) +{ + entireWord = mLastEntireWord; + return NS_OK; +} + + + // Finds the next using the current context and params +NS_IMETHODIMP +CFindComponent::FindNext(PRBool& didFind) +{ + NS_ENSURE_TRUE(mDocShell, NS_ERROR_NULL_POINTER); + + Find(mLastSearchString, mLastCaseSensitive, mLastSearchBackwards, mLastWrapSearch, mLastEntireWord, didFind); + + return NS_OK; +} + + // Finds all occurrances from the top to bottom +NS_IMETHODIMP +CFindComponent::FindAll(const nsString& searchString, + PRBool caseSensitive, + PRInt32& numFound) +{ + NS_ENSURE_TRUE(mDocShell, NS_ERROR_NULL_POINTER); + + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +CFindComponent::SetFindStyle(CFHighlightStyle style) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +CFindComponent::CreateTSDocument(nsIDocShell* aDocShell, + nsITextServicesDocument** aDoc) +{ + if (!aDocShell) + return NS_ERROR_INVALID_ARG; + + if (!aDoc) + return NS_ERROR_NULL_POINTER; + + *aDoc = NULL; + + // Create the text services document. + nsCOMPtr tempDoc; + nsresult rv = nsComponentManager::CreateInstance(kCTextServicesDocumentCID, + nsnull, + NS_GET_IID(nsITextServicesDocument), + getter_AddRefs(tempDoc)); + if (NS_FAILED(rv) || !tempDoc) + return rv; + + // Get content viewer from the web shell. + nsCOMPtr contentViewer; + rv = aDocShell->GetContentViewer(getter_AddRefs(contentViewer)); + if (NS_FAILED(rv) || !contentViewer) + return rv; + + // Up-cast to a document viewer. + nsCOMPtr docViewer = do_QueryInterface(contentViewer, &rv); + if (NS_FAILED(rv) || !docViewer) + return rv; + + // Get the document and pres shell from the doc viewer. + nsCOMPtr document; + nsCOMPtr presShell; + rv = docViewer->GetDocument(*getter_AddRefs(document)); + if (document) + rv = docViewer->GetPresShell(*getter_AddRefs(presShell)); + + if (NS_FAILED(rv) || !document || !presShell) + return rv; + + // Get the word breaker used by the document + rv = document->GetWordBreaker(getter_AddRefs(mWordBreaker)); + if (NS_FAILED(rv) || !mWordBreaker) + return rv; + + // Upcast document to a DOM document. + nsCOMPtr domDoc = do_QueryInterface(document, &rv); + if (NS_FAILED(rv) || !domDoc) + return rv; + + // Initialize the text services document. + rv = tempDoc->InitWithDocument(domDoc, presShell); + if (NS_FAILED(rv)) + return rv; + + // Return the resulting text services document. + *aDoc = tempDoc; + NS_IF_ADDREF(*aDoc); + + return rv; +} + + +// utility method to discover which block we're in. The TSDoc interface doesn't give +// us this, because it can't assume a read-only document. +NS_IMETHODIMP +CFindComponent::GetCurrentBlockIndex(nsITextServicesDocument *aDoc, PRInt32 *outBlockIndex) +{ + PRInt32 blockIndex = 0; + PRBool isDone = PR_FALSE; + + while (NS_SUCCEEDED(aDoc->IsDone(&isDone)) && !isDone) + { + aDoc->PrevBlock(); + blockIndex ++; + } + + *outBlockIndex = blockIndex; + return NS_OK; +} + +NS_IMETHODIMP +CFindComponent::SetupDocForSearch(nsITextServicesDocument *aDoc, PRBool searchBackwards, PRInt32 *outBlockOffset) +{ + nsresult rv; + + nsITextServicesDocument::TSDBlockSelectionStatus blockStatus; + PRInt32 selOffset; + PRInt32 selLength; + + if (!searchBackwards) // searching forwards + { + rv = aDoc->LastSelectedBlock(&blockStatus, &selOffset, &selLength); + if (NS_SUCCEEDED(rv) && (blockStatus != nsITextServicesDocument::eBlockNotFound)) + { + switch (blockStatus) + { + case nsITextServicesDocument::eBlockOutside: // No TB in S, but found one before/after S. + case nsITextServicesDocument::eBlockPartial: // S begins or ends in TB but extends outside of TB. + // the TS doc points to the block we want. + *outBlockOffset = selOffset + selLength; + break; + + case nsITextServicesDocument::eBlockInside: // S extends beyond the start and end of TB. + // we want the block after this one. + rv = aDoc->NextBlock(); + *outBlockOffset = 0; + break; + + case nsITextServicesDocument::eBlockContains: // TB contains entire S. + *outBlockOffset = selOffset + selLength; + break; + + case nsITextServicesDocument::eBlockNotFound: // There is no text block (TB) in or before the selection (S). + default: + NS_NOTREACHED("Shouldn't ever get this status"); + } + + } + else //failed to get last sel block. Just start at beginning + { + rv = aDoc->FirstBlock(); + } + + } + else // searching backwards + { + rv = aDoc->FirstSelectedBlock(&blockStatus, &selOffset, &selLength); + if (NS_SUCCEEDED(rv) && (blockStatus != nsITextServicesDocument::eBlockNotFound)) + { + switch (blockStatus) + { + case nsITextServicesDocument::eBlockOutside: // No TB in S, but found one before/after S. + case nsITextServicesDocument::eBlockPartial: // S begins or ends in TB but extends outside of TB. + // the TS doc points to the block we want. + *outBlockOffset = selOffset; + break; + + case nsITextServicesDocument::eBlockInside: // S extends beyond the start and end of TB. + // we want the block before this one. + rv = aDoc->PrevBlock(); + *outBlockOffset = -1; + break; + + case nsITextServicesDocument::eBlockContains: // TB contains entire S. + *outBlockOffset = selOffset; + break; + + case nsITextServicesDocument::eBlockNotFound: // There is no text block (TB) in or before the selection (S). + default: + NS_NOTREACHED("Shouldn't ever get this status"); + } + } + else + { + rv = aDoc->LastBlock(); + } + } + + return rv; +} + + +// ---------------------------------------------------------------- +// CharsMatch +// +// Compare chars. Match if both are whitespace, or both are +// non whitespace and same char. +// ---------------------------------------------------------------- + +inline static PRBool CharsMatch(PRUnichar c1, PRUnichar c2) +{ + return (nsString::IsSpace(c1) && nsString::IsSpace(c2)) || + (c1 == c2); + +} + +// ---------------------------------------------------------------- +// FindInString +// +// Routine to search in an nsString which is smart about extra +// whitespace, can search backwards, and do case insensitive search. +// +// This uses a brute-force algorithm, which should be sufficient +// for our purposes (text searching) +// +// searchStr contains the text from a content node, which can contain +// extra white space between words, which we have to deal with. +// The offsets passed in and back are offsets into searchStr, +// and thus include extra white space. +// +// If we are ignoring case, the strings have already been lowercased +// at this point. +// +// If we are searching for entire words only, wordBreaker is non-NULL +// and is used to check whether the found string is an entire word. +// If wordBreaker is NULL, we are not searching for entire words only. +// +// startOffset is the offset in the search string to start seraching +// at. If -1, it means search from the start (forwards) or end (backwards). +// +// Returns -1 if the string is not found, or if the pattern is an +// empty string, or if startOffset is off the end of the string. +// ---------------------------------------------------------------- + +PRInt32 +CFindComponent::FindInString(const nsString &searchStr, const nsString &patternStr, + PRInt32 startOffset, PRBool searchBackwards, nsIWordBreaker* wordBreaker) +{ + PRInt32 foundOffset = -1; + PRInt32 patternLen = patternStr.Length(); + PRInt32 searchStrLen = searchStr.Length(); + PRBool goodMatch; + PRUint32 wordBegin, wordEnd; + + if (patternLen == 0) // pattern is empty + return -1; + + if (startOffset < 0) + startOffset = (searchBackwards) ? searchStrLen : 0; + + if (startOffset > searchStrLen) // bad start offset + return -1; + + if (patternLen > searchStrLen) // pattern is longer than string to search + return -1; + + if (!wordBreaker) + goodMatch = PR_TRUE; + + const PRUnichar *searchBuf = searchStr.GetUnicode(); + const PRUnichar *patternBuf = patternStr.GetUnicode(); + + const PRUnichar *searchEnd = searchBuf + searchStrLen; + const PRUnichar *patEnd = patternBuf + patternLen; + + if (searchBackwards) + { + // searching backwards + const PRUnichar *s = searchBuf + startOffset - patternLen - 1; + + while (s >= searchBuf) + { + if (CharsMatch(*patternBuf, *s)) // start potential match + { + const PRUnichar *t = s; + const PRUnichar *p = patternBuf; + PRInt32 curMatchOffset = t - searchBuf; + PRBool inWhitespace = nsString::IsSpace(*p); + + while (p < patEnd && CharsMatch(*p, *t)) + { + if (inWhitespace && !nsString::IsSpace(*p)) + { + // leaving p whitespace. Eat up addition whitespace in s + while (t < searchEnd - 1 && nsString::IsSpace(*(t + 1))) + t ++; + + inWhitespace = PR_FALSE; + } + else + inWhitespace = nsString::IsSpace(*p); + + t ++; + p ++; + } + + if (p == patEnd) + { + if (wordBreaker) + { + wordBreaker->FindWord(searchBuf, searchStrLen, curMatchOffset, &wordBegin, &wordEnd); + goodMatch = ((wordBegin == curMatchOffset) && (wordEnd - wordBegin == patternLen)); + } + + if (goodMatch) // always TRUE if wordBreaker == NULL + { + foundOffset = curMatchOffset; + goto done; + } + } + + // could be smart about decrementing s here + } + + s --; + } + + } + else + { + // searching forwards + + const PRUnichar *s = &searchBuf[startOffset]; + + while (s < searchEnd) + { + if (CharsMatch(*patternBuf, *s)) // start potential match + { + const PRUnichar *t = s; + const PRUnichar *p = patternBuf; + PRInt32 curMatchOffset = t - searchBuf; + PRBool inWhitespace = nsString::IsSpace(*p); + + while (p < patEnd && CharsMatch(*p, *t)) + { + if (inWhitespace && !nsString::IsSpace(*p)) + { + // leaving p whitespace. Eat up addition whitespace in s + while (t < searchEnd - 1 && nsString::IsSpace(*(t + 1))) + t ++; + + inWhitespace = PR_FALSE; + } + else + inWhitespace = nsString::IsSpace(*p); + + t ++; + p ++; + } + + if (p == patEnd) + { + if (wordBreaker) + { + wordBreaker->FindWord(searchBuf, searchStrLen, curMatchOffset, &wordBegin, &wordEnd); + goodMatch = ((wordBegin == curMatchOffset) && (wordEnd - wordBegin == patternLen)); + } + + if (goodMatch) // always TRUE if wordBreaker == NULL + { + foundOffset = curMatchOffset; + goto done; + } + } + + // could be smart about incrementing s here + } + + s ++; + } + + } + +done: + return foundOffset; +} diff --git a/embedding/browser/powerplant/source/CFindComponent.h b/embedding/browser/powerplant/source/CFindComponent.h new file mode 100644 index 000000000000..a5421bf8ceb5 --- /dev/null +++ b/embedding/browser/powerplant/source/CFindComponent.h @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Contributor(s): + * Conrad Carlen + * Based on nsFindComponent.cpp by Pierre Phaneuf + * + */ + +#ifndef __CFindComponent__ +#define __CFindComponent__ + +#include "nsISupports.h" +#include "nsString.h" +#include "nsComPtr.h" + +// Forward Declarations +class nsIDocShell; +class nsITextServicesDocument; +class nsIWordBreaker; + + /* + * CFindComponent is a class which, given a docshell and search params, + * does basic text searching. It will eventually be upgraded to a real + * component - for now it's just a class. + */ + +class CFindComponent +{ + public: + + enum CFHighlightStyle { + eStdSelect + }; + CFindComponent(); + virtual ~CFindComponent(); + + // Must be called initially! + // Call this whenever the docshell content changes + // Passing NULL is OK - clears current state + NS_IMETHOD SetContext(nsIDocShell* aDocShell); + + + // Initiates a find in the current context + NS_IMETHOD Find(const nsString& searchStr, + PRBool caseSensitive, + PRBool searchBackward, + PRBool wrapSearch, + PRBool wholeWordOnly, + PRBool& didFind); + + // Returns whether we can do FindNext + NS_IMETHOD CanFindNext(PRBool& canDo); + + // Returns the params to the last find + // If there was none, searchStr is empty and others are default + NS_IMETHOD GetLastSearchString(nsString& searchString); + NS_IMETHOD GetLastCaseSensitive(PRBool& caseSensitive); + NS_IMETHOD GetLastSearchBackwards(PRBool& searchBackward); + NS_IMETHOD GetLastWrapSearch(PRBool& wrapSearch); + NS_IMETHOD GetLastEntireWord(PRBool& entireWord); + + // Finds the next using the params last given to Find + NS_IMETHOD FindNext(PRBool& didFind); + + // Finds all occurrances from the top to bottom + NS_IMETHOD FindAll(const nsString& searchStr, + PRBool caseSensitive, + PRInt32& numFound); + + + // How we highlight found text + // The default is to select it + NS_IMETHOD SetFindStyle(CFHighlightStyle style); + + + protected: + nsString mLastSearchString; + PRBool mLastCaseSensitive, mLastSearchBackwards, mLastWrapSearch, mLastEntireWord; + + nsIDocShell *mDocShell; + nsCOMPtr mTextDoc; + nsCOMPtr mWordBreaker; + + protected: + NS_IMETHOD CreateTSDocument(nsIDocShell* aWebShell, nsITextServicesDocument** aDoc); + NS_IMETHOD GetCurrentBlockIndex(nsITextServicesDocument *aDoc, PRInt32 *outBlockIndex); + NS_IMETHOD SetupDocForSearch(nsITextServicesDocument *aDoc, PRBool searchBackwards, PRInt32 *outBlockOffset); + + static PRInt32 FindInString(const nsString &searchStr, const nsString &patternStr, + PRInt32 startOffset, PRBool searchBackwards, + nsIWordBreaker* wordBreaker); + +}; + +#endif // __CFindComponent__ diff --git a/embedding/browser/powerplant/source/CThrobber.cpp b/embedding/browser/powerplant/source/CThrobber.cpp new file mode 100644 index 000000000000..222c0461bb0b --- /dev/null +++ b/embedding/browser/powerplant/source/CThrobber.cpp @@ -0,0 +1,419 @@ +/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Contributor(s): + * Conrad Carlen + */ + +#include "CThrobber.h" +#include "CBrowserWindow.h" + +#include "nsIWidget.h" +#include "nsWidgetsCID.h" +#include "nsIComponentManager.h" +#include "nsComponentManagerUtils.h" +#include "nsIImageGroup.h" +#include "nsIDeviceContext.h" +#include "nsITimer.h" +#include "nsIImageRequest.h" +#include "nsFont.h" +#include "nsIFontMetrics.h" +#include "prprf.h" + +// CIDs +static NS_DEFINE_IID(kChildCID, NS_CHILD_CID); +static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +// Static variables +map CThrobber::mgThrobberMap; + +// Constants +const PRUint32 kThrobFrequency = 66; // animation frequency in milliseconds + +//***************************************************************************** +//*** CThrobber: constructors/destructor +//***************************************************************************** + +CThrobber::CThrobber() : + mImages(nsnull), + mNumImages(0), mCompletedImages(0), mIndex(0), mRunning(false), + mImageGroup(nsnull), mTimer(nsnull) +{ + NS_INIT_REFCNT(); // caller must add ref as normal + + AddThrobber(this); +} + + +CThrobber::CThrobber(LStream* inStream) : + LView(inStream), + mImages(nsnull), + mNumImages(0), mCompletedImages(0), mIndex(0), mRunning(false), + mImageGroup(nsnull), mTimer(nsnull) +{ + mRefCnt = 1; // PowerPlant is making us, and it sure isn't going to do an AddRef. + + LStr255 tempStr; + *inStream >> (StringPtr) tempStr; + *inStream >> mNumImages; + mFileNamePattern.SetString((char *)&tempStr[1], (PRInt32)tempStr.Length()); +} + + +CThrobber::~CThrobber() +{ + if (mWidget) + mWidget->Destroy(); + DestroyImages(); + RemoveThrobber(this); +} + +NS_IMPL_ISUPPORTS(CThrobber, kIImageObserverIID) + +void CThrobber::Notify(nsIImageRequest *aImageRequest, + nsIImage *aImage, + nsImageNotification aNotificationType, + PRInt32 aParam1, PRInt32 aParam2, + void *aParam3) +{ + if (aNotificationType == nsImageNotification_kImageComplete) + { + mCompletedImages++; + + // Remove ourselves as an observer of the image request object, because + // the image request objects each hold a reference to us. This avoids a + // circular reference problem. If we don't, our ref count will never reach + // 0 and we won't get destroyed and neither will the image request objects + + aImageRequest->RemoveObserver((nsIImageRequestObserver*)this); + } +} + +void CThrobber::NotifyError(nsIImageRequest *aImageRequest, + nsImageError aErrorType) +{ +} + + +void CThrobber::FinishCreateSelf() +{ + CBrowserWindow *ourWindow = dynamic_cast(LWindow::FetchWindowObject(GetMacPort())); + ThrowIfNil_(ourWindow); + + // Get the widget from the browser window + nsCOMPtr parentWidget; + ourWindow->GetWidget(getter_AddRefs(parentWidget)); + ThrowIfNil_(parentWidget); + + FocusDraw(); + + Rect portFrame; + CalcPortFrameRect(portFrame); + nsRect r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top); + + // Create widget + nsresult rv; + + mWidget = do_CreateInstance(kChildCID, &rv); + if (!mWidget) + Throw_(NS_ERROR_GET_CODE(rv)); + mWidget->Create(parentWidget, r, HandleThrobberEvent, NULL); + + rv = LoadImages(mFileNamePattern, mNumImages); + if (NS_SUCCEEDED(rv)) + AddThrobber(this); +} + + +void CThrobber::ShowSelf() +{ + mWidget->Show(PR_TRUE); +} + + +void CThrobber::HideSelf() +{ + mWidget->Show(PR_FALSE); +} + + +void CThrobber::DrawSelf() +{ + // Draw directly with the rendering context instead of passing an + // update event through nsMacMessageSink. By the time this routine is + // called, PowerPlant has taken care of the location, z order, and clipping + // of each view. Since focusing puts the the origin at our top left corner, + // all we have to do is get the bounds of the widget and put that at (0,0) + + nsIRenderingContext *cx = mWidget->GetRenderingContext(); + nsRect bounds; + nsIImageRequest *imgreq; + nsIImage *img; + PRBool clipState; + + mWidget->GetClientBounds(bounds); + bounds.x = bounds.y = 0; + + //cx->SetClipRect(bounds, nsClipCombine_kReplace, clipState); + + cx->SetColor(NS_RGB(255, 255, 255)); + cx->DrawLine(0, bounds.height - 1, 0, 0); + cx->DrawLine(0, 0, bounds.width, 0); + + cx->SetColor(NS_RGB(128, 128, 128)); + cx->DrawLine(bounds.width - 1, 1, bounds.width - 1, bounds.height - 1); + cx->DrawLine(bounds.width - 1, bounds.height - 1, 0, bounds.height - 1); + + imgreq = (*mImages)[mIndex]; + + if ((nsnull == imgreq) || (nsnull == (img = imgreq->GetImage()))) + { + char str[10]; + nsFont tfont = nsFont("monospace", 0, 0, 0, 0, 10); + nsIFontMetrics *met; + nscoord w, h; + + cx->SetColor(NS_RGB(0, 0, 0)); + cx->FillRect(1, 1, bounds.width - 2, bounds.height - 2); + + PR_snprintf(str, sizeof(str), "%02d", mIndex); + + cx->SetColor(NS_RGB(255, 255, 255)); + cx->SetFont(tfont); + cx->GetFontMetrics(met); + if (nsnull != met) + { + cx->GetWidth(str, w); + met->GetHeight(h); + cx->DrawString(str, PRUint32(2), (bounds.width - w) >> 1, (bounds.height - h) >> 1); + NS_RELEASE(met); + } + } + else + { + cx->DrawImage(img, 1, 1); + NS_RELEASE(img); + } +} + + +void CThrobber::AdjustCursorSelf(Point /* inPortPt */, + const EventRecord& /* inMacEvent */) +{ + // Overridden to do nothing - Cursor handling is done by HandleThrobberEvent +} + + +void CThrobber::ResizeFrameBy(SInt16 inWidthDelta, + SInt16 inHeightDelta, + Boolean inRefresh) +{ + LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh); + AdjustFrame(inRefresh); +} + + +void CThrobber::MoveBy(SInt32 inHorizDelta, + SInt32 inVertDelta, + Boolean inRefresh) +{ + LView::MoveBy(inHorizDelta, inVertDelta, inRefresh); + AdjustFrame(inRefresh); +} + + +void CThrobber::Start() +{ + mRunning = true; +} + + +void CThrobber::Stop() +{ + mRunning = false; +} + + +void CThrobber::AdjustFrame(Boolean inRefresh) +{ + FocusDraw(); + + Rect portFrame; + CalcPortFrameRect(portFrame); + nsRect r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top); + + mWidget->Resize(r.x, r.y, r.width, r.height, inRefresh); +} + + +NS_METHOD CThrobber::LoadImages(const nsString& aFileNameMask, PRInt32 aNumImages) +{ + nsresult rv; + char url[2000]; + + mImages = new vector(mNumImages); + if (nsnull == mImages) { + return NS_ERROR_OUT_OF_MEMORY; + } + rv = NS_NewImageGroup(&mImageGroup); + if (NS_OK != rv) { + return rv; + } + + nsIDeviceContext *deviceCtx = mWidget->GetDeviceContext(); + mImageGroup->Init(deviceCtx, nsnull); + NS_RELEASE(deviceCtx); + + rv = NS_NewTimer(&mTimer); + if (NS_OK != rv) { + return rv; + } + mTimer->Init(ThrobTimerCallback, this, kThrobFrequency, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK); + + char * mask = aFileNameMask.ToNewCString(); + for (PRInt32 cnt = 0; cnt < mNumImages; cnt++) + { + PR_snprintf(url, sizeof(url), mask, cnt); + nscolor bgcolor = NS_RGB(0, 0, 0); + (*mImages)[cnt] = mImageGroup->GetImage(url, + (nsIImageRequestObserver *)this, + &bgcolor, + mFrameSize.width - 2, + mFrameSize.height - 2, 0); + } + + if (nsnull != mask) + nsAllocator::Free(mask); + + mWidget->Invalidate(PR_TRUE); + + return rv; +} + +void CThrobber::DestroyImages() +{ + if (mTimer) + { + mTimer->Cancel(); + NS_RELEASE(mTimer); + } + + if (mImageGroup) + { + mImageGroup->Interrupt(); + + for (vector::iterator iter = mImages->begin(); iter < mImages->end(); ++iter) + { + NS_IF_RELEASE(*iter); + } + NS_RELEASE(mImageGroup); + } + + if (mImages) + { + delete mImages; + mImages = nsnull; + } +} + +void CThrobber::Tick() +{ + if (mRunning) { + mIndex++; + if (mIndex >= mNumImages) + mIndex = 0; + FocusDraw(); + mWidget->Invalidate(PR_TRUE); + } else if (mCompletedImages == (PRUint32)mNumImages) { + FocusDraw(); + mWidget->Invalidate(PR_TRUE); + mCompletedImages = 0; + } + +#ifndef REPEATING_TIMERS + NS_RELEASE(mTimer); + + nsresult rv = NS_NewTimer(&mTimer); + if (NS_OK == rv) { + mTimer->Init(ThrobTimerCallback, this, kThrobFrequency); + } +#endif +} + + + +CThrobber* CThrobber::FindThrobberForWidget(nsIWidget* aWidget) +{ + map::iterator iter = mgThrobberMap.find(aWidget); + if (iter == mgThrobberMap.end()) + return nsnull; + else + return iter->second; +} + + +void CThrobber::AddThrobber(CThrobber* aThrobber) +{ + pair entry(aThrobber->mWidget, aThrobber); + mgThrobberMap[aThrobber->mWidget] = aThrobber; +} + + +void CThrobber::RemoveThrobber(CThrobber* aThrobber) +{ + map::iterator iter = mgThrobberMap.find(aThrobber->mWidget); + if (iter != mgThrobberMap.end()) + mgThrobberMap.erase(iter); +} + + +nsEventStatus PR_CALLBACK CThrobber::HandleThrobberEvent(nsGUIEvent *aEvent) +{ + CThrobber* throbber = FindThrobberForWidget(aEvent->widget); + if (nsnull == throbber) { + return nsEventStatus_eIgnore; + } + + switch (aEvent->message) + { + case NS_PAINT: + break; + + case NS_MOUSE_LEFT_BUTTON_UP: + // Broadcast a message + break; + + case NS_MOUSE_ENTER: + aEvent->widget->SetCursor(eCursor_hyperlink); + break; + + case NS_MOUSE_EXIT: + aEvent->widget->SetCursor(eCursor_standard); + break; + } + + return nsEventStatus_eIgnore; +} + + +void CThrobber::ThrobTimerCallback(nsITimer *aTimer, void *aClosure) +{ + CThrobber* throbber = (CThrobber*)aClosure; + throbber->Tick(); +} diff --git a/embedding/browser/powerplant/source/CThrobber.h b/embedding/browser/powerplant/source/CThrobber.h new file mode 100644 index 000000000000..b952f0bbe5d5 --- /dev/null +++ b/embedding/browser/powerplant/source/CThrobber.h @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Contributor(s): + * Conrad Carlen + */ + +#ifndef __CThrobber__ +#define __CThrobber__ + +#ifndef nsError_h +#include "nsError.h" +#endif + +#ifndef nsCOMPtr_h___ +#include "nsCOMPtr.h" +#endif + +#ifndef nsGUIEvent_h__ +#include "nsGUIEvent.h" +#endif + +#include "nsString.h" +#include "nsIImageObserver.h" + +#include +#include +using namespace std; + +class nsIWidget; +class nsIImageGroup; +class nsITimer; +class nsIImageRequest; + +class CThrobber : public LView, + public nsIImageRequestObserver +{ +public: + enum { class_ID = FOUR_CHAR_CODE('Thrb') }; + + CThrobber(); + CThrobber(LStream* inStream); + + virtual ~CThrobber(); + + NS_DECL_ISUPPORTS + + // nsIImageRequestObserver + virtual void Notify(nsIImageRequest *aImageRequest, + nsIImage *aImage, + nsImageNotification aNotificationType, + PRInt32 aParam1, PRInt32 aParam2, + void *aParam3); + + virtual void NotifyError(nsIImageRequest *aImageRequest, + nsImageError aErrorType); + + // CThrobber + virtual void FinishCreateSelf(); + virtual void ShowSelf(); + virtual void HideSelf(); + virtual void DrawSelf(); + virtual void AdjustCursorSelf(Point inPortPt, + const EventRecord& inMacEvent); + + void ResizeFrameBy(SInt16 inWidthDelta, + SInt16 inHeightDelta, + Boolean inRefresh); + void MoveBy(SInt32 inHorizDelta, + SInt32 inVertDelta, + Boolean inRefresh); + + virtual void Start(); + virtual void Stop(); + protected: + + void AdjustFrame(Boolean inRefresh); + nsresult LoadImages(const nsString& aFileNameMask, PRInt32 aNumImages); + void DestroyImages(); + void Tick(); + + nsString mFileNamePattern; + nsCOMPtr mWidget; + vector *mImages; + bool mRunning; + SInt32 mNumImages, mCompletedImages, mIndex; + nsIImageGroup *mImageGroup; + nsITimer *mTimer; + + static map mgThrobberMap; + + static CThrobber* FindThrobberForWidget(nsIWidget* aWidget); + static void AddThrobber(CThrobber* aThrobber); + static void RemoveThrobber(CThrobber* aThrobber); + static nsEventStatus PR_CALLBACK HandleThrobberEvent(nsGUIEvent *aEvent); + static void ThrobTimerCallback(nsITimer *aTimer, void *aClosure); + +}; + + +#endif diff --git a/embedding/browser/powerplant/source/CUrlField.cp b/embedding/browser/powerplant/source/CUrlField.cp new file mode 100644 index 000000000000..699212c22b0c --- /dev/null +++ b/embedding/browser/powerplant/source/CUrlField.cp @@ -0,0 +1,84 @@ + +#include "CUrlField.h" +#include + + +// CUrlField: +// A text edit field that broadcasts its PaneID on Return or Enter. + + + + +// --------------------------------------------------------------------------- +// ¥ CUrlField Default Constructor [public] +// --------------------------------------------------------------------------- + +CUrlField::CUrlField() +{ +} + + + +// --------------------------------------------------------------------------- +// ¥ CUrlField Stream Constructor [public] +// --------------------------------------------------------------------------- + +CUrlField::CUrlField(LStream* inStream) + : LEditText(inStream) +{ +} + + +// --------------------------------------------------------------------------- +// ¥ ~CUrlField Destructor [public] +// --------------------------------------------------------------------------- + +CUrlField::~CUrlField() +{ +} + + +// --------------------------------------------------------------------------- +// ¥ HandleKeyPress +// --------------------------------------------------------------------------- +// Broadcast the paneID when the user hits Return or Enter + +Boolean +CUrlField::HandleKeyPress(const EventRecord &inKeyEvent) +{ + Boolean keyHandled = true; + Char16 theChar = (Char16) (inKeyEvent.message & charCodeMask); + + if (theChar == char_Return || theChar == char_Enter) + { + Str255 urlString; + BroadcastMessage(GetPaneID(), (void*)GetDescriptor(urlString)); + } + else + keyHandled = Inherited::HandleKeyPress(inKeyEvent); + + return keyHandled; +} + + +// --------------------------------------------------------------------------- +// ¥ ClickSelf +// --------------------------------------------------------------------------- +// Select everything when a single click gives us the focus + +void +CUrlField::ClickSelf(const SMouseDownEvent &inMouseDown) +{ + Boolean wasTarget = IsTarget(); + + Inherited::ClickSelf(inMouseDown); + + if (!wasTarget) + { + ControlEditTextSelectionRec selection; + GetSelection(selection); + if (selection.selStart == selection.selEnd) + SelectAll(); + } +} + diff --git a/embedding/browser/powerplant/source/CUrlField.h b/embedding/browser/powerplant/source/CUrlField.h new file mode 100644 index 000000000000..ac0bba12756d --- /dev/null +++ b/embedding/browser/powerplant/source/CUrlField.h @@ -0,0 +1,29 @@ + +#include + + +// CUrlField: +// A text edit field that broadcasts its PaneID on Return or Enter. + + + +class CUrlField : public LEditText +{ +private: + typedef LEditText Inherited; + +public: + enum { class_ID = FOUR_CHAR_CODE('UrlF') }; + + + CUrlField(); + CUrlField(LStream* inStream); + + virtual ~CUrlField(); + + virtual Boolean HandleKeyPress( + const EventRecord &inKeyEvent); + + virtual void ClickSelf( + const SMouseDownEvent &inMouseDown); +}; diff --git a/embedding/browser/powerplant/source/CWebBrowserChrome.cpp b/embedding/browser/powerplant/source/CWebBrowserChrome.cpp new file mode 100644 index 000000000000..ca464a37e7ac --- /dev/null +++ b/embedding/browser/powerplant/source/CWebBrowserChrome.cpp @@ -0,0 +1,446 @@ +/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Contributor(s): + * Travis Bogard + * Conrad Carlen + */ + +// Local Includes +#include "CWebBrowserChrome.h" +#include "CBrowserWindow.h" + +#include "nsIGenericFactory.h" +#include "nsString.h" +#include "nsXPIDLString.h" +#include "nsIURI.h" +#include "nsIWebProgress.h" + +#include "UMacUnicode.h" + +// Interfaces needed to be included + +// CIDs + +//***************************************************************************** +//*** CWebBrowserChrome: Object Management +//***************************************************************************** + +CWebBrowserChrome::CWebBrowserChrome() : mBrowserWindow(nsnull) +{ + NS_INIT_REFCNT(); +} + +CWebBrowserChrome::~CWebBrowserChrome() +{ +} + +//***************************************************************************** +// CWebBrowserChrome::nsISupports +//***************************************************************************** + +NS_IMPL_ADDREF(CWebBrowserChrome) +NS_IMPL_RELEASE(CWebBrowserChrome) + +NS_INTERFACE_MAP_BEGIN(CWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY(nsIDocumentLoaderObserver) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) + NS_INTERFACE_MAP_ENTRY(nsIBaseWindow) +NS_INTERFACE_MAP_END + +//***************************************************************************** +// CWebBrowserChrome::nsIInterfaceRequestor +//***************************************************************************** + +NS_IMETHODIMP CWebBrowserChrome::GetInterface(const nsIID &aIID, void** aInstancePtr) +{ + return QueryInterface(aIID, aInstancePtr); +} + +//***************************************************************************** +// CWebBrowserChrome::nsIWebBrowserChrome +//***************************************************************************** + +NS_IMETHODIMP CWebBrowserChrome::SetJSStatus(const PRUnichar* aStatus) +{ + NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED); + + mBrowserWindow->SetStatus(aStatus); + + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetJSDefaultStatus(const PRUnichar* aStatus) +{ + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetOverLink(const PRUnichar* aLink) +{ + NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED); + + mBrowserWindow->SetOverLink(aLink); + + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::GetWebBrowser(nsIWebBrowser** aWebBrowser) +{ + NS_ERROR("Haven't Implemented this yet"); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP CWebBrowserChrome::SetWebBrowser(nsIWebBrowser* aWebBrowser) +{ + NS_ERROR("Haven't Implemented this yet"); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP CWebBrowserChrome::GetChromeMask(PRUint32* aChromeMask) +{ + NS_ERROR("Haven't Implemented this yet"); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP CWebBrowserChrome::SetChromeMask(PRUint32 aChromeMask) +{ + NS_ERROR("Haven't Implemented this yet"); + return NS_ERROR_FAILURE; +} + + +NS_IMETHODIMP CWebBrowserChrome::GetNewBrowser(PRUint32 chromeMask, nsIWebBrowser **webBrowser) +{ + NS_ERROR("Haven't Implemented this yet"); + return NS_ERROR_FAILURE; +} + + +NS_IMETHODIMP CWebBrowserChrome::FindNamedBrowserItem(const PRUnichar* aName, + nsIDocShellTreeItem ** aWebBrowser) +{ + NS_ERROR("Haven't Implemented this yet"); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP CWebBrowserChrome::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY) +{ + NS_ERROR("Haven't Implemented this yet"); + return NS_ERROR_FAILURE; +} + + +NS_IMETHODIMP CWebBrowserChrome::ShowAsModal(void) +{ + NS_ERROR("Haven't Implemented this yet"); + return NS_ERROR_FAILURE; +} + + +//***************************************************************************** +// CWebBrowserChrome::nsIDocumentLoaderObserver +//***************************************************************************** + +NS_IMETHODIMP CWebBrowserChrome::OnStartDocumentLoad(nsIDocumentLoader *aLoader, nsIURI *aURL, const char *aCommand) +{ + NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED); + return mBrowserWindow->BeginDocumentLoad(aLoader, aURL, aCommand); +} + +NS_IMETHODIMP CWebBrowserChrome::OnEndDocumentLoad(nsIDocumentLoader *aLoader, nsIChannel *aChannel, PRUint32 aStatus) +{ + NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED); + return mBrowserWindow->EndDocumentLoad(aLoader, aChannel, aStatus); +} + +NS_IMETHODIMP CWebBrowserChrome::OnStartURLLoad(nsIDocumentLoader *aLoader, nsIChannel *channel) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP CWebBrowserChrome::OnProgressURLLoad(nsIDocumentLoader *aLoader, nsIChannel *aChannel, PRUint32 aProgress, PRUint32 aProgressMax) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP CWebBrowserChrome::OnStatusURLLoad(nsIDocumentLoader *loader, nsIChannel *channel, nsString & aMsg) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP CWebBrowserChrome::OnEndURLLoad(nsIDocumentLoader *aLoader, nsIChannel *aChannel, PRUint32 aStatus) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + + +//***************************************************************************** +// CWebBrowserChrome::nsIWebProgressListener +//***************************************************************************** + +NS_IMETHODIMP CWebBrowserChrome::OnProgressChange(nsIChannel *channel, PRInt32 curSelfProgress, PRInt32 maxSelfProgress, PRInt32 curTotalProgress, PRInt32 maxTotalProgress) +{ + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::OnChildProgressChange(nsIChannel *channel, PRInt32 curSelfProgress, PRInt32 curTotalProgress) +{ + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::OnStatusChange(nsIChannel *channel, PRInt32 progressStatusFlags) +{ + NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED); + + switch (progressStatusFlags) + { + case nsIWebProgress::flag_net_start: + mBrowserWindow->OnStatusNetStart(channel); + break; + case nsIWebProgress::flag_net_stop: + mBrowserWindow->OnStatusNetStop(channel); + break; + case nsIWebProgress::flag_net_dns: + mBrowserWindow->OnStatusDNS(channel); + break; + } + + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::OnChildStatusChange(nsIChannel *channel, PRInt32 progressStatusFlags) +{ + return NS_OK; +} + + +NS_IMETHODIMP CWebBrowserChrome::OnLocationChange(nsIURI *location) +{ + NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED); + + nsXPIDLCString spec; + + if (location) + location->GetSpec(getter_Copies(spec)); + + nsAutoString tmp(spec); + mBrowserWindow->SetLocation(tmp); + + return NS_OK; +} + + +//***************************************************************************** +// CWebBrowserChrome::nsIBaseWindow +//***************************************************************************** + +NS_IMETHODIMP CWebBrowserChrome::InitWindow(nativeWindow aParentNativeWindow, + nsIWidget* parentWidget, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy) +{ + // Ignore wigdet parents for now. Don't think those are a vaild thing to call. + NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, PR_FALSE), NS_ERROR_FAILURE); + + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::Create() +{ + NS_ASSERTION(PR_FALSE, "You can't call this"); + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP CWebBrowserChrome::Destroy() +{ + NS_ASSERTION(PR_FALSE, "You can't call this"); + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP CWebBrowserChrome::SetPosition(PRInt32 x, PRInt32 y) +{ + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::GetPosition(PRInt32* x, PRInt32* y) +{ + NS_ENSURE_ARG_POINTER(x && y); + + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetSize(PRInt32 cx, PRInt32 cy, PRBool fRepaint) +{ + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::GetSize(PRInt32* cx, PRInt32* cy) +{ + NS_ENSURE_ARG_POINTER(cx && cy); + + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetPositionAndSize(PRInt32 x, PRInt32 y, PRInt32 cx, + PRInt32 cy, PRBool fRepaint) +{ + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::GetPositionAndSize(PRInt32* x, PRInt32* y, PRInt32* cx, + PRInt32* cy) +{ + + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::Repaint(PRBool aForce) +{ + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::GetParentWidget(nsIWidget** aParentWidget) +{ + NS_ENSURE_ARG_POINTER(aParentWidget); + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetParentWidget(nsIWidget* aParentWidget) +{ + NS_ASSERTION(PR_FALSE, "You can't call this"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP CWebBrowserChrome::GetParentNativeWindow(nativeWindow* aParentNativeWindow) +{ + NS_ENSURE_ARG_POINTER(aParentNativeWindow); + + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetParentNativeWindow(nativeWindow aParentNativeWindow) +{ + NS_ASSERTION(PR_FALSE, "You can't call this"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP CWebBrowserChrome::GetVisibility(PRBool* aVisibility) +{ + NS_ENSURE_ARG_POINTER(aVisibility); + + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetVisibility(PRBool aVisibility) +{ + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::GetMainWidget(nsIWidget** aMainWidget) +{ + NS_ENSURE_ARG_POINTER(aMainWidget); + + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetFocus() +{ + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::FocusAvailable(nsIBaseWindow* aCurrentFocus, + PRBool* aTookFocus) +{ + //XXX First Check In + NS_ASSERTION(PR_FALSE, "Not Yet Implemented"); + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::GetTitle(PRUnichar** aTitle) +{ + NS_ENSURE_ARG_POINTER(aTitle); + NS_ENSURE_STATE(mBrowserWindow); + + Str255 aStr; + nsAutoString titleStr; + + mBrowserWindow->GetDescriptor(aStr); + UMacUnicode::Str255ToString(aStr, titleStr); + *aTitle = titleStr.ToNewUnicode(); + + return NS_OK; +} + +NS_IMETHODIMP CWebBrowserChrome::SetTitle(const PRUnichar* aTitle) +{ + NS_ENSURE_STATE(mBrowserWindow); + + nsAutoString titleStr(aTitle); + Str255 aStr; + + UMacUnicode::StringToStr255(titleStr, aStr); + mBrowserWindow->SetDescriptor(aStr); + + return NS_OK; +} + +//***************************************************************************** +// CWebBrowserChrome: Helpers +//***************************************************************************** + +//***************************************************************************** +// CWebBrowserChrome: Accessors +//***************************************************************************** + +void CWebBrowserChrome::BrowserWindow(CBrowserWindow* aBrowserWindow) +{ + mBrowserWindow = aBrowserWindow; +} + +CBrowserWindow* CWebBrowserChrome::BrowserWindow() +{ + return mBrowserWindow; +} + diff --git a/embedding/browser/powerplant/source/CWebBrowserChrome.h b/embedding/browser/powerplant/source/CWebBrowserChrome.h new file mode 100644 index 000000000000..0abcebeef506 --- /dev/null +++ b/embedding/browser/powerplant/source/CWebBrowserChrome.h @@ -0,0 +1,65 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Contributor(s): + * Travis Bogard + */ + +#ifndef __CWebBrowserChrome__ +#define __CWebBrowserChrome__ + +// Helper Classes +#include "nsCOMPtr.h" + +// Interfaces Needed +#include "nsIWebBrowserChrome.h" +#include "nsIBaseWindow.h" +#include "nsIWebProgressListener.h" +#include "nsIInterfaceRequestor.h" +#include "nsIDocumentLoaderObserver.h" + +class CBrowserWindow; + +class CWebBrowserChrome : public nsIWebBrowserChrome, + public nsIDocumentLoaderObserver, + public nsIWebProgressListener, + public nsIBaseWindow, + public nsIInterfaceRequestor +{ +friend class CBrowserWindow; + +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIWEBBROWSERCHROME + NS_DECL_NSIDOCUMENTLOADEROBSERVER + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_NSIBASEWINDOW + NS_DECL_NSIINTERFACEREQUESTOR + +protected: + CWebBrowserChrome(); + virtual ~CWebBrowserChrome(); + + void BrowserWindow(CBrowserWindow* aBrowserWindow); + CBrowserWindow* BrowserWindow(); + +protected: + CBrowserWindow* mBrowserWindow; +}; + +#endif /* __CWebBrowserChrome__ */ diff --git a/embedding/browser/powerplant/source/UMacUnicode.cpp b/embedding/browser/powerplant/source/UMacUnicode.cpp new file mode 100644 index 000000000000..f3708ad5ef4e --- /dev/null +++ b/embedding/browser/powerplant/source/UMacUnicode.cpp @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Contributor(s): + * Conrad Carlen + */ + +#include "UMacUnicode.h" +#include "nsString.h" +#include "nsIUnicodeEncoder.h" +#include "nsIUnicodeDecoder.h" +#include "nsIServiceManager.h" +#define NS_IMPL_IDS +#include "nsIPlatformCharset.h" +#undef NS_IMPL_IDS +#include "nsICharsetConverterManager.h" + +static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); + +static nsIUnicodeEncoder *gUnicodeEncoder; +static nsIUnicodeDecoder *gUnicodeDecoder; + +static void GetFileSystemCharset(nsString & fileSystemCharset); + + +void UMacUnicode::ReleaseUnit() +{ + NS_IF_RELEASE(gUnicodeEncoder); + NS_IF_RELEASE(gUnicodeDecoder); +} + + +void UMacUnicode::StringToStr255(const nsString& aText, Str255& aStr255) +{ + char buffer[256]; + nsresult rv = NS_OK; + + // get file system charset and create a unicode encoder + if (nsnull == gUnicodeEncoder) { + nsAutoString fileSystemCharset; + GetFileSystemCharset(fileSystemCharset); + + NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &rv); + if (NS_SUCCEEDED(rv)) { + rv = ccm->GetUnicodeEncoder(&fileSystemCharset, &gUnicodeEncoder); + } + } + + // converts from unicode to the file system charset + if (NS_SUCCEEDED(rv)) { + PRInt32 inLength = aText.Length(); + PRInt32 outLength = 255; + rv = gUnicodeEncoder->Convert(aText.GetUnicode(), &inLength, (char *) &aStr255[1], &outLength); + if (NS_SUCCEEDED(rv)) + aStr255[0] = outLength; + } + + if (NS_FAILED(rv)) { +// NS_ASSERTION(0, "error: charset covnersion"); + aText.ToCString(buffer, 255); + PRInt32 len = nsCRT::strlen(buffer); + memcpy(&aStr255[1], buffer, len); + aStr255[0] = len; + } +} + + +void UMacUnicode::Str255ToString(const Str255& aStr255, nsString& aText) +{ + nsresult rv = NS_OK; + + // get file system charset and create a unicode encoder + if (nsnull == gUnicodeDecoder) { + nsAutoString fileSystemCharset; + GetFileSystemCharset(fileSystemCharset); + + NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &rv); + if (NS_SUCCEEDED(rv)) { + rv = ccm->GetUnicodeDecoder(&fileSystemCharset, &gUnicodeDecoder); + } + } + + // converts from the file system charset to unicode + if (NS_SUCCEEDED(rv)) { + PRUnichar buffer[512]; + PRInt32 inLength = aStr255[0]; + PRInt32 outLength = 512; + rv = gUnicodeDecoder->Convert((char *) &aStr255[1], &inLength, buffer, &outLength); + if (NS_SUCCEEDED(rv)) { + aText.SetString(buffer, outLength); + } + } + + if (NS_FAILED(rv)) { +// NS_ASSERTION(0, "error: charset covnersion"); + aText.SetString((char *) &aStr255[1], aStr255[0]); + } +} + + +static void GetFileSystemCharset(nsString & fileSystemCharset) +{ + static nsAutoString aCharset; + nsresult rv; + + if (aCharset.Length() < 1) { + nsCOMPtr platformCharset = do_GetService(NS_PLATFORMCHARSET_PROGID, &rv); + if (NS_SUCCEEDED(rv)) + rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, aCharset); + + NS_ASSERTION(NS_SUCCEEDED(rv), "error getting platform charset"); + if (NS_FAILED(rv)) + aCharset.SetString("x-mac-roman"); + } + fileSystemCharset = aCharset; +} diff --git a/embedding/browser/powerplant/source/UMacUnicode.h b/embedding/browser/powerplant/source/UMacUnicode.h new file mode 100644 index 000000000000..20512fd91f62 --- /dev/null +++ b/embedding/browser/powerplant/source/UMacUnicode.h @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Contributor(s): + * Conrad Carlen + */ + +#ifndef __UMacUnicode__ +#define __UMacUnicode__ + + +class nsString; + +namespace UMacUnicode +{ + + void ReleaseUnit(); + + void StringToStr255(const nsString& aText, Str255& aStr255); + void Str255ToString(const Str255& aStr255, nsString& aText); +} + +#endif // __UMacUnicode__