зеркало из https://github.com/mozilla/gecko-dev.git
First stab at Cocoa impl of widget. Some code still carbon, copied from
widget/src/mac. [Not part of build].
This commit is contained in:
Родитель
18c0c3636f
Коммит
43eb937819
|
@ -0,0 +1,69 @@
|
||||||
|
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
//
|
||||||
|
// nsAppShellCocoa
|
||||||
|
//
|
||||||
|
// This file contains the default interface of the application shell. Clients
|
||||||
|
// may either use this implementation or write their own. If you write your
|
||||||
|
// own, you must create a message sink to route events to. (The message sink
|
||||||
|
// interface may change, so this comment must be updated accordingly.)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef nsAppShellCocoa_h__
|
||||||
|
#define nsAppShellCocoa_h__
|
||||||
|
|
||||||
|
#include "nsIAppShell.h"
|
||||||
|
|
||||||
|
|
||||||
|
class nsAppShellCocoa : public nsIAppShell
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsAppShellCocoa();
|
||||||
|
virtual ~nsAppShellCocoa();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIAPPSHELL
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // nsAppShellCocoa_h__
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
//
|
||||||
|
// nsAppShellCocoa
|
||||||
|
//
|
||||||
|
// This file contains the default implementation of the application shell. Clients
|
||||||
|
// may either use this implementation or write their own. If you write your
|
||||||
|
// own, you must create a message sink to route events to. (The message sink
|
||||||
|
// interface may change, so this comment must be updated accordingly.)
|
||||||
|
//
|
||||||
|
|
||||||
|
#undef DARWIN
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#include "nsAppShellCocoa.h"
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMPL_THREADSAFE_ISUPPORTS1(nsAppShellCocoa, nsIAppShell)
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// nsAppShellCocoa constructor
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsAppShellCocoa::nsAppShellCocoa()
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// nsAppShellCocoa destructor
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsAppShellCocoa::~nsAppShellCocoa()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Create the application shell
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsAppShellCocoa::Create(int* argc, char ** argv)
|
||||||
|
{
|
||||||
|
// There's reallly not a whole lot that needs to be done here. The
|
||||||
|
// window will register its own interest in the necessary events
|
||||||
|
// so there's no need for us to create a pump or a sink.
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Enter a message handler loop
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsAppShellCocoa::Run(void)
|
||||||
|
{
|
||||||
|
[NSApp run];
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Exit appshell
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsAppShellCocoa::Exit(void)
|
||||||
|
{
|
||||||
|
[NSApp stop];
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsAppShellCocoa::SetDispatchListener(nsDispatchListener* aDispatchListener)
|
||||||
|
{
|
||||||
|
// nobody uses this except viewer
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// respond to notifications that an event queue has come or gone
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsAppShellCocoa::ListenToEventQueue(nsIEventQueue * aQueue, PRBool aListen)
|
||||||
|
{
|
||||||
|
// unnecessary; handled elsewhere
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Prepare to process events
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsAppShellCocoa::Spinup(void)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Stop being prepared to process events.
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsAppShellCocoa::Spindown(void)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetNativeEvent
|
||||||
|
// DispatchNativeEvent
|
||||||
|
//
|
||||||
|
// These are generally used in the tight loop of a modal event loop. Cocoa
|
||||||
|
// has other ways of dealing with this, perhaps those should be investigated
|
||||||
|
// here.
|
||||||
|
//
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsAppShellCocoa::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
|
||||||
|
{
|
||||||
|
NS_WARNING("GetNativeEvent NOT YET IMPLEMENTED");
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static EventRecord theEvent; // icky icky static (can't really do any better)
|
||||||
|
|
||||||
|
if (!mMacPump.get())
|
||||||
|
return NS_ERROR_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
aRealEvent = mMacPump->GetEvent(theEvent);
|
||||||
|
aEvent = &theEvent;
|
||||||
|
#endif
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsAppShellCocoa::DispatchNativeEvent(PRBool aRealEvent, void *aEvent)
|
||||||
|
{
|
||||||
|
NS_WARNING("DispatchNativeEvent NOT YET IMPLEMENTED");
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (!mMacPump.get())
|
||||||
|
return NS_ERROR_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
mMacPump->DispatchEvent(aRealEvent, (EventRecord *) aEvent);
|
||||||
|
#endif
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* -*- 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 IBM code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is IBM.
|
||||||
|
* Portions created by IBM are
|
||||||
|
* Copyright (C) International Business Machines
|
||||||
|
* Corporation, 2000. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Simon Montagu
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsBidiKeyboard.h"
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsBidiKeyboard, nsIBidiKeyboard)
|
||||||
|
|
||||||
|
nsBidiKeyboard::nsBidiKeyboard() : nsIBidiKeyboard()
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsBidiKeyboard::~nsBidiKeyboard()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsBidiKeyboard::IsLangRTL(PRBool *aIsRTL)
|
||||||
|
{
|
||||||
|
*aIsRTL = PR_FALSE;
|
||||||
|
#ifdef IBMBIDI
|
||||||
|
// XXX Insert platform specific code to determine keyboard direction
|
||||||
|
#endif
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsBidiKeyboard::SetLangFromBidiLevel(PRUint8 aLevel)
|
||||||
|
{
|
||||||
|
#ifdef IBMBIDI
|
||||||
|
// XXX Insert platform specific code to set keyboard language
|
||||||
|
#endif
|
||||||
|
return NS_OK;
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* -*- 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 IBM code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is IBM.
|
||||||
|
* Portions created by IBM are
|
||||||
|
* Copyright (C) International Business Machines
|
||||||
|
* Corporation, 2000. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Simon Montagu
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __nsBidiKeyboard
|
||||||
|
#define __nsBidiKeyboard
|
||||||
|
#include "nsIBidiKeyboard.h"
|
||||||
|
|
||||||
|
class nsBidiKeyboard : public nsIBidiKeyboard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIBIDIKEYBOARD
|
||||||
|
|
||||||
|
nsBidiKeyboard();
|
||||||
|
virtual ~nsBidiKeyboard();
|
||||||
|
/* additional members */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __nsBidiKeyboard
|
|
@ -0,0 +1,266 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 Window_h__
|
||||||
|
#define Window_h__
|
||||||
|
|
||||||
|
#include "nsISupports.h"
|
||||||
|
#include "nsBaseWidget.h"
|
||||||
|
#include "nsDeleteObserver.h"
|
||||||
|
|
||||||
|
#include "nsIWidget.h"
|
||||||
|
#include "nsIKBStateControl.h"
|
||||||
|
#include "nsIAppShell.h"
|
||||||
|
|
||||||
|
#include "nsIMouseListener.h"
|
||||||
|
#include "nsIEventListener.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
#include "nsIMenuBar.h"
|
||||||
|
|
||||||
|
#include "nsplugindefs.h"
|
||||||
|
#include <QuickDraw.h>
|
||||||
|
|
||||||
|
#define NSRGB_2_COLOREF(color) \
|
||||||
|
RGB(NS_GET_R(color),NS_GET_G(color),NS_GET_B(color))
|
||||||
|
|
||||||
|
struct nsPluginPort;
|
||||||
|
|
||||||
|
#undef DARWIN
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
class nsChildView;
|
||||||
|
class nsIEventSink;
|
||||||
|
|
||||||
|
|
||||||
|
@interface ChildView : NSQuickDrawView
|
||||||
|
{
|
||||||
|
// the nsChildView that created the view. It retains this NSView, so
|
||||||
|
// the link back to it must be weak.
|
||||||
|
nsChildView* mGeckoChild;
|
||||||
|
|
||||||
|
// allows us to redispatch events back to a centralized location
|
||||||
|
nsIEventSink* mEventSink;
|
||||||
|
|
||||||
|
// tag for our mouse enter/exit tracking rect
|
||||||
|
NSTrackingRectTag mMouseEnterExitTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets up our view, attaching it to its owning gecko view
|
||||||
|
- (id) initWithGeckoChild:(nsChildView*)child eventSink:(nsIEventSink*)sink;
|
||||||
|
|
||||||
|
// access the nsIWidget associated with this view. DOES NOT ADDREF.
|
||||||
|
- (nsIWidget*) widget;
|
||||||
|
|
||||||
|
// convert from one event system to the other for even dispatching
|
||||||
|
- (void) convert:(NSEvent*)inEvent message:(PRInt32)inMsg toGeckoEvent:(nsInputEvent*)outGeckoEvent;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// nsChildView
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class nsChildView : public nsBaseWidget, public nsDeleteObserved, public nsIKBStateControl
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef nsBaseWidget Inherited;
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsChildView();
|
||||||
|
virtual ~nsChildView();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
// nsIWidget interface
|
||||||
|
NS_IMETHOD Create(nsIWidget *aParent,
|
||||||
|
const nsRect &aRect,
|
||||||
|
EVENT_CALLBACK aHandleEventFunction,
|
||||||
|
nsIDeviceContext *aContext,
|
||||||
|
nsIAppShell *aAppShell = nsnull,
|
||||||
|
nsIToolkit *aToolkit = nsnull,
|
||||||
|
nsWidgetInitData *aInitData = nsnull);
|
||||||
|
NS_IMETHOD Create(nsNativeWidget aNativeParent,
|
||||||
|
const nsRect &aRect,
|
||||||
|
EVENT_CALLBACK aHandleEventFunction,
|
||||||
|
nsIDeviceContext *aContext,
|
||||||
|
nsIAppShell *aAppShell = nsnull,
|
||||||
|
nsIToolkit *aToolkit = nsnull,
|
||||||
|
nsWidgetInitData *aInitData = nsnull);
|
||||||
|
|
||||||
|
// Utility method for implementing both Create(nsIWidget ...) and
|
||||||
|
// Create(nsNativeWidget...)
|
||||||
|
|
||||||
|
virtual nsresult StandardCreate(nsIWidget *aParent,
|
||||||
|
const nsRect &aRect,
|
||||||
|
EVENT_CALLBACK aHandleEventFunction,
|
||||||
|
nsIDeviceContext *aContext,
|
||||||
|
nsIAppShell *aAppShell,
|
||||||
|
nsIToolkit *aToolkit,
|
||||||
|
nsWidgetInitData *aInitData,
|
||||||
|
nsNativeWidget aNativeParent = nsnull);
|
||||||
|
|
||||||
|
NS_IMETHOD Destroy();
|
||||||
|
virtual nsIWidget* GetParent(void);
|
||||||
|
|
||||||
|
NS_IMETHOD Show(PRBool aState);
|
||||||
|
NS_IMETHOD IsVisible(PRBool & aState);
|
||||||
|
|
||||||
|
NS_IMETHOD ModalEventFilter(PRBool aRealEvent, void *aEvent,
|
||||||
|
PRBool *aForWindow);
|
||||||
|
|
||||||
|
NS_IMETHOD ConstrainPosition(PRInt32 *aX, PRInt32 *aY);
|
||||||
|
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
|
||||||
|
NS_IMETHOD Resize(PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint);
|
||||||
|
NS_IMETHOD Resize(PRInt32 aX, PRInt32 aY,PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint);
|
||||||
|
|
||||||
|
NS_IMETHOD Enable(PRBool bState);
|
||||||
|
NS_IMETHOD SetFocus(PRBool aRaise);
|
||||||
|
NS_IMETHOD SetBounds(const nsRect &aRect);
|
||||||
|
NS_IMETHOD GetBounds(nsRect &aRect);
|
||||||
|
|
||||||
|
virtual nsIFontMetrics* GetFont(void);
|
||||||
|
NS_IMETHOD SetFont(const nsFont &aFont);
|
||||||
|
NS_IMETHOD Invalidate(PRBool aIsSynchronous);
|
||||||
|
NS_IMETHOD Invalidate(const nsRect &aRect,PRBool aIsSynchronous);
|
||||||
|
NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous);
|
||||||
|
|
||||||
|
virtual void* GetNativeData(PRUint32 aDataType);
|
||||||
|
NS_IMETHOD SetColorMap(nsColorMap *aColorMap);
|
||||||
|
NS_IMETHOD Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect);
|
||||||
|
NS_IMETHOD WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect);
|
||||||
|
NS_IMETHOD ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect);
|
||||||
|
NS_IMETHOD BeginResizingChildren(void);
|
||||||
|
NS_IMETHOD EndResizingChildren(void);
|
||||||
|
|
||||||
|
static PRBool ConvertStatus(nsEventStatus aStatus);
|
||||||
|
NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
|
||||||
|
virtual PRBool DispatchMouseEvent(nsMouseEvent &aEvent);
|
||||||
|
|
||||||
|
virtual void StartDraw(nsIRenderingContext* aRenderingContext = nsnull);
|
||||||
|
virtual void EndDraw();
|
||||||
|
NS_IMETHOD Update();
|
||||||
|
virtual void UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext);
|
||||||
|
|
||||||
|
virtual void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY);
|
||||||
|
void LocalToWindowCoordinate(nsPoint& aPoint) { ConvertToDeviceCoordinates(aPoint.x, aPoint.y); }
|
||||||
|
void LocalToWindowCoordinate(nscoord& aX, nscoord& aY) { ConvertToDeviceCoordinates(aX, aY); }
|
||||||
|
void LocalToWindowCoordinate(nsRect& aRect) { ConvertToDeviceCoordinates(aRect.x, aRect.y); }
|
||||||
|
|
||||||
|
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar);
|
||||||
|
NS_IMETHOD ShowMenuBar(PRBool aShow);
|
||||||
|
virtual nsIMenuBar* GetMenuBar();
|
||||||
|
NS_IMETHOD GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight);
|
||||||
|
NS_IMETHOD SetPreferredSize(PRInt32 aWidth, PRInt32 aHeight);
|
||||||
|
|
||||||
|
NS_IMETHOD SetCursor(nsCursor aCursor);
|
||||||
|
|
||||||
|
NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent);
|
||||||
|
NS_IMETHOD SetTitle(const nsString& title);
|
||||||
|
|
||||||
|
NS_IMETHOD GetAttention();
|
||||||
|
|
||||||
|
// Mac specific methods
|
||||||
|
void nsRectToMacRect(const nsRect& aRect, Rect& aMacRect) const;
|
||||||
|
virtual void CalcWindowRegions();
|
||||||
|
|
||||||
|
virtual PRBool PointInWidget(Point aThePoint);
|
||||||
|
virtual nsChildView* FindWidgetHit(Point aThePoint);
|
||||||
|
|
||||||
|
virtual PRBool DispatchWindowEvent(nsGUIEvent& event);
|
||||||
|
virtual PRBool DispatchWindowEvent(nsGUIEvent &event,nsEventStatus &aStatus);
|
||||||
|
virtual void AcceptFocusOnClick(PRBool aBool) { mAcceptFocusOnClick = aBool;};
|
||||||
|
PRBool AcceptFocusOnClick() { return mAcceptFocusOnClick;};
|
||||||
|
void Flash(nsPaintEvent &aEvent);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// nsIKBStateControl interface
|
||||||
|
NS_IMETHOD ResetInputState();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
PRBool ReportDestroyEvent();
|
||||||
|
PRBool ReportMoveEvent();
|
||||||
|
PRBool ReportSizeEvent();
|
||||||
|
|
||||||
|
NS_IMETHOD CalcOffset(PRInt32 &aX,PRInt32 &aY);
|
||||||
|
|
||||||
|
virtual PRBool OnPaint(nsPaintEvent & aEvent);
|
||||||
|
|
||||||
|
// our own impl of ::ScrollRect() that uses CopyBits so that it looks good. On
|
||||||
|
// Carbon, this just calls ::ScrollWindowRect()
|
||||||
|
void ScrollBits ( Rect & foo, PRInt32 inLeftDelta, PRInt32 inTopDelta ) ;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
#if DEBUG
|
||||||
|
const char* gInstanceClassName;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsIWidget* mParent; // my parent. could be a childview or a window [WEAK]
|
||||||
|
NSWindow* mWindow; // shortcut to the top window, [WEAK]
|
||||||
|
|
||||||
|
ChildView* mView; // my parallel cocoa view, [STRONG]
|
||||||
|
|
||||||
|
PRBool mDestroyCalled;
|
||||||
|
PRBool mDestructorCalled;
|
||||||
|
PRBool mVisible;
|
||||||
|
|
||||||
|
nsIFontMetrics* mFontMetrics;
|
||||||
|
|
||||||
|
PRBool mDrawing;
|
||||||
|
nsIRenderingContext* mTempRenderingContext;
|
||||||
|
PRBool mTempRenderingContextMadeHere;
|
||||||
|
|
||||||
|
nsPluginPort* mPluginPort;
|
||||||
|
|
||||||
|
PRBool mAcceptFocusOnClick;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#define WIDGET_SET_CLASSNAME(n) gInstanceClassName = (n)
|
||||||
|
#else
|
||||||
|
#define WIDGET_SET_CLASSNAME(n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Window_h__
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,532 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mike Pinkerton
|
||||||
|
// Netscape Communications
|
||||||
|
//
|
||||||
|
// See header file for details.
|
||||||
|
//
|
||||||
|
// Remaining Work:
|
||||||
|
// * only convert data to clipboard on an app switch.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsClipboard.h"
|
||||||
|
|
||||||
|
#include "nsVoidArray.h"
|
||||||
|
#include "nsIClipboardOwner.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsIFormatConverter.h"
|
||||||
|
#include "nsMimeMapper.h"
|
||||||
|
|
||||||
|
#include "nsIComponentManager.h"
|
||||||
|
#include "nsISupportsPrimitives.h"
|
||||||
|
#include "nsXPIDLString.h"
|
||||||
|
#include "nsPrimitiveHelpers.h"
|
||||||
|
#include "nsIImageMac.h"
|
||||||
|
#include "nsMemory.h"
|
||||||
|
|
||||||
|
#include <Scrap.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// nsClipboard constructor
|
||||||
|
//
|
||||||
|
nsClipboard::nsClipboard() : nsBaseClipboard()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// nsClipboard destructor
|
||||||
|
//
|
||||||
|
nsClipboard::~nsClipboard()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// SetNativeClipboardData
|
||||||
|
//
|
||||||
|
// Take data off the transferrable and put it on the clipboard in as many formats
|
||||||
|
// as are registered.
|
||||||
|
//
|
||||||
|
// NOTE: This code could all live in ForceDataToClipboard() and this could be a NOOP.
|
||||||
|
// If speed and large data sizes are an issue, we should move that code there and only
|
||||||
|
// do it on an app switch.
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsClipboard :: SetNativeClipboardData ( PRInt32 aWhichClipboard )
|
||||||
|
{
|
||||||
|
if ( aWhichClipboard != kGlobalClipboard )
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsresult errCode = NS_OK;
|
||||||
|
|
||||||
|
mIgnoreEmptyNotification = PR_TRUE;
|
||||||
|
|
||||||
|
// make sure we have a good transferable
|
||||||
|
if ( !mTransferable )
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
|
nsMimeMapperMac theMapper;
|
||||||
|
|
||||||
|
#if TARGET_CARBON
|
||||||
|
::ClearCurrentScrap();
|
||||||
|
#else
|
||||||
|
::ZeroScrap();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// get flavor list that includes all flavors that can be written (including ones
|
||||||
|
// obtained through conversion)
|
||||||
|
nsCOMPtr<nsISupportsArray> flavorList;
|
||||||
|
errCode = mTransferable->FlavorsTransferableCanExport ( getter_AddRefs(flavorList) );
|
||||||
|
if ( NS_FAILED(errCode) )
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// For each flavor present (either directly in the transferable or that its
|
||||||
|
// converter knows about) put it on the clipboard. Luckily, GetTransferData()
|
||||||
|
// handles conversions for us, so we really don't need to know if a conversion
|
||||||
|
// is required or not.
|
||||||
|
PRUint32 cnt;
|
||||||
|
flavorList->Count(&cnt);
|
||||||
|
for ( PRUint32 i = 0; i < cnt; ++i ) {
|
||||||
|
nsCOMPtr<nsISupports> genericFlavor;
|
||||||
|
flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
|
||||||
|
nsCOMPtr<nsISupportsString> currentFlavor ( do_QueryInterface(genericFlavor) );
|
||||||
|
if ( currentFlavor ) {
|
||||||
|
nsXPIDLCString flavorStr;
|
||||||
|
currentFlavor->ToString( getter_Copies(flavorStr) );
|
||||||
|
|
||||||
|
// find MacOS flavor
|
||||||
|
ResType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr);
|
||||||
|
|
||||||
|
// get data. This takes converters into account. Different things happen for
|
||||||
|
// different flavors, so do some special processing.
|
||||||
|
void* data = nsnull;
|
||||||
|
PRUint32 dataSize = 0;
|
||||||
|
if ( strcmp(flavorStr,kUnicodeMime) == 0 ) {
|
||||||
|
// we have unicode, put it on first as unicode
|
||||||
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||||
|
errCode = mTransferable->GetTransferData ( flavorStr, getter_AddRefs(genericDataWrapper), &dataSize );
|
||||||
|
nsPrimitiveHelpers::CreateDataFromPrimitive ( flavorStr, genericDataWrapper, &data, dataSize );
|
||||||
|
errCode = PutOnClipboard ( macOSFlavor, data, dataSize );
|
||||||
|
if ( NS_SUCCEEDED(errCode) ) {
|
||||||
|
// we also need to put it on as 'TEXT' after doing the conversion to the platform charset.
|
||||||
|
char* plainTextData = nsnull;
|
||||||
|
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, data);
|
||||||
|
PRInt32 plainTextLen = 0;
|
||||||
|
nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, dataSize / 2, &plainTextData, &plainTextLen );
|
||||||
|
if ( plainTextData ) {
|
||||||
|
errCode = PutOnClipboard ( 'TEXT', plainTextData, plainTextLen );
|
||||||
|
nsMemory::Free ( plainTextData );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // if unicode
|
||||||
|
else if ( strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
|
||||||
|
strcmp(flavorStr, kGIFImageMime) == 0 ) {
|
||||||
|
// we have an image, which is in the transferable as an nsIImage. Convert it
|
||||||
|
// to PICT (PicHandle) and put those bits on the clipboard. The actual size
|
||||||
|
// of the picture is the size of the handle, not sizeof(Picture).
|
||||||
|
nsCOMPtr<nsISupports> imageSupports;
|
||||||
|
errCode = mTransferable->GetTransferData ( flavorStr, getter_AddRefs(imageSupports), &dataSize );
|
||||||
|
nsCOMPtr<nsIImageMac> image ( do_QueryInterface(imageSupports) );
|
||||||
|
if ( image ) {
|
||||||
|
PicHandle picture = nsnull;
|
||||||
|
image->ConvertToPICT ( &picture );
|
||||||
|
if ( picture ) {
|
||||||
|
errCode = PutOnClipboard ( 'PICT', *picture, ::GetHandleSize((Handle)picture) );
|
||||||
|
::KillPicture ( picture );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
NS_WARNING ( "Image isn't an nsIImageMac in transferable" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we don't know what we have. let's just assume it's unicode but doesn't need to be
|
||||||
|
// translated to TEXT.
|
||||||
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||||
|
errCode = mTransferable->GetTransferData ( flavorStr, getter_AddRefs(genericDataWrapper), &dataSize );
|
||||||
|
nsPrimitiveHelpers::CreateDataFromPrimitive ( flavorStr, genericDataWrapper, &data, dataSize );
|
||||||
|
errCode = PutOnClipboard ( macOSFlavor, data, dataSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMemory::Free ( data );
|
||||||
|
}
|
||||||
|
} // foreach flavor in transferable
|
||||||
|
|
||||||
|
// write out the mapping data in a special flavor on the clipboard. |mappingLen|
|
||||||
|
// includes the NULL terminator.
|
||||||
|
short mappingLen = 0;
|
||||||
|
const char* mapping = theMapper.ExportMapping(&mappingLen);
|
||||||
|
if ( mapping && mappingLen ) {
|
||||||
|
errCode = PutOnClipboard ( nsMimeMapperMac::MappingFlavor(), mapping, mappingLen );
|
||||||
|
nsCRT::free ( NS_CONST_CAST(char*, mapping) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return errCode;
|
||||||
|
|
||||||
|
} // SetNativeClipboardData
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// PutOnClipboard
|
||||||
|
//
|
||||||
|
// Actually does the work of placing the data on the native clipboard
|
||||||
|
// in the given flavor
|
||||||
|
//
|
||||||
|
nsresult
|
||||||
|
nsClipboard :: PutOnClipboard ( ResType inFlavor, const void* inData, PRInt32 inLen )
|
||||||
|
{
|
||||||
|
nsresult errCode = NS_OK;
|
||||||
|
|
||||||
|
#if TARGET_CARBON
|
||||||
|
ScrapRef scrap;
|
||||||
|
::GetCurrentScrap(&scrap);
|
||||||
|
::PutScrapFlavor( scrap, inFlavor, kScrapFlavorMaskNone, inLen, inData );
|
||||||
|
#else
|
||||||
|
long numBytes = ::PutScrap ( inLen, inFlavor, inData );
|
||||||
|
if ( numBytes != noErr )
|
||||||
|
errCode = NS_ERROR_FAILURE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return errCode;
|
||||||
|
|
||||||
|
} // PutOnClipboard
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetNativeClipboardData
|
||||||
|
//
|
||||||
|
// Take data off the native clip and put it on the transferable.
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsClipboard :: GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32 aWhichClipboard )
|
||||||
|
{
|
||||||
|
if ( aWhichClipboard != kGlobalClipboard )
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsresult errCode = NS_OK;
|
||||||
|
|
||||||
|
// make sure we have a good transferable
|
||||||
|
if ( !aTransferable )
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
|
// get flavor list that includes all acceptable flavors (including ones obtained through
|
||||||
|
// conversion)
|
||||||
|
nsCOMPtr<nsISupportsArray> flavorList;
|
||||||
|
errCode = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) );
|
||||||
|
if ( NS_FAILED(errCode) )
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// create a mime mapper. It's ok for this to fail because the data may come from
|
||||||
|
// another app which obviously wouldn't put our mime mapping data on the clipboard.
|
||||||
|
char* mimeMapperData = nsnull;
|
||||||
|
errCode = GetDataOffClipboard ( nsMimeMapperMac::MappingFlavor(), (void**)&mimeMapperData, 0 );
|
||||||
|
nsMimeMapperMac theMapper ( mimeMapperData );
|
||||||
|
if (mimeMapperData)
|
||||||
|
nsCRT::free ( mimeMapperData );
|
||||||
|
|
||||||
|
// Now walk down the list of flavors. When we find one that is actually on the
|
||||||
|
// clipboard, copy out the data into the transferable in that format. SetTransferData()
|
||||||
|
// implicitly handles conversions.
|
||||||
|
PRBool dataFound = PR_FALSE;
|
||||||
|
PRUint32 cnt;
|
||||||
|
flavorList->Count(&cnt);
|
||||||
|
for ( PRUint32 i = 0; i < cnt; ++i ) {
|
||||||
|
nsCOMPtr<nsISupports> genericFlavor;
|
||||||
|
flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
|
||||||
|
nsCOMPtr<nsISupportsString> currentFlavor ( do_QueryInterface(genericFlavor) );
|
||||||
|
if ( currentFlavor ) {
|
||||||
|
nsXPIDLCString flavorStr;
|
||||||
|
currentFlavor->ToString ( getter_Copies(flavorStr) );
|
||||||
|
|
||||||
|
// find MacOS flavor (don't add if not present)
|
||||||
|
ResType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr, PR_FALSE);
|
||||||
|
|
||||||
|
void* clipboardData = nsnull;
|
||||||
|
PRInt32 dataSize = 0L;
|
||||||
|
nsresult loadResult = GetDataOffClipboard ( macOSFlavor, &clipboardData, &dataSize );
|
||||||
|
if ( NS_SUCCEEDED(loadResult) && clipboardData )
|
||||||
|
dataFound = PR_TRUE;
|
||||||
|
else {
|
||||||
|
// if we are looking for text/unicode and we fail to find it on the clipboard first,
|
||||||
|
// try again with text/plain. If that is present, convert it to unicode.
|
||||||
|
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||||
|
loadResult = GetDataOffClipboard ( 'TEXT', &clipboardData, &dataSize );
|
||||||
|
if ( NS_SUCCEEDED(loadResult) && clipboardData ) {
|
||||||
|
const char* castedText = NS_REINTERPRET_CAST(char*, clipboardData);
|
||||||
|
PRUnichar* convertedText = nsnull;
|
||||||
|
PRInt32 convertedTextLen = 0;
|
||||||
|
nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize,
|
||||||
|
&convertedText, &convertedTextLen );
|
||||||
|
if ( convertedText ) {
|
||||||
|
// out with the old, in with the new
|
||||||
|
nsMemory::Free(clipboardData);
|
||||||
|
clipboardData = convertedText;
|
||||||
|
dataSize = convertedTextLen * 2;
|
||||||
|
dataFound = PR_TRUE;
|
||||||
|
}
|
||||||
|
} // if plain text data on clipboard
|
||||||
|
} // if looking for text/unicode
|
||||||
|
} // else we try one last ditch effort to find our data
|
||||||
|
|
||||||
|
if ( dataFound ) {
|
||||||
|
if ( strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
|
||||||
|
strcmp(flavorStr, kGIFImageMime) == 0 ) {
|
||||||
|
// someone asked for an image, so we have to convert from PICT to the desired
|
||||||
|
// image format
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ( "----------- IMAGE REQUESTED ----------" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // if image requested
|
||||||
|
else {
|
||||||
|
// Assume that we have some form of textual data. The DOM only wants LF, so convert
|
||||||
|
// from MacOS line endings to DOM line endings.
|
||||||
|
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &clipboardData, &dataSize );
|
||||||
|
|
||||||
|
// put it into the transferable
|
||||||
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||||
|
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, clipboardData, dataSize, getter_AddRefs(genericDataWrapper) );
|
||||||
|
errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMemory::Free ( clipboardData );
|
||||||
|
|
||||||
|
// we found one, get out of this loop!
|
||||||
|
break;
|
||||||
|
} // if flavor found on clipboard
|
||||||
|
}
|
||||||
|
} // foreach flavor
|
||||||
|
|
||||||
|
return errCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetDataOffClipboard
|
||||||
|
//
|
||||||
|
// Actually does the work of retrieving the data from the native clipboard
|
||||||
|
// with the given MacOS flavor
|
||||||
|
//
|
||||||
|
nsresult
|
||||||
|
nsClipboard :: GetDataOffClipboard ( ResType inMacFlavor, void** outData, PRInt32* outDataSize )
|
||||||
|
{
|
||||||
|
if ( !outData || !inMacFlavor )
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// set up default results.
|
||||||
|
*outData = nsnull;
|
||||||
|
if ( outDataSize )
|
||||||
|
*outDataSize = 0;
|
||||||
|
|
||||||
|
// check if it is on the clipboard
|
||||||
|
long offsetUnused = 0;
|
||||||
|
|
||||||
|
#if TARGET_CARBON
|
||||||
|
ScrapRef scrap;
|
||||||
|
long dataSize;
|
||||||
|
OSStatus err;
|
||||||
|
|
||||||
|
err = ::GetCurrentScrap(&scrap);
|
||||||
|
if (err != noErr) return NS_ERROR_FAILURE;
|
||||||
|
err = ::GetScrapFlavorSize(scrap, inMacFlavor, &dataSize);
|
||||||
|
if (err != noErr) return NS_ERROR_FAILURE;
|
||||||
|
if (dataSize > 0) {
|
||||||
|
char* dataBuff = (char*) nsMemory::Alloc(dataSize);
|
||||||
|
if ( !dataBuff )
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
// ::GetScrapFlavorData can be very expensive when a conversion
|
||||||
|
// is required (say the OS does the conversion from TEXT to utxt). Be
|
||||||
|
// sure to only call this when pasting. We no longer use it in
|
||||||
|
// CheckIfFlavorPresent() for this very reason.
|
||||||
|
err = ::GetScrapFlavorData(scrap, inMacFlavor, &dataSize, dataBuff);
|
||||||
|
NS_ASSERTION(err == noErr, "nsClipboard:: Error getting data off clipboard");
|
||||||
|
if ( err ) {
|
||||||
|
nsMemory::Free(dataBuff);
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// put it into the transferable
|
||||||
|
if ( outDataSize )
|
||||||
|
*outDataSize = dataSize;
|
||||||
|
*outData = dataBuff;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
long clipResult = ::GetScrap(NULL, inMacFlavor, &offsetUnused);
|
||||||
|
if ( clipResult > 0 ) {
|
||||||
|
Handle dataHand = ::NewHandle(0);
|
||||||
|
if ( !dataHand )
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
long dataSize = ::GetScrap ( dataHand, inMacFlavor, &offsetUnused );
|
||||||
|
NS_ASSERTION(dataSize > 0, "nsClipboard:: Error getting data off the clipboard, size negative");
|
||||||
|
if ( dataSize > 0 ) {
|
||||||
|
char* dataBuff = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(dataSize));
|
||||||
|
if ( !dataBuff )
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
::HLock(dataHand);
|
||||||
|
::BlockMoveData ( *dataHand, dataBuff, dataSize );
|
||||||
|
::HUnlock(dataHand);
|
||||||
|
|
||||||
|
::DisposeHandle(dataHand);
|
||||||
|
|
||||||
|
if ( outDataSize )
|
||||||
|
*outDataSize = dataSize;
|
||||||
|
*outData = dataBuff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
#endif /* TARGET_CARBON */
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
} // GetDataOffClipboard
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// HasDataMatchingFlavors
|
||||||
|
//
|
||||||
|
// Check the clipboard to see if we have any data that matches the given flavors. This
|
||||||
|
// does NOT actually fetch the data. The items in the flavor list are nsISupportsString's.
|
||||||
|
//
|
||||||
|
// Handle the case where we ask for unicode and it's not there, but plain text is. We
|
||||||
|
// say "yes" in that case, knowing that we will have to perform a conversion when we actually
|
||||||
|
// pull the data off the clipboard.
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsClipboard :: HasDataMatchingFlavors ( nsISupportsArray* aFlavorList, PRInt32 aWhichClipboard, PRBool * outResult )
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
*outResult = PR_FALSE; // assume there is nothing there we want.
|
||||||
|
if ( aWhichClipboard != kGlobalClipboard )
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// create a mime mapper. It's ok for this to fail because the data may come from
|
||||||
|
// another app which obviously wouldn't put our mime mapping data on the clipboard.
|
||||||
|
char* mimeMapperData = nsnull;
|
||||||
|
rv = GetDataOffClipboard ( nsMimeMapperMac::MappingFlavor(), (void**)&mimeMapperData, 0 );
|
||||||
|
nsMimeMapperMac theMapper ( mimeMapperData );
|
||||||
|
nsMemory::Free ( mimeMapperData );
|
||||||
|
|
||||||
|
PRUint32 length;
|
||||||
|
aFlavorList->Count(&length);
|
||||||
|
for ( PRUint32 i = 0; i < length; ++i ) {
|
||||||
|
nsCOMPtr<nsISupports> genericFlavor;
|
||||||
|
aFlavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
|
||||||
|
nsCOMPtr<nsISupportsString> flavorWrapper ( do_QueryInterface(genericFlavor) );
|
||||||
|
if ( flavorWrapper ) {
|
||||||
|
nsXPIDLCString flavor;
|
||||||
|
flavorWrapper->ToString ( getter_Copies(flavor) );
|
||||||
|
|
||||||
|
#ifdef NS_DEBUG
|
||||||
|
if ( strcmp(flavor, kTextMime) == 0 )
|
||||||
|
NS_WARNING ( "DO NOT USE THE text/plain DATA FLAVOR ANY MORE. USE text/unicode INSTEAD" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// now that we have the flavor (whew!), run it through the mime mapper. If
|
||||||
|
// the mapper returns a null flavor, then it ain't there.
|
||||||
|
ResType macFlavor = theMapper.MapMimeTypeToMacOSType ( flavor, PR_FALSE );
|
||||||
|
if ( macFlavor ) {
|
||||||
|
if ( CheckIfFlavorPresent(macFlavor) ) {
|
||||||
|
*outResult = PR_TRUE; // we found one!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// if the client asked for unicode and it wasn't present, check if we have TEXT.
|
||||||
|
// We'll handle the actual data substitution in GetNativeClipboardData().
|
||||||
|
if ( strcmp(flavor, kUnicodeMime) == 0 ) {
|
||||||
|
if ( CheckIfFlavorPresent('TEXT') ) {
|
||||||
|
*outResult = PR_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // foreach flavor
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// CheckIfFlavorPresent
|
||||||
|
//
|
||||||
|
// A little utility routine for derminining if a given flavor is really there
|
||||||
|
//
|
||||||
|
PRBool
|
||||||
|
nsClipboard :: CheckIfFlavorPresent ( ResType inMacFlavor )
|
||||||
|
{
|
||||||
|
PRBool retval = PR_FALSE;
|
||||||
|
|
||||||
|
#if TARGET_CARBON
|
||||||
|
ScrapRef scrap = nsnull;
|
||||||
|
OSStatus err = ::GetCurrentScrap(&scrap);
|
||||||
|
if ( scrap ) {
|
||||||
|
|
||||||
|
// the OS clipboard may contain promises and require conversions. Instead
|
||||||
|
// of calling in those promises, we can use ::GetScrapFlavorInfoList() to
|
||||||
|
// see the list of what could be there if we asked for it. This is really
|
||||||
|
// fast. Iterate over the list, and if we find it, we're good to go.
|
||||||
|
UInt32 flavorCount = 0;
|
||||||
|
::GetScrapFlavorCount ( scrap, &flavorCount );
|
||||||
|
ScrapFlavorInfo* flavorList = new ScrapFlavorInfo[flavorCount];
|
||||||
|
if ( flavorList ) {
|
||||||
|
err = ::GetScrapFlavorInfoList ( scrap, &flavorCount, flavorList );
|
||||||
|
if ( !err && flavorList ) {
|
||||||
|
for ( int i = 0; i < flavorCount; ++i ) {
|
||||||
|
if ( flavorList[i].flavorType == inMacFlavor )
|
||||||
|
retval = PR_TRUE;
|
||||||
|
}
|
||||||
|
delete flavorList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
long offsetUnused = 0;
|
||||||
|
long clipResult = ::GetScrap(NULL, inMacFlavor, &offsetUnused);
|
||||||
|
if ( clipResult > 0 )
|
||||||
|
retval = PR_TRUE; // we found one!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
} // CheckIfFlavorPresent
|
|
@ -0,0 +1,85 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mike Pinkerton
|
||||||
|
// Netscape Communications
|
||||||
|
//
|
||||||
|
// Native MacOS Clipboard Implementation of nsIClipboard. This contains
|
||||||
|
// the FE-specific implementations of the pure virtuals in nsBaseClipboard
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef nsClipboard_h__
|
||||||
|
#define nsClipboard_h__
|
||||||
|
|
||||||
|
#include "nsBaseClipboard.h"
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
class nsITransferable;
|
||||||
|
|
||||||
|
|
||||||
|
class nsClipboard : public nsBaseClipboard
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsClipboard();
|
||||||
|
virtual ~nsClipboard();
|
||||||
|
|
||||||
|
// nsIClipboard
|
||||||
|
//NS_IMETHOD ForceDataToClipboard();
|
||||||
|
NS_IMETHOD HasDataMatchingFlavors(nsISupportsArray *aFlavorList, PRInt32 aWhichClipboard, PRBool *_retval);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// impelement the native clipboard behavior
|
||||||
|
NS_IMETHOD SetNativeClipboardData ( PRInt32 aWhichClipboard );
|
||||||
|
NS_IMETHOD GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32 aWhichClipboard );
|
||||||
|
|
||||||
|
// helper to get the data off the clipboard. Caller responsible for deleting
|
||||||
|
// |outData| with delete[].
|
||||||
|
nsresult GetDataOffClipboard ( ResType inMacFlavor, void** outData, PRInt32* outDataSize ) ;
|
||||||
|
|
||||||
|
// helper to check if the data is really there
|
||||||
|
PRBool CheckIfFlavorPresent ( ResType inMacFlavor ) ;
|
||||||
|
|
||||||
|
// actually places data on the clipboard
|
||||||
|
nsresult PutOnClipboard ( ResType inFlavor, const void* inData, PRInt32 inLen ) ;
|
||||||
|
|
||||||
|
}; // nsClipboard
|
||||||
|
|
||||||
|
#endif // nsClipboard_h__
|
|
@ -0,0 +1,208 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 MacWindow_h__
|
||||||
|
#define MacWindow_h__
|
||||||
|
|
||||||
|
#undef DARWIN
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#include "nsIEventSink.h"
|
||||||
|
|
||||||
|
//#include <memory> // for auto_ptr
|
||||||
|
#include <Controls.h>
|
||||||
|
|
||||||
|
//using std::auto_ptr;
|
||||||
|
|
||||||
|
#include "nsBaseWidget.h"
|
||||||
|
|
||||||
|
//#include "nsMacEventHandler.h"
|
||||||
|
|
||||||
|
class nsCocoaWindow;
|
||||||
|
|
||||||
|
|
||||||
|
@interface WindowDelegate : NSObject
|
||||||
|
{
|
||||||
|
nsCocoaWindow* mGeckoWindow;
|
||||||
|
}
|
||||||
|
- (id)initWithGeckoWindow:(nsCocoaWindow*)geckoWind;
|
||||||
|
- (void)windowDidResize:(NSNotification *)aNotification;
|
||||||
|
- (void)eventTimer:(NSTimer *)theTimer;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// nsCocoaWindow
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Cocoa native window
|
||||||
|
|
||||||
|
class nsCocoaWindow : public nsBaseWidget, public nsIEventSink
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef nsBaseWidget Inherited;
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsCocoaWindow();
|
||||||
|
virtual ~nsCocoaWindow();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_NSIEVENTSINK
|
||||||
|
|
||||||
|
NS_IMETHOD Create(nsNativeWidget aParent,
|
||||||
|
const nsRect &aRect,
|
||||||
|
EVENT_CALLBACK aHandleEventFunction,
|
||||||
|
nsIDeviceContext *aContext,
|
||||||
|
nsIAppShell *aAppShell = nsnull,
|
||||||
|
nsIToolkit *aToolkit = nsnull,
|
||||||
|
nsWidgetInitData *aInitData = nsnull);
|
||||||
|
|
||||||
|
NS_IMETHOD Create(nsIWidget* aParent,
|
||||||
|
const nsRect &aRect,
|
||||||
|
EVENT_CALLBACK aHandleEventFunction,
|
||||||
|
nsIDeviceContext *aContext,
|
||||||
|
nsIAppShell *aAppShell = nsnull,
|
||||||
|
nsIToolkit *aToolkit = nsnull,
|
||||||
|
nsWidgetInitData *aInitData = nsnull);
|
||||||
|
|
||||||
|
// Utility method for implementing both Create(nsIWidget ...) and
|
||||||
|
// Create(nsNativeWidget...)
|
||||||
|
|
||||||
|
virtual nsresult StandardCreate(nsIWidget *aParent,
|
||||||
|
const nsRect &aRect,
|
||||||
|
EVENT_CALLBACK aHandleEventFunction,
|
||||||
|
nsIDeviceContext *aContext,
|
||||||
|
nsIAppShell *aAppShell,
|
||||||
|
nsIToolkit *aToolkit,
|
||||||
|
nsWidgetInitData *aInitData,
|
||||||
|
nsNativeWidget aNativeParent = nsnull);
|
||||||
|
|
||||||
|
NS_IMETHOD Show(PRBool aState);
|
||||||
|
|
||||||
|
NS_IMETHOD Enable(PRBool aState) { return NS_OK; }
|
||||||
|
NS_IMETHOD SetModal(PRBool aState) { return NS_OK; }
|
||||||
|
NS_IMETHOD IsVisible(PRBool & aState) { return NS_OK; }
|
||||||
|
NS_IMETHOD SetFocus(PRBool aState=PR_FALSE) { return NS_OK; }
|
||||||
|
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar) { return NS_OK; }
|
||||||
|
NS_IMETHOD ShowMenuBar(PRBool aShow) { return NS_OK; }
|
||||||
|
NS_IMETHOD WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect) { return NS_OK; }
|
||||||
|
NS_IMETHOD ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect) { return NS_OK; }
|
||||||
|
|
||||||
|
virtual void* GetNativeData(PRUint32 aDataType) ;
|
||||||
|
|
||||||
|
NS_IMETHOD ConstrainPosition(PRInt32 *aX, PRInt32 *aY);
|
||||||
|
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
|
||||||
|
NS_IMETHOD PlaceBehind(nsIWidget *aWidget, PRBool aActivate);
|
||||||
|
NS_IMETHOD SetSizeMode(PRInt32 aMode);
|
||||||
|
void CalculateAndSetZoomedSize();
|
||||||
|
|
||||||
|
NS_IMETHOD Resize(PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint);
|
||||||
|
NS_IMETHOD Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint);
|
||||||
|
NS_IMETHOD GetScreenBounds(nsRect &aRect);
|
||||||
|
virtual PRBool OnPaint(nsPaintEvent &event);
|
||||||
|
void ReportSizeEvent();
|
||||||
|
|
||||||
|
NS_IMETHOD SetTitle(const nsString& aTitle);
|
||||||
|
|
||||||
|
virtual nsIFontMetrics* GetFont(void) { return nsnull; }
|
||||||
|
NS_IMETHOD SetFont(const nsFont &aFont) { return NS_OK; }
|
||||||
|
NS_IMETHOD Invalidate(const nsRect & aRect, PRBool aIsSynchronous) { return NS_OK; }
|
||||||
|
NS_IMETHOD Invalidate(PRBool aIsSynchronous) { return NS_OK; };
|
||||||
|
NS_IMETHOD Update() { return NS_OK; }
|
||||||
|
NS_IMETHOD Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect) { return NS_OK; }
|
||||||
|
NS_IMETHOD SetColorMap(nsColorMap *aColorMap) { return NS_OK; }
|
||||||
|
NS_IMETHOD BeginResizingChildren(void) { return NS_OK; }
|
||||||
|
NS_IMETHOD EndResizingChildren(void) { return NS_OK; }
|
||||||
|
NS_IMETHOD GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight) { return NS_OK; }
|
||||||
|
NS_IMETHOD SetPreferredSize(PRInt32 aWidth, PRInt32 aHeight) { return NS_OK; }
|
||||||
|
NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus) ;
|
||||||
|
NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent) { return NS_OK; }
|
||||||
|
|
||||||
|
// be notified that a some form of drag event needs to go into Gecko
|
||||||
|
virtual PRBool DragEvent ( unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers ) ;
|
||||||
|
|
||||||
|
// Helpers to prevent recursive resizing during live-resize
|
||||||
|
PRBool IsResizing ( ) const { return mIsResizing; }
|
||||||
|
void StartResizing ( ) { mIsResizing = PR_TRUE; }
|
||||||
|
void StopResizing ( ) { mIsResizing = PR_FALSE; }
|
||||||
|
|
||||||
|
void ComeToFront();
|
||||||
|
|
||||||
|
// nsIKBStateControl interface
|
||||||
|
NS_IMETHOD ResetInputState();
|
||||||
|
|
||||||
|
void MoveToGlobalPoint(PRInt32 aX, PRInt32 aY);
|
||||||
|
|
||||||
|
void IsActive(PRBool* aActive);
|
||||||
|
void SetIsActive(PRBool aActive);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
pascal static OSErr DragTrackingHandler ( DragTrackingMessage theMessage, WindowPtr theWindow,
|
||||||
|
void *handlerRefCon, DragReference theDrag );
|
||||||
|
pascal static OSErr DragReceiveHandler (WindowPtr theWindow,
|
||||||
|
void *handlerRefCon, DragReference theDragRef) ;
|
||||||
|
DragTrackingHandlerUPP mDragTrackingHandlerUPP;
|
||||||
|
DragReceiveHandlerUPP mDragReceiveHandlerUPP;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
pascal static OSStatus WindowEventHandler ( EventHandlerCallRef inHandlerChain,
|
||||||
|
EventRef inEvent, void* userData ) ;
|
||||||
|
pascal static OSStatus ScrollEventHandler ( EventHandlerCallRef inHandlerChain,
|
||||||
|
EventRef inEvent, void* userData ) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
PRBool mIsDialog; // true if the window is a dialog
|
||||||
|
auto_ptr<nsMacEventHandler> mMacEventHandler;
|
||||||
|
nsIWidget *mOffsetParent;
|
||||||
|
PRBool mAcceptsActivation;
|
||||||
|
PRBool mIsActive;
|
||||||
|
PRBool mZoomOnShow;
|
||||||
|
#endif // COCOA
|
||||||
|
|
||||||
|
PRBool mIsResizing; // we originated the resize, prevent infinite recursion
|
||||||
|
PRBool mWindowMadeHere; // true if we created the window, false for embedding
|
||||||
|
NSWindow* mWindow; // our cocoa window [STRONG]
|
||||||
|
NSTimer* mEventTimer; // event timer [STRONG]
|
||||||
|
WindowDelegate* mDelegate; // our delegate for processing window msgs [STRONG]
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MacWindow_h__
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,95 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 "nsDeleteObserver.h"
|
||||||
|
#include "nsVoidArray.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsDeleteObserved::nsDeleteObserved(void* aObject)
|
||||||
|
{
|
||||||
|
mDeleteObserverArray = nsnull;
|
||||||
|
mObject = (aObject ? aObject : this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsDeleteObserved::~nsDeleteObserved()
|
||||||
|
{
|
||||||
|
if (mDeleteObserverArray)
|
||||||
|
{
|
||||||
|
// notify observers of the delete
|
||||||
|
for (PRInt32 i = mDeleteObserverArray->Count() - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
nsDeleteObserver* deleteObserver = static_cast<nsDeleteObserver*>(mDeleteObserverArray->ElementAt(i));
|
||||||
|
if (deleteObserver)
|
||||||
|
deleteObserver->NotifyDelete(mObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete mDeleteObserverArray;
|
||||||
|
mDeleteObserverArray = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PRBool nsDeleteObserved::AddDeleteObserver(nsDeleteObserver* aDeleteObserver)
|
||||||
|
{
|
||||||
|
if (! mDeleteObserverArray)
|
||||||
|
mDeleteObserverArray = new nsVoidArray();
|
||||||
|
|
||||||
|
if (mDeleteObserverArray)
|
||||||
|
return mDeleteObserverArray->AppendElement(aDeleteObserver);
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PRBool nsDeleteObserved::RemoveDeleteObserver(nsDeleteObserver* aDeleteObserver)
|
||||||
|
{
|
||||||
|
if (mDeleteObserverArray)
|
||||||
|
return mDeleteObserverArray->RemoveElement(aDeleteObserver);
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 DeleteObserver_h__
|
||||||
|
#define DeleteObserver_h__
|
||||||
|
|
||||||
|
#include "prtypes.h"
|
||||||
|
class nsVoidArray;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This is a small utility class which allows to notify an object
|
||||||
|
// (the "observer") holding a reference on another object
|
||||||
|
// (the "observed") that the observed object has been deleted.
|
||||||
|
//
|
||||||
|
// As you imagine, it's reserved to cases where XPCOM refCouting doesn't fit.
|
||||||
|
// It is used by the MacEventHandler and the Toolkit to hold references
|
||||||
|
// on the focused widget and the the last widget hit.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class nsDeleteObserver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void NotifyDelete(void* aDeletedObject) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class nsDeleteObserved
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsDeleteObserved(void* aObject);
|
||||||
|
virtual ~nsDeleteObserved();
|
||||||
|
|
||||||
|
PRBool AddDeleteObserver(nsDeleteObserver* aDeleteObserver);
|
||||||
|
PRBool RemoveDeleteObserver(nsDeleteObserver* aDeleteObserver);
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsVoidArray* mDeleteObserverArray;
|
||||||
|
void* mObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DeleteObserver_h__
|
|
@ -0,0 +1,899 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mike Pinkerton
|
||||||
|
// Netscape Communications
|
||||||
|
//
|
||||||
|
// See associated header file for details
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "nsDragService.h"
|
||||||
|
|
||||||
|
#include "nsITransferable.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsMimeMapper.h"
|
||||||
|
#include "nsClipboard.h"
|
||||||
|
#include "nsIRegion.h"
|
||||||
|
#include "nsVoidArray.h"
|
||||||
|
#include "nsISupportsPrimitives.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsXPIDLString.h"
|
||||||
|
#include "nsPrimitiveHelpers.h"
|
||||||
|
#ifndef XP_MACOSX
|
||||||
|
#include "nsILocalFileMac.h"
|
||||||
|
#endif
|
||||||
|
#include "nsWatchTask.h"
|
||||||
|
|
||||||
|
// rjc
|
||||||
|
#include <Gestalt.h>
|
||||||
|
#include "nsIContent.h"
|
||||||
|
#include "nsIDOMNode.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIPresShell.h"
|
||||||
|
#include "nsIPresContext.h"
|
||||||
|
#include "nsIFrame.h"
|
||||||
|
#include "nsIView.h"
|
||||||
|
#include "nsRect.h"
|
||||||
|
#include "nsPoint.h"
|
||||||
|
#include "nsIWidget.h"
|
||||||
|
#include "nsCarbonHelpers.h"
|
||||||
|
|
||||||
|
#include "nsIXULContent.h"
|
||||||
|
#include "nsIDOMElement.h"
|
||||||
|
|
||||||
|
|
||||||
|
// we need our own stuff for MacOS because of nsIDragSessionMac.
|
||||||
|
NS_IMPL_ADDREF_INHERITED(nsDragService, nsBaseDragService)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(nsDragService, nsBaseDragService)
|
||||||
|
NS_IMPL_QUERY_INTERFACE3(nsDragService, nsIDragService, nsIDragSession, nsIDragSessionMac)
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// DragService constructor
|
||||||
|
//
|
||||||
|
nsDragService::nsDragService()
|
||||||
|
: mDragRef(0), mDataItems(nsnull), mImageDraggingSupported(PR_FALSE), mDragSendDataUPP(nsnull)
|
||||||
|
{
|
||||||
|
#if USE_TRANSLUCENT_DRAGS
|
||||||
|
// check if the Drag Manager supports image dragging
|
||||||
|
// however, it doesn't really work too well, so let's back off (pinkerton)
|
||||||
|
long response;
|
||||||
|
OSErr err = Gestalt(gestaltDragMgrAttr, &response);
|
||||||
|
if (err == noErr && (response & (1L << gestaltDragMgrHasImageSupport))) {
|
||||||
|
mImageDraggingSupported = PR_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mDragSendDataUPP = NewDragSendDataUPP(DragSendDataProc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// DragService destructor
|
||||||
|
//
|
||||||
|
nsDragService::~nsDragService()
|
||||||
|
{
|
||||||
|
if ( mDragSendDataUPP )
|
||||||
|
::DisposeDragSendDataUPP(mDragSendDataUPP);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsDragService :: ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outScreenRect )
|
||||||
|
{
|
||||||
|
NS_ASSERTION ( aDOMNode, "Oopps, no DOM node" );
|
||||||
|
|
||||||
|
// this isn't so much of an issue as long as we're just dragging around outlines,
|
||||||
|
// but it is when we are showing the text being drawn. Comment it out for now
|
||||||
|
// but leave it around when we turn this all back on (pinkerton).
|
||||||
|
#if USE_TRANSLUCENT_DRAGGING
|
||||||
|
// until bug 41237 is fixed, only do translucent dragging if the drag is in
|
||||||
|
// the chrome or it's a link.
|
||||||
|
nsCOMPtr<nsIXULContent> xulContent ( do_QueryInterface(aDOMNode) );
|
||||||
|
if ( !xulContent ) {
|
||||||
|
// the link node is the parent of the node we have (which is probably text or image).
|
||||||
|
nsCOMPtr<nsIDOMNode> parent;
|
||||||
|
aDOMNode->GetParentNode ( getter_AddRefs(parent) );
|
||||||
|
if ( parent ) {
|
||||||
|
nsAutoString localName;
|
||||||
|
parent->GetLocalName ( localName );
|
||||||
|
if ( ! localName.Equals(NS_LITERAL_STRING("A")) )
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PRBool haveRectFlag = PR_FALSE;
|
||||||
|
outScreenRect.left = outScreenRect.right = outScreenRect.top = outScreenRect.bottom = 0;
|
||||||
|
|
||||||
|
// Get the frame for this content node (note: frames are not refcounted)
|
||||||
|
nsIFrame *aFrame = nsnull;
|
||||||
|
nsCOMPtr<nsIPresContext> presContext;
|
||||||
|
GetFrameFromNode ( aDOMNode, &aFrame, getter_AddRefs(presContext) );
|
||||||
|
if ( !aFrame || !presContext )
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now that we have the frame, we have to convert its coordinates into global screen
|
||||||
|
// coordinates.
|
||||||
|
//
|
||||||
|
|
||||||
|
nsRect aRect(0,0,0,0);
|
||||||
|
nsIView *parentView = nsnull;
|
||||||
|
aFrame->GetRect(aRect);
|
||||||
|
|
||||||
|
// Find offset from our view
|
||||||
|
nsIView *containingView = nsnull;
|
||||||
|
nsPoint viewOffset(0,0);
|
||||||
|
aFrame->GetOffsetFromView(presContext, viewOffset, &containingView);
|
||||||
|
NS_ASSERTION(containingView, "No containing view!");
|
||||||
|
if ( !containingView )
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// get the widget associated with the containing view.
|
||||||
|
nsCOMPtr<nsIWidget> aWidget;
|
||||||
|
nscoord widgetOffsetX = 0, widgetOffsetY = 0;
|
||||||
|
containingView->GetOffsetFromWidget ( &widgetOffsetX, &widgetOffsetY, *getter_AddRefs(aWidget) );
|
||||||
|
if (aWidget) {
|
||||||
|
float t2p = 1.0;
|
||||||
|
presContext->GetTwipsToPixels(&t2p);
|
||||||
|
|
||||||
|
// GetOffsetFromWidget() actually returns the _parent's_ offset from its widget, so we
|
||||||
|
// still have to add in the offset to |containingView|'s parent ourselves.
|
||||||
|
nscoord viewOffsetToParentX = 0, viewOffsetToParentY = 0;
|
||||||
|
containingView->GetPosition ( &viewOffsetToParentX, &viewOffsetToParentY );
|
||||||
|
|
||||||
|
// Shift our offset rect by offset into our view, the view's offset to its parent, and
|
||||||
|
// the parent's offset to the closest widget. Then convert that to global coordinates.
|
||||||
|
// Recall that WidgetToScreen() will give us the global coordinates of the rectangle we
|
||||||
|
// give it, but it expects everything to be in pixels.
|
||||||
|
nsRect screenOffset;
|
||||||
|
screenOffset.MoveBy ( NSTwipsToIntPixels(widgetOffsetX + viewOffsetToParentX + viewOffset.x, t2p),
|
||||||
|
NSTwipsToIntPixels(widgetOffsetY + viewOffsetToParentY + viewOffset.y, t2p) );
|
||||||
|
aWidget->WidgetToScreen ( screenOffset, screenOffset );
|
||||||
|
|
||||||
|
// stash it all in a mac rect
|
||||||
|
outScreenRect.left = screenOffset.x;
|
||||||
|
outScreenRect.top = screenOffset.y;
|
||||||
|
outScreenRect.right = outScreenRect.left + NSTwipsToIntPixels(aRect.width, t2p);
|
||||||
|
outScreenRect.bottom = outScreenRect.top + NSTwipsToIntPixels(aRect.height, t2p);
|
||||||
|
|
||||||
|
haveRectFlag = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return haveRectFlag;
|
||||||
|
|
||||||
|
} // ComputeGlobalRectFromFrame
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// StartDragSession
|
||||||
|
//
|
||||||
|
// Do all the work to kick it off.
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDragService :: InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * aTransferableArray, nsIScriptableRegion * aDragRgn, PRUint32 aActionType)
|
||||||
|
{
|
||||||
|
::InitCursor();
|
||||||
|
nsBaseDragService::InvokeDragSession ( aDOMNode, aTransferableArray, aDragRgn, aActionType );
|
||||||
|
|
||||||
|
DragReference theDragRef;
|
||||||
|
OSErr result = ::NewDrag(&theDragRef);
|
||||||
|
if ( result != noErr )
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
mDragRef = theDragRef;
|
||||||
|
#if DEBUG_DD
|
||||||
|
printf("**** created drag ref %ld\n", theDragRef);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// add the flavors from the transferables. Cache this array for the send data proc
|
||||||
|
mDataItems = aTransferableArray;
|
||||||
|
RegisterDragItemsAndFlavors ( aTransferableArray ) ;
|
||||||
|
|
||||||
|
Rect frameRect = { 0, 0, 0, 0 };
|
||||||
|
RgnHandle theDragRgn = ::NewRgn();
|
||||||
|
::RectRgn(theDragRgn, &frameRect);
|
||||||
|
|
||||||
|
if ( mImageDraggingSupported ) {
|
||||||
|
Point imgOffsetPt;
|
||||||
|
imgOffsetPt.v = imgOffsetPt.h = 0;
|
||||||
|
|
||||||
|
PRBool canUseRect = BuildDragRegion ( aDragRgn, aDOMNode, theDragRgn );
|
||||||
|
if ( canUseRect ) {
|
||||||
|
// passing in null for image's PixMapHandle to SetDragImage() means use bits on screen
|
||||||
|
::SetDragImage (theDragRef, nsnull, theDragRgn, imgOffsetPt, kDragDarkerTranslucency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BuildDragRegion ( aDragRgn, aDOMNode, theDragRgn );
|
||||||
|
|
||||||
|
// we have to synthesize the native event because we may be called from JavaScript
|
||||||
|
// through XPConnect. In that case, we only have a DOM event and no way to
|
||||||
|
// get to the native event. As a consequence, we just always fake it.
|
||||||
|
EventRecord theEvent;
|
||||||
|
theEvent.what = mouseDown;
|
||||||
|
theEvent.message = 0L;
|
||||||
|
theEvent.when = 0L;
|
||||||
|
theEvent.modifiers = 0L;
|
||||||
|
|
||||||
|
// since we don't have the original mouseDown location, just assume the drag
|
||||||
|
// started in the middle of the frame. This prevents us from having the mouse
|
||||||
|
// and the region we're dragging separated by a big gap (which could happen if
|
||||||
|
// we used the current mouse position). I know this isn't exactly right, and you can
|
||||||
|
// see it if you're paying attention, but who pays such close attention?
|
||||||
|
Rect dragRect;
|
||||||
|
::GetRegionBounds(theDragRgn, &dragRect);
|
||||||
|
theEvent.where.v = rint(dragRect.top + (dragRect.bottom - dragRect.top) / 2);
|
||||||
|
theEvent.where.h = rint(dragRect.left + (dragRect.right - dragRect.left) / 2);
|
||||||
|
|
||||||
|
// register drag send proc which will call us back when asked for the actual
|
||||||
|
// flavor data (instead of placing it all into the drag manager)
|
||||||
|
::SetDragSendProc ( theDragRef, mDragSendDataUPP, this );
|
||||||
|
|
||||||
|
// start the drag. Be careful, mDragRef will be invalid AFTER this call (it is
|
||||||
|
// reset by the dragTrackingHandler).
|
||||||
|
StartDragSession();
|
||||||
|
::TrackDrag ( theDragRef, &theEvent, theDragRgn );
|
||||||
|
EndDragSession();
|
||||||
|
|
||||||
|
// clean up after ourselves
|
||||||
|
::DisposeRgn ( theDragRgn );
|
||||||
|
result = ::DisposeDrag ( theDragRef );
|
||||||
|
#if DEBUG_DD
|
||||||
|
printf("**** disposing drag ref %ld\n", theDragRef);
|
||||||
|
#endif
|
||||||
|
NS_ASSERTION ( result == noErr, "Error disposing drag" );
|
||||||
|
mDragRef = 0L;
|
||||||
|
mDataItems = nsnull;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
} // StartDragSession
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// BuildDragRegion
|
||||||
|
//
|
||||||
|
// Given the XP region describing the drag rectangles, build up an appropriate drag region. If
|
||||||
|
// the region we're given is null, try the given DOM node. If that doesn't work fake it as
|
||||||
|
// best we can.
|
||||||
|
//
|
||||||
|
// Returns PR_TRUE if the region is something that can be used with SetDragImage()
|
||||||
|
//
|
||||||
|
PRBool
|
||||||
|
nsDragService :: BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* inNode, RgnHandle ioDragRgn )
|
||||||
|
{
|
||||||
|
PRBool retVal = PR_TRUE;
|
||||||
|
nsCOMPtr<nsIRegion> geckoRegion;
|
||||||
|
if ( inRegion )
|
||||||
|
inRegion->GetRegion(getter_AddRefs(geckoRegion));
|
||||||
|
|
||||||
|
// create the drag region. Pull out the native mac region from the nsIRegion we're
|
||||||
|
// given, copy it, inset it one pixel, and subtract them so we're left with just an
|
||||||
|
// outline. Too bad we can't do this with gfx api's.
|
||||||
|
//
|
||||||
|
// At the end, we are left with an outline of the region in global coordinates.
|
||||||
|
if ( geckoRegion ) {
|
||||||
|
RgnHandle dragRegion = nsnull;
|
||||||
|
geckoRegion->GetNativeRegion((void*&)dragRegion);
|
||||||
|
if ( dragRegion && ioDragRgn ) {
|
||||||
|
::CopyRgn ( dragRegion, ioDragRgn );
|
||||||
|
::InsetRgn ( ioDragRgn, 1, 1 );
|
||||||
|
::DiffRgn ( dragRegion, ioDragRgn, ioDragRgn );
|
||||||
|
|
||||||
|
// now shift the region into global coordinates.
|
||||||
|
Point offsetFromLocalToGlobal = { 0, 0 };
|
||||||
|
::LocalToGlobal ( &offsetFromLocalToGlobal );
|
||||||
|
::OffsetRgn ( ioDragRgn, offsetFromLocalToGlobal.h, offsetFromLocalToGlobal.v );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PRBool useRectFromFrame = PR_FALSE;
|
||||||
|
|
||||||
|
// no region provided, let's try to use the dom node to get the frame. Pick a
|
||||||
|
// silly default in case we can't get it.
|
||||||
|
Point currMouse;
|
||||||
|
::GetMouse(&currMouse);
|
||||||
|
Rect frameRect = { currMouse.v, currMouse.h, currMouse.v + 25, currMouse.h + 100 };
|
||||||
|
if ( inNode )
|
||||||
|
useRectFromFrame = ComputeGlobalRectFromFrame ( inNode, frameRect );
|
||||||
|
else
|
||||||
|
NS_WARNING ( "Can't find anything to get a drag rect from. I'm dyin' out here!" );
|
||||||
|
|
||||||
|
if ( ioDragRgn ) {
|
||||||
|
RgnHandle frameRgn = ::NewRgn();
|
||||||
|
if ( frameRgn ) {
|
||||||
|
::RectRgn ( frameRgn, &frameRect );
|
||||||
|
::CopyRgn ( frameRgn, ioDragRgn );
|
||||||
|
::InsetRgn ( ioDragRgn, 1, 1 );
|
||||||
|
::DiffRgn ( frameRgn, ioDragRgn, ioDragRgn );
|
||||||
|
|
||||||
|
::DisposeRgn ( frameRgn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we couldn't find the exact frame coordinates, then we need to alert people that
|
||||||
|
// they shouldn't use this as the basis of SetDragImage()
|
||||||
|
retVal = useRectFromFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
|
||||||
|
} // BuildDragRegion
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// RegisterDragItemsAndFlavors
|
||||||
|
//
|
||||||
|
// Takes the multiple drag items from an array of transferables and registers them
|
||||||
|
// and their flavors with the MacOS DragManager. Note that we don't actually place
|
||||||
|
// any of the data there yet, but will rely on a sendDataProc to get the data as
|
||||||
|
// requested.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray )
|
||||||
|
{
|
||||||
|
const FlavorFlags flags = 0;
|
||||||
|
|
||||||
|
unsigned int numDragItems = 0;
|
||||||
|
inArray->Count ( &numDragItems ) ;
|
||||||
|
for ( int itemIndex = 0; itemIndex < numDragItems; ++itemIndex ) {
|
||||||
|
nsMimeMapperMac theMapper;
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> genericItem;
|
||||||
|
inArray->GetElementAt ( itemIndex, getter_AddRefs(genericItem) );
|
||||||
|
nsCOMPtr<nsITransferable> currItem ( do_QueryInterface(genericItem) );
|
||||||
|
if ( currItem ) {
|
||||||
|
nsCOMPtr<nsISupportsArray> flavorList;
|
||||||
|
if ( NS_SUCCEEDED(currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList))) ) {
|
||||||
|
PRUint32 numFlavors;
|
||||||
|
flavorList->Count ( &numFlavors );
|
||||||
|
for ( int flavorIndex = 0; flavorIndex < numFlavors; ++flavorIndex ) {
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> genericWrapper;
|
||||||
|
flavorList->GetElementAt ( flavorIndex, getter_AddRefs(genericWrapper) );
|
||||||
|
nsCOMPtr<nsISupportsString> currentFlavor ( do_QueryInterface(genericWrapper) );
|
||||||
|
if ( currentFlavor ) {
|
||||||
|
nsXPIDLCString flavorStr;
|
||||||
|
currentFlavor->ToString ( getter_Copies(flavorStr) );
|
||||||
|
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr);
|
||||||
|
::AddDragItemFlavor ( mDragRef, itemIndex, macOSFlavor, NULL, 0, flags );
|
||||||
|
|
||||||
|
// If we advertise text/unicode, then make sure we add 'TEXT' to the list
|
||||||
|
// of flavors supported since we will do the conversion ourselves in GetDataForFlavor()
|
||||||
|
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||||
|
theMapper.MapMimeTypeToMacOSType(kTextMime);
|
||||||
|
::AddDragItemFlavor ( mDragRef, itemIndex, 'TEXT', NULL, 0, flags );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // foreach flavor in item
|
||||||
|
} // if valid flavor list
|
||||||
|
} // if item is a transferable
|
||||||
|
|
||||||
|
// put the mime mapping data for this item in a special flavor. Unlike the other data,
|
||||||
|
// we have to put the data in now (rather than defer it) or the mappings will go out
|
||||||
|
// of scope by the time they are asked for. Remember that the |mappingLen|
|
||||||
|
// includes the null, and we need to maintain that for when we parse it.
|
||||||
|
short mappingLen;
|
||||||
|
char* mapping = theMapper.ExportMapping(&mappingLen);
|
||||||
|
if ( mapping && mappingLen ) {
|
||||||
|
::AddDragItemFlavor ( mDragRef, itemIndex, nsMimeMapperMac::MappingFlavor(),
|
||||||
|
mapping, mappingLen, flags );
|
||||||
|
nsCRT::free ( mapping );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // foreach drag item
|
||||||
|
|
||||||
|
} // RegisterDragItemsAndFlavors
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetData
|
||||||
|
//
|
||||||
|
// Pull data out of the OS drag item at the requested index and stash it into the
|
||||||
|
// given transferable. Only put in the data with the highest fidelity asked for and
|
||||||
|
// stop as soon as we find a match.
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDragService :: GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex )
|
||||||
|
{
|
||||||
|
nsresult errCode = NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// make sure we have a good transferable
|
||||||
|
if ( !aTransferable )
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
|
// get flavor list that includes all acceptable flavors (including ones obtained through
|
||||||
|
// conversion). Flavors are nsISupportsStrings so that they can be seen from JS.
|
||||||
|
nsCOMPtr<nsISupportsArray> flavorList;
|
||||||
|
errCode = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) );
|
||||||
|
if ( NS_FAILED(errCode) )
|
||||||
|
return errCode;
|
||||||
|
|
||||||
|
// get the data for the requested drag item. Remember that GetDragItemReferenceNumber()
|
||||||
|
// is one-based NOT zero-based like |aItemIndex| is.
|
||||||
|
ItemReference itemRef;
|
||||||
|
::GetDragItemReferenceNumber ( mDragRef, aItemIndex + 1, &itemRef );
|
||||||
|
|
||||||
|
// create a mime mapper to help us out based on data in a special flavor for this item
|
||||||
|
char* mappings = LookupMimeMappingsForItem(mDragRef, itemRef);
|
||||||
|
nsMimeMapperMac theMapper ( mappings );
|
||||||
|
nsCRT::free ( mappings );
|
||||||
|
|
||||||
|
// Now walk down the list of flavors. When we find one that is actually present,
|
||||||
|
// copy out the data into the transferable in that format. SetTransferData()
|
||||||
|
// implicitly handles conversions.
|
||||||
|
PRUint32 cnt;
|
||||||
|
flavorList->Count ( &cnt );
|
||||||
|
for ( int i = 0; i < cnt; ++i ) {
|
||||||
|
nsCOMPtr<nsISupports> genericWrapper;
|
||||||
|
flavorList->GetElementAt ( i, getter_AddRefs(genericWrapper) );
|
||||||
|
nsCOMPtr<nsISupportsString> currentFlavor ( do_QueryInterface(genericWrapper) );
|
||||||
|
if ( currentFlavor ) {
|
||||||
|
// find MacOS flavor (but don't add it if it's not there)
|
||||||
|
nsXPIDLCString flavorStr;
|
||||||
|
currentFlavor->ToString ( getter_Copies(flavorStr) );
|
||||||
|
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr, PR_FALSE);
|
||||||
|
#if DEBUG_DD
|
||||||
|
printf("looking for data in type %s, mac flavor %ld\n", NS_STATIC_CAST(const char*,flavorStr), macOSFlavor);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check if it is present in the current drag item.
|
||||||
|
FlavorFlags unused;
|
||||||
|
PRBool dataFound = PR_FALSE;
|
||||||
|
void* dataBuff;
|
||||||
|
PRInt32 dataSize = 0;
|
||||||
|
if ( macOSFlavor && ::GetFlavorFlags(mDragRef, itemRef, macOSFlavor, &unused) == noErr ) {
|
||||||
|
nsresult loadResult = ExtractDataFromOS(mDragRef, itemRef, macOSFlavor, &dataBuff, &dataSize);
|
||||||
|
if ( NS_SUCCEEDED(loadResult) && dataBuff )
|
||||||
|
dataFound = PR_TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// if we are looking for text/unicode and we fail to find it on the clipboard first,
|
||||||
|
// try again with text/plain. If that is present, convert it to unicode.
|
||||||
|
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||||
|
if ( ::GetFlavorFlags(mDragRef, itemRef, 'TEXT', &unused) == noErr ) {
|
||||||
|
nsresult loadResult = ExtractDataFromOS(mDragRef, itemRef, 'TEXT', &dataBuff, &dataSize);
|
||||||
|
if ( NS_SUCCEEDED(loadResult) && dataBuff ) {
|
||||||
|
const char* castedText = NS_REINTERPRET_CAST(char*, dataBuff);
|
||||||
|
PRUnichar* convertedText = nsnull;
|
||||||
|
PRInt32 convertedTextLen = 0;
|
||||||
|
nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize,
|
||||||
|
&convertedText, &convertedTextLen );
|
||||||
|
if ( convertedText ) {
|
||||||
|
// out with the old, in with the new
|
||||||
|
nsMemory::Free(dataBuff);
|
||||||
|
dataBuff = convertedText;
|
||||||
|
dataSize = convertedTextLen * 2;
|
||||||
|
dataFound = PR_TRUE;
|
||||||
|
}
|
||||||
|
} // if plain text data on clipboard
|
||||||
|
} // if plain text flavor present
|
||||||
|
} // if looking for text/unicode
|
||||||
|
} // else we try one last ditch effort to find our data
|
||||||
|
|
||||||
|
if ( dataFound ) {
|
||||||
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||||
|
if ( strcmp(flavorStr, kFileMime) == 0 ) {
|
||||||
|
// we have a HFSFlavor struct in |dataBuff|. Create an nsLocalFileMac object.
|
||||||
|
HFSFlavor* fileData = NS_REINTERPRET_CAST(HFSFlavor*, dataBuff);
|
||||||
|
NS_ASSERTION ( sizeof(HFSFlavor) == dataSize, "Ooops, we realy don't have a HFSFlavor" );
|
||||||
|
#ifndef XP_MACOSX
|
||||||
|
nsCOMPtr<nsILocalFileMac> file;
|
||||||
|
if ( NS_SUCCEEDED(NS_NewLocalFileWithFSSpec(&fileData->fileSpec, PR_TRUE, getter_AddRefs(file))) )
|
||||||
|
genericDataWrapper = do_QueryInterface(file);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we probably have some form of text. The DOM only wants LF, so convert k
|
||||||
|
// from MacOS line endings to DOM line endings.
|
||||||
|
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &dataBuff, NS_REINTERPRET_CAST(int*, &dataSize) );
|
||||||
|
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, dataBuff, dataSize, getter_AddRefs(genericDataWrapper) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// put it into the transferable.
|
||||||
|
errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize );
|
||||||
|
#ifdef NS_DEBUG
|
||||||
|
if ( errCode != NS_OK ) printf("nsDragService:: Error setting data into transferable\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsMemory::Free ( dataBuff );
|
||||||
|
errCode = NS_OK;
|
||||||
|
|
||||||
|
// we found one, get out of this loop!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // foreach flavor
|
||||||
|
|
||||||
|
return errCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// IsDataFlavorSupported
|
||||||
|
//
|
||||||
|
// Check the OS to see if the given drag flavor is in the list. Oddly returns
|
||||||
|
// NS_OK for success and NS_ERROR_FAILURE if flavor is not present.
|
||||||
|
//
|
||||||
|
// Handle the case where we ask for unicode and it's not there, but plain text is. We
|
||||||
|
// say "yes" in that case, knowing that we will have to perform a conversion when we actually
|
||||||
|
// pull the data out of the drag.
|
||||||
|
//
|
||||||
|
// ¥¥¥ this is obviously useless with more than one drag item. Need to specify
|
||||||
|
// ¥¥¥Êand index to this API
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDragService :: IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)
|
||||||
|
{
|
||||||
|
if ( !_retval )
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
|
#ifdef NS_DEBUG
|
||||||
|
if ( strcmp(aDataFlavor, kTextMime) == 0 )
|
||||||
|
NS_WARNING ( "DO NOT USE THE text/plain DATA FLAVOR ANY MORE. USE text/unicode INSTEAD" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*_retval = PR_FALSE;
|
||||||
|
|
||||||
|
// search through all drag items looking for something with this flavor. Recall
|
||||||
|
// that drag item indices are 1-based.
|
||||||
|
unsigned short numDragItems = 0;
|
||||||
|
::CountDragItems ( mDragRef, &numDragItems );
|
||||||
|
for ( int i = 1; i <= numDragItems; ++i ) {
|
||||||
|
ItemReference currItem;
|
||||||
|
OSErr res = ::GetDragItemReferenceNumber ( mDragRef, i, &currItem );
|
||||||
|
if ( res != noErr )
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// convert to 4 character MacOS type for this item
|
||||||
|
char* mappings = LookupMimeMappingsForItem(mDragRef, currItem) ;
|
||||||
|
nsMimeMapperMac theMapper ( mappings );
|
||||||
|
FlavorType macFlavor = theMapper.MapMimeTypeToMacOSType(aDataFlavor, PR_FALSE);
|
||||||
|
nsMemory::Free(mappings);
|
||||||
|
|
||||||
|
FlavorFlags ignored;
|
||||||
|
if ( ::GetFlavorFlags(mDragRef, currItem, macFlavor, &ignored) == noErr )
|
||||||
|
*_retval = PR_TRUE;
|
||||||
|
else {
|
||||||
|
// if the client asked for unicode and it wasn't present, check if we have TEXT.
|
||||||
|
// We'll handle the actual data substitution in GetDataForFlavor().
|
||||||
|
if ( strcmp(aDataFlavor, kUnicodeMime) == 0 ) {
|
||||||
|
if ( ::GetFlavorFlags(mDragRef, currItem, 'TEXT', &ignored) == noErr )
|
||||||
|
*_retval = PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // for each item in drag
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
} // IsDataFlavorSupported
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetNumDropItems
|
||||||
|
//
|
||||||
|
// Returns the number of drop items present in the current drag.
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDragService :: GetNumDropItems ( PRUint32 * aNumItems )
|
||||||
|
{
|
||||||
|
// we have to put it into a short first because that's what the MacOS API's expect.
|
||||||
|
// After it's in a short, getting it into a long is no problem. Oh well.
|
||||||
|
unsigned short numDragItems = 0;
|
||||||
|
OSErr result = ::CountDragItems ( mDragRef, &numDragItems );
|
||||||
|
*aNumItems = numDragItems;
|
||||||
|
|
||||||
|
return ( result == noErr ? NS_OK : NS_ERROR_FAILURE );
|
||||||
|
|
||||||
|
} // GetNumDropItems
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// SetDragReference
|
||||||
|
//
|
||||||
|
// An API to allow the drag manager callback functions to tell the session about the
|
||||||
|
// current dragRef w/out resorting to knowing the internals of the implementation
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDragService :: SetDragReference ( DragReference aDragRef )
|
||||||
|
{
|
||||||
|
mDragRef = aDragRef;
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
} // SetDragReference
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// DragSendDataProc
|
||||||
|
//
|
||||||
|
// Called when a drop occurs and the drop site asks for the data.
|
||||||
|
//
|
||||||
|
// This will only get called when Mozilla is the originator of the drag, so we can
|
||||||
|
// make certain assumptions. One is that we've cached the list of transferables in the
|
||||||
|
// drag session. The other is that the item ref is the index into this list so we
|
||||||
|
// can easily pull out the item asked for.
|
||||||
|
//
|
||||||
|
// We cannot rely on |mDragRef| at this point so we have to use what was passed in
|
||||||
|
// and pass that along.
|
||||||
|
//
|
||||||
|
pascal OSErr
|
||||||
|
nsDragService :: DragSendDataProc ( FlavorType inFlavor, void* inRefCon, ItemReference inItemRef,
|
||||||
|
DragReference inDragRef )
|
||||||
|
{
|
||||||
|
OSErr retVal = noErr;
|
||||||
|
nsDragService* self = NS_STATIC_CAST(nsDragService*, inRefCon);
|
||||||
|
NS_ASSERTION ( self, "Refcon not set correctly for DragSendDataProc" );
|
||||||
|
if ( self ) {
|
||||||
|
void* data = nsnull;
|
||||||
|
PRUint32 dataSize = 0;
|
||||||
|
retVal = self->GetDataForFlavor ( self->mDataItems, inDragRef, inItemRef, inFlavor, &data, &dataSize );
|
||||||
|
if ( retVal == noErr ) {
|
||||||
|
// make the data accessable to the DragManager
|
||||||
|
retVal = ::SetDragItemFlavorData ( inDragRef, inItemRef, inFlavor, data, dataSize, 0 );
|
||||||
|
NS_ASSERTION ( retVal == noErr, "SDIFD failed in DragSendDataProc" );
|
||||||
|
}
|
||||||
|
nsMemory::Free ( data );
|
||||||
|
} // if valid refcon
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
|
||||||
|
} // DragSendDataProc
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetDataForFlavor
|
||||||
|
//
|
||||||
|
// Given a MacOS flavor and an index for which drag item to lookup, get the information from the
|
||||||
|
// drag item corresponding to this flavor.
|
||||||
|
//
|
||||||
|
// This routine also handles the conversions between text/plain and text/unicode to take platform
|
||||||
|
// charset encodings into account. If someone asks for text/plain, we convert the unicode (we assume
|
||||||
|
// it is present because that's how we knew to advertise text/plain in the first place) and give it
|
||||||
|
// to them. If someone asks for text/unicode, and it isn't there, we need to convert text/plain and
|
||||||
|
// hand them back the unicode. Again, we can assume that text/plain is there because otherwise we
|
||||||
|
// wouldn't have been allowed to look for unicode.
|
||||||
|
//
|
||||||
|
OSErr
|
||||||
|
nsDragService :: GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference inDragRef, unsigned int inItemIndex,
|
||||||
|
FlavorType inFlavor, void** outData, unsigned int* outDataSize )
|
||||||
|
{
|
||||||
|
if ( !inDragItems || !inDragRef )
|
||||||
|
return paramErr;
|
||||||
|
|
||||||
|
OSErr retVal = noErr;
|
||||||
|
|
||||||
|
// (assumes that the items were placed into the transferable as nsITranferable*'s, not nsISupports*'s.)
|
||||||
|
nsCOMPtr<nsISupports> genericItem;
|
||||||
|
inDragItems->GetElementAt ( inItemIndex, getter_AddRefs(genericItem) );
|
||||||
|
nsCOMPtr<nsITransferable> item ( do_QueryInterface(genericItem) );
|
||||||
|
if ( item ) {
|
||||||
|
nsCAutoString mimeFlavor;
|
||||||
|
|
||||||
|
// create a mime mapper to help us out based on data in a special flavor for this item.
|
||||||
|
char* mappings = LookupMimeMappingsForItem(inDragRef, inItemIndex) ;
|
||||||
|
nsMimeMapperMac theMapper ( mappings );
|
||||||
|
theMapper.MapMacOSTypeToMimeType ( inFlavor, mimeFlavor );
|
||||||
|
nsMemory::Free ( mappings );
|
||||||
|
|
||||||
|
// if someone was asking for text/plain, lookup unicode instead so we can convert it.
|
||||||
|
PRBool needToDoConversionToPlainText = PR_FALSE;
|
||||||
|
const char* actualFlavor = mimeFlavor;
|
||||||
|
if ( strcmp(mimeFlavor,kTextMime) == 0 ) {
|
||||||
|
actualFlavor = kUnicodeMime;
|
||||||
|
needToDoConversionToPlainText = PR_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
actualFlavor = mimeFlavor;
|
||||||
|
|
||||||
|
*outDataSize = 0;
|
||||||
|
nsCOMPtr<nsISupports> data;
|
||||||
|
if ( NS_SUCCEEDED(item->GetTransferData(actualFlavor, getter_AddRefs(data), outDataSize)) ) {
|
||||||
|
nsPrimitiveHelpers::CreateDataFromPrimitive ( actualFlavor, data, outData, *outDataSize );
|
||||||
|
|
||||||
|
// if required, do the extra work to convert unicode to plain text and replace the output
|
||||||
|
// values with the plain text.
|
||||||
|
if ( needToDoConversionToPlainText ) {
|
||||||
|
char* plainTextData = nsnull;
|
||||||
|
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, *outData);
|
||||||
|
PRInt32 plainTextLen = 0;
|
||||||
|
nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, *outDataSize / 2, &plainTextData, &plainTextLen );
|
||||||
|
if ( *outData ) {
|
||||||
|
nsMemory::Free(*outData);
|
||||||
|
*outData = plainTextData;
|
||||||
|
*outDataSize = plainTextLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = cantGetFlavorErr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = cantGetFlavorErr;
|
||||||
|
} // if valid item
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
|
||||||
|
} // GetDataForFlavor
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// LookupMimeMappingsForItem
|
||||||
|
//
|
||||||
|
// load up the flavor data for the mime mapper from the drag item and create a
|
||||||
|
// mime mapper to help us go between mime types and macOS flavors. It may not be
|
||||||
|
// there (such as when the drag originated from another app), but that's ok.
|
||||||
|
//
|
||||||
|
// Caller is responsible for deleting the memory.
|
||||||
|
//
|
||||||
|
char*
|
||||||
|
nsDragService :: LookupMimeMappingsForItem ( DragReference inDragRef, ItemReference inItemRef )
|
||||||
|
{
|
||||||
|
char* mapperData = nsnull;
|
||||||
|
PRInt32 mapperSize = 0;
|
||||||
|
ExtractDataFromOS(inDragRef, inItemRef, nsMimeMapperMac::MappingFlavor(), (void**)&mapperData, &mapperSize);
|
||||||
|
|
||||||
|
return mapperData;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
OSErr err = ::GetFlavorDataSize ( inDragRef, itemRef, nsMimeMapperMac::MappingFlavor(), &mapperSize );
|
||||||
|
if ( !err && mapperSize > 0 ) {
|
||||||
|
mapperData = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(mapperSize + 1));
|
||||||
|
if ( !mapperData )
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
err = ::GetFlavorData ( inDragRef, itemRef, nsMimeMapperMac::MappingFlavor(), mapperData, &mapperSize, 0 );
|
||||||
|
if ( err ) {
|
||||||
|
#ifdef NS_DEBUG
|
||||||
|
printf("nsDragService: Error getting data out of drag manager for mime mapper, #%ld\n", err);
|
||||||
|
#endif
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mapperData[mapperSize] = '\0'; // null terminate the data
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapperData;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ExtractDataFromOS
|
||||||
|
//
|
||||||
|
// Handles pulling the data from the DragManager. Will return NS_ERROR_FAILURE if it can't get
|
||||||
|
// the data for whatever reason.
|
||||||
|
//
|
||||||
|
nsresult
|
||||||
|
nsDragService :: ExtractDataFromOS ( DragReference inDragRef, ItemReference inItemRef, ResType inFlavor,
|
||||||
|
void** outBuffer, PRInt32* outBuffSize )
|
||||||
|
{
|
||||||
|
if ( !outBuffer || !outBuffSize || !inFlavor )
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsresult retval = NS_OK;
|
||||||
|
char* buff = nsnull;
|
||||||
|
Size buffSize = 0;
|
||||||
|
OSErr err = ::GetFlavorDataSize ( inDragRef, inItemRef, inFlavor, &buffSize );
|
||||||
|
if ( !err && buffSize > 0 ) {
|
||||||
|
buff = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(buffSize + 1));
|
||||||
|
if ( buff ) {
|
||||||
|
err = ::GetFlavorData ( inDragRef, inItemRef, inFlavor, buff, &buffSize, 0 );
|
||||||
|
if ( err ) {
|
||||||
|
#ifdef NS_DEBUG
|
||||||
|
printf("nsDragService: Error getting data out of drag manager, #%ld\n", err);
|
||||||
|
#endif
|
||||||
|
retval = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retval = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( NS_FAILED(retval) ) {
|
||||||
|
if ( buff )
|
||||||
|
nsMemory::Free(buff);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*outBuffer = buff;
|
||||||
|
*outBuffSize = buffSize;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
} // ExtractDataFromOS
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// StartDragSession
|
||||||
|
// EndDragSession
|
||||||
|
//
|
||||||
|
// Override the defaults to disable/enable the watch cursor while we're dragging
|
||||||
|
//
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDragService :: StartDragSession ( )
|
||||||
|
{
|
||||||
|
nsWatchTask::GetTask().Suspend();
|
||||||
|
|
||||||
|
return nsBaseDragService::StartDragSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDragService :: EndDragSession ( )
|
||||||
|
{
|
||||||
|
nsWatchTask::GetTask().Resume();
|
||||||
|
|
||||||
|
return nsBaseDragService::EndDragSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// SetDragAction
|
||||||
|
//
|
||||||
|
// Override to set the cursor to the appropriate feedback when the
|
||||||
|
// drag action changes based on modifier keys
|
||||||
|
//
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDragService :: SetDragAction ( PRUint32 anAction )
|
||||||
|
{
|
||||||
|
const PRInt32 kCopyCursorID = 144;
|
||||||
|
const PRInt32 kLinkCursorID = 145;
|
||||||
|
|
||||||
|
// don't do the work if it's the same.
|
||||||
|
if ( anAction == mDragAction )
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
CursHandle newCursor = nsnull;
|
||||||
|
if ( anAction == DRAGDROP_ACTION_COPY )
|
||||||
|
newCursor = ::GetCursor ( kCopyCursorID );
|
||||||
|
else if ( anAction == DRAGDROP_ACTION_LINK )
|
||||||
|
newCursor = ::GetCursor ( kLinkCursorID );
|
||||||
|
if ( newCursor ) {
|
||||||
|
::HLock((Handle)newCursor);
|
||||||
|
::SetCursor ( *newCursor );
|
||||||
|
::HUnlock((Handle)newCursor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
::InitCursor();
|
||||||
|
|
||||||
|
return nsBaseDragService::SetDragAction(anAction);
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mike Pinkerton
|
||||||
|
// Netscape Communications
|
||||||
|
//
|
||||||
|
// The MacOS native implementation of nsIDragService, nsIDragSession, and
|
||||||
|
// nsIDragSessionMac.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef nsDragService_h__
|
||||||
|
#define nsDragService_h__
|
||||||
|
|
||||||
|
|
||||||
|
#include "nsBaseDragService.h"
|
||||||
|
#include "nsIDragSessionMac.h"
|
||||||
|
#include <Drag.h>
|
||||||
|
#include <MacWindows.h>
|
||||||
|
|
||||||
|
class nsNativeDragTarget;
|
||||||
|
|
||||||
|
|
||||||
|
class nsDragService : public nsBaseDragService, public nsIDragSessionMac
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsDragService();
|
||||||
|
virtual ~nsDragService();
|
||||||
|
|
||||||
|
//nsISupports - can't use inherited because of nsIDragSessionMac
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
//nsIDragService
|
||||||
|
NS_IMETHOD InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * anArrayTransferables, nsIScriptableRegion * aRegion, PRUint32 aActionType);
|
||||||
|
|
||||||
|
//nsIDragSession
|
||||||
|
NS_IMETHOD GetData (nsITransferable * aTransferable, PRUint32 aItemIndex);
|
||||||
|
NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval);
|
||||||
|
NS_IMETHOD GetNumDropItems (PRUint32 * aNumItems);
|
||||||
|
NS_IMETHOD SetDragAction ( PRUint32 anAction ) ;
|
||||||
|
|
||||||
|
//nsIDragSessionMac
|
||||||
|
NS_IMETHOD SetDragReference ( DragReference aDragRef ) ;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NS_IMETHOD StartDragSession ( ) ;
|
||||||
|
NS_IMETHOD EndDragSession ( ) ;
|
||||||
|
|
||||||
|
char* LookupMimeMappingsForItem ( DragReference inDragRef, ItemReference itemRef ) ;
|
||||||
|
|
||||||
|
void RegisterDragItemsAndFlavors ( nsISupportsArray * inArray ) ;
|
||||||
|
PRBool BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* inNode, RgnHandle ioDragRgn ) ;
|
||||||
|
OSErr GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference inDragRef, unsigned int inItemIndex,
|
||||||
|
FlavorType inFlavor, void** outData, unsigned int * outSize ) ;
|
||||||
|
nsresult ExtractDataFromOS ( DragReference inDragRef, ItemReference inItemRef, ResType inFlavor,
|
||||||
|
void** outBuffer, PRInt32* outBuffSize ) ;
|
||||||
|
|
||||||
|
// compute a screen rect from the frame associated with the given dom node
|
||||||
|
PRBool ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outScreenRect ) ;
|
||||||
|
|
||||||
|
// callback for the MacOS DragManager when a drop site asks for data
|
||||||
|
static pascal OSErr DragSendDataProc ( FlavorType inFlavor, void* inRefCon,
|
||||||
|
ItemReference theItemRef, DragReference inDragRef ) ;
|
||||||
|
|
||||||
|
PRBool mImageDraggingSupported;
|
||||||
|
DragSendDataUPP mDragSendDataUPP;
|
||||||
|
DragReference mDragRef; // reference to _the_ drag. There can be only one.
|
||||||
|
nsISupportsArray* mDataItems; // cached here for when we start the drag so the
|
||||||
|
// DragSendDataProc has access to them.
|
||||||
|
// ONLY VALID DURING A DRAG STARTED WITHIN THIS APP.
|
||||||
|
|
||||||
|
}; // class nsDragService
|
||||||
|
|
||||||
|
|
||||||
|
#endif // nsDragService_h__
|
||||||
|
|
|
@ -0,0 +1,600 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 "nsDynamicMDEF.h"
|
||||||
|
|
||||||
|
#include "prinrval.h"
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIDOMElement.h"
|
||||||
|
#include "nsIDOMNode.h"
|
||||||
|
#include "nsMenuBar.h"
|
||||||
|
#include "nsIMenuBar.h"
|
||||||
|
#include "DefProcFakery.h"
|
||||||
|
#include "nsGUIEvent.h"
|
||||||
|
|
||||||
|
#include <Resources.h>
|
||||||
|
#include <MixedMode.h>
|
||||||
|
|
||||||
|
extern nsWeakPtr gMacMenubar;
|
||||||
|
|
||||||
|
|
||||||
|
// needed for CallMenuDefProc() to work correctly
|
||||||
|
#pragma options align=mac68k
|
||||||
|
|
||||||
|
|
||||||
|
// Caching the Mac menu
|
||||||
|
nsVoidArray gPreviousMenuHandleStack; // hold MenuHandles
|
||||||
|
nsMenuStack gPreviousMenuStack; // weak refs
|
||||||
|
nsWeakPtr gPreviousMenuBar; // weak ref
|
||||||
|
|
||||||
|
MenuHandle gSizedMenu = nsnull;
|
||||||
|
|
||||||
|
|
||||||
|
extern Handle gMDEF;
|
||||||
|
bool gTested = false;
|
||||||
|
|
||||||
|
MenuHandle gCachedMenuHandle = nsnull;
|
||||||
|
PRUint16 gCachedMenuID = 0;
|
||||||
|
|
||||||
|
extern PRInt16 gMenuDepth; // volital running total
|
||||||
|
extern PRInt16 gCurrentMenuDepth; // The menu depth that is currently shown
|
||||||
|
extern MenuHandle gLevel2HierMenu;
|
||||||
|
extern MenuHandle gLevel3HierMenu;
|
||||||
|
extern MenuHandle gLevel4HierMenu;
|
||||||
|
extern MenuHandle gLevel5HierMenu;
|
||||||
|
|
||||||
|
PRUint32 gCurrentMenuItem = 0; // 1 based ala MacOS
|
||||||
|
PRUint32 gCurrentTopLevelMenuIndex = 0;
|
||||||
|
MenuHandle gPreviousTopLevelMenuHandle = nsnull;
|
||||||
|
nsIMenu * gPreviousTopLevelMenu = nsnull;
|
||||||
|
nsIMenu * gPreviousMenu = nsnull;
|
||||||
|
MenuHandle gPreviousMenuHandle = nsnull;
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
nsMenuStack::nsMenuStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMenuStack::~nsMenuStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsMenuStack::GetMenuAt(PRInt32 aIndex, nsIMenu **outMenu)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupports> elementPtr = getter_AddRefs(mMenuArray.ElementAt(aIndex));
|
||||||
|
if (!elementPtr)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(elementPtr);
|
||||||
|
return weakRef->QueryReferent(NS_GET_IID(nsIMenu), NS_REINTERPRET_CAST(void**, outMenu));
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsMenuStack::HaveMenuAt(PRInt32 aIndex)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupports> elementPtr = getter_AddRefs(mMenuArray.ElementAt(aIndex));
|
||||||
|
if (!elementPtr)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(elementPtr);
|
||||||
|
nsCOMPtr<nsIMenu> theMenu = do_QueryReferent(weakRef);
|
||||||
|
return (theMenu.get() != nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsMenuStack::RemoveMenuAt(PRInt32 aIndex)
|
||||||
|
{
|
||||||
|
return mMenuArray.RemoveElementAt(aIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsMenuStack::InsertMenuAt(nsIMenu* inMenuItem, PRInt32 aIndex)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupportsWeakReference> weakRefFactory = do_QueryInterface(inMenuItem);
|
||||||
|
if (!weakRefFactory) return NS_ERROR_NULL_POINTER;
|
||||||
|
nsCOMPtr<nsISupports> observerRef = getter_AddRefs(NS_STATIC_CAST(nsISupports*, NS_GetWeakReference(weakRefFactory)));
|
||||||
|
if (!observerRef) return NS_ERROR_NULL_POINTER;
|
||||||
|
return mMenuArray.InsertElementAt(observerRef, aIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Internal functions
|
||||||
|
|
||||||
|
void nsDynamicChooseItem(
|
||||||
|
MenuHandle theMenu,
|
||||||
|
Rect * menuRect,
|
||||||
|
Point hitPt,
|
||||||
|
short * whichItem);
|
||||||
|
|
||||||
|
void nsDynamicSizeTheMenu(
|
||||||
|
MenuHandle theMenu);
|
||||||
|
|
||||||
|
void nsBuildMenu(
|
||||||
|
MenuHandle theMenu,
|
||||||
|
PRBool isChild);
|
||||||
|
|
||||||
|
void nsPushMenu(
|
||||||
|
nsIMenu * aMenu);
|
||||||
|
|
||||||
|
void nsPopMenu(
|
||||||
|
nsIMenu ** aMenu);
|
||||||
|
|
||||||
|
void nsPushMenuHandle(
|
||||||
|
MenuHandle aMenu);
|
||||||
|
|
||||||
|
void nsPopMenuHandle(
|
||||||
|
MenuHandle * aMenu);
|
||||||
|
|
||||||
|
void nsCallSystemMDEF(
|
||||||
|
short message,
|
||||||
|
MenuHandle theMenu,
|
||||||
|
Rect * menuRect,
|
||||||
|
Point hitPt,
|
||||||
|
short * whichItem);
|
||||||
|
|
||||||
|
void nsDoMagic(
|
||||||
|
MenuHandle theMenu);
|
||||||
|
|
||||||
|
void nsPostBuild(
|
||||||
|
nsIMenu * menu,
|
||||||
|
MenuHandle theMenu,
|
||||||
|
PRBool isChild);
|
||||||
|
|
||||||
|
bool nsIsHierChild(
|
||||||
|
MenuHandle theMenu);
|
||||||
|
|
||||||
|
void nsCheckDestroy(
|
||||||
|
MenuHandle theMenu,
|
||||||
|
short * whichItem);
|
||||||
|
|
||||||
|
//void TestPreviousMenuStackUnwind(nsIMenu * aMenuJustBuilt, MenuHandle aMenuHandleJustBuilt);
|
||||||
|
//void TestCheckDestroy(MenuHandle theMenu, short * whichItem);
|
||||||
|
//void TestPostBuild(nsIMenu * menu, MenuHandle theMenu, PRBool isChild);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
pascal void nsDynamicMDEFMain(
|
||||||
|
short message,
|
||||||
|
MenuHandle theMenu,
|
||||||
|
Rect * menuRect,
|
||||||
|
Point hitPt,
|
||||||
|
short * whichItem)
|
||||||
|
{
|
||||||
|
switch (message) {
|
||||||
|
case kMenuDrawMsg:
|
||||||
|
//printf(" Draw passed in menu is = %d \n", *theMenu);
|
||||||
|
//printf(" t= %d l= %d b= %d r= %d\n", (*menuRect).top, (*menuRect).left, (*menuRect).bottom, (*menuRect).right);
|
||||||
|
//printf(" Point.v = %d Point.h = %d\n", hitPt.v, hitPt.h);
|
||||||
|
//printf(" whichItem = %d \n", *whichItem);
|
||||||
|
//printf(" theMenu.menuID = %d \n", (**theMenu).menuID);
|
||||||
|
|
||||||
|
nsCheckDestroy(theMenu, whichItem);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMenuChooseMsg:
|
||||||
|
// Keep track of currently chosen item
|
||||||
|
nsDynamicChooseItem(theMenu, menuRect, hitPt, whichItem);
|
||||||
|
return; // Yes, intentional return as CallSystemMDEF has happened already
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMenuSizeMsg:
|
||||||
|
//printf("Size passed in menu is = %d \n", *theMenu);
|
||||||
|
//printf(" t= %d l= %d b= %d r= %d \n", (*menuRect).top, (*menuRect).left, (*menuRect).bottom ,(*menuRect).right);
|
||||||
|
//printf(" Point.v = %d Point.h = %d \n", hitPt.v, hitPt.h);
|
||||||
|
//printf(" whichItem = %d \n", *whichItem);
|
||||||
|
//printf(" theMenu.menuID = %d \n", (**theMenu).menuID);
|
||||||
|
|
||||||
|
nsCheckDestroy(theMenu, whichItem);
|
||||||
|
|
||||||
|
// Need to make sure that we rebuild the menu every time...
|
||||||
|
if (gPreviousMenuHandleStack.Count())
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIMenu> menu;
|
||||||
|
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(menu));
|
||||||
|
// nsIMenu * menu = (nsIMenu *) gPreviousMenuStack[gPreviousMenuStack.Count() - 1];
|
||||||
|
MenuHandle menuHandle = (MenuHandle) gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1];
|
||||||
|
|
||||||
|
//printf(" gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
|
||||||
|
//printf(" gPreviousMenuHandleStack.Count() = %d \n", gPreviousMenuHandleStack.Count());
|
||||||
|
|
||||||
|
if( menu && menuHandle ) {
|
||||||
|
|
||||||
|
if( menuHandle == theMenu ) {
|
||||||
|
|
||||||
|
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(menu));
|
||||||
|
if(listener) {
|
||||||
|
//printf("MenuPop \n");
|
||||||
|
|
||||||
|
nsMenuEvent mevent;
|
||||||
|
mevent.message = NS_MENU_SELECTED;
|
||||||
|
mevent.eventStructType = NS_MENU_EVENT;
|
||||||
|
mevent.point.x = 0;
|
||||||
|
mevent.point.y = 0;
|
||||||
|
mevent.widget = nsnull;
|
||||||
|
mevent.time = PR_IntervalNow();
|
||||||
|
mevent.mCommand = (PRUint32) nsnull;
|
||||||
|
|
||||||
|
// UNDO
|
||||||
|
listener->MenuDeselected(mevent);
|
||||||
|
|
||||||
|
//gPreviousMenuStack.RemoveElementAt(gPreviousMenuStack.Count() - 1);
|
||||||
|
gPreviousMenuStack.RemoveMenuAt(gPreviousMenuStack.Count() - 1);
|
||||||
|
//NS_IF_RELEASE(menu);
|
||||||
|
|
||||||
|
//printf("%d items now on gPreviousMenuStack \n", gPreviousMenuStack.Count());
|
||||||
|
gPreviousMenuHandleStack.RemoveElementAt(gPreviousMenuHandleStack.Count() - 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsDynamicSizeTheMenu(theMenu);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nsCallSystemMDEF(message, theMenu, menuRect, hitPt, whichItem);
|
||||||
|
|
||||||
|
// Force a size message next time we draw this menu
|
||||||
|
if(message == kMenuDrawMsg) {
|
||||||
|
#if !TARGET_CARBON
|
||||||
|
(**theMenu).menuWidth = -1;
|
||||||
|
(**theMenu).menuHeight = -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsCheckDestroy(MenuHandle theMenu, short * whichItem)
|
||||||
|
{
|
||||||
|
// Determine if we have unselected the previous popup. If so we need to
|
||||||
|
// destroy it now.
|
||||||
|
bool changeOccured = true;
|
||||||
|
bool isChild = false;
|
||||||
|
|
||||||
|
if(gCurrentMenuItem == *whichItem)
|
||||||
|
changeOccured = false;
|
||||||
|
|
||||||
|
if(!gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1])
|
||||||
|
changeOccured = false;
|
||||||
|
|
||||||
|
if(nsIsHierChild(theMenu))
|
||||||
|
isChild = true;
|
||||||
|
|
||||||
|
if(changeOccured && !isChild) {
|
||||||
|
|
||||||
|
nsPreviousMenuStackUnwind(nsnull, theMenu);
|
||||||
|
|
||||||
|
if(gCurrentMenuDepth > 1)
|
||||||
|
gCurrentMenuDepth--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsDynamicChooseItem(
|
||||||
|
MenuHandle theMenu,
|
||||||
|
Rect * menuRect,
|
||||||
|
Point hitPt,
|
||||||
|
short * whichItem)
|
||||||
|
{
|
||||||
|
//printf("enter DynamicChooseItem \n");
|
||||||
|
nsCallSystemMDEF(kMenuChooseMsg, theMenu, menuRect, hitPt, whichItem);
|
||||||
|
|
||||||
|
nsCheckDestroy(theMenu, whichItem);
|
||||||
|
|
||||||
|
gCurrentMenuItem = *whichItem;
|
||||||
|
|
||||||
|
//printf("exit DynamicChooseItem \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsDynamicSizeTheMenu(
|
||||||
|
MenuHandle theMenu)
|
||||||
|
{
|
||||||
|
//printf("enter DynamicSizeTheMenu \n");
|
||||||
|
|
||||||
|
nsDoMagic(theMenu);
|
||||||
|
//printf("exit DynamicSizeTheMenu \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool nsIsHierChild(MenuHandle theMenu)
|
||||||
|
{
|
||||||
|
if(theMenu == gLevel2HierMenu) {
|
||||||
|
if(gCurrentMenuDepth <= 2) return true;
|
||||||
|
} else if(theMenu == gLevel3HierMenu) {
|
||||||
|
if(gCurrentMenuDepth <= 3) return true;
|
||||||
|
} else if(theMenu == gLevel4HierMenu) {
|
||||||
|
if(gCurrentMenuDepth <= 4) return true;
|
||||||
|
} else if(theMenu == gLevel5HierMenu) {
|
||||||
|
if(gCurrentMenuDepth <= 5) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsDoMagic(MenuHandle theMenu)
|
||||||
|
{
|
||||||
|
//printf("DoMagic \n");
|
||||||
|
// ask if this is a child of the previous menu
|
||||||
|
PRBool isChild = PR_FALSE;
|
||||||
|
|
||||||
|
if (gPreviousMenuStack.Count() > 0)
|
||||||
|
{
|
||||||
|
if (gPreviousMenuStack.HaveMenuAt(gPreviousMenuStack.Count() - 1)) {
|
||||||
|
if(nsIsHierChild(theMenu)) {
|
||||||
|
isChild = PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(theMenu == gLevel2HierMenu) {
|
||||||
|
gCurrentMenuDepth = 2;
|
||||||
|
} else if(theMenu == gLevel3HierMenu) {
|
||||||
|
gCurrentMenuDepth = 3;
|
||||||
|
} else if(theMenu == gLevel4HierMenu) {
|
||||||
|
gCurrentMenuDepth = 4;
|
||||||
|
} else if(theMenu == gLevel5HierMenu) {
|
||||||
|
gCurrentMenuDepth = 5;
|
||||||
|
} else {
|
||||||
|
gCurrentMenuDepth = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsBuildMenu(theMenu, isChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsBuildMenu(MenuHandle theMenu, PRBool isChild)
|
||||||
|
{
|
||||||
|
// printf("enter BuildMenu \n");
|
||||||
|
nsCOMPtr<nsIMenuBar> menubar = do_QueryReferent(gMacMenubar);
|
||||||
|
if (!menubar || !theMenu) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMenuEvent mevent;
|
||||||
|
mevent.message = NS_MENU_SELECTED;
|
||||||
|
mevent.eventStructType = NS_MENU_EVENT;
|
||||||
|
mevent.point.x = 0;
|
||||||
|
mevent.point.y = 0;
|
||||||
|
mevent.widget = nsnull;
|
||||||
|
mevent.time = PR_IntervalNow();
|
||||||
|
mevent.mCommand = (PRUint32) theMenu;
|
||||||
|
|
||||||
|
// If toplevel
|
||||||
|
if( gCurrentMenuDepth < 2 ) {
|
||||||
|
PRUint32 numMenus = 0;
|
||||||
|
menubar->GetMenuCount(numMenus);
|
||||||
|
numMenus--;
|
||||||
|
for(PRInt32 i = numMenus; i >= 0; i--) {
|
||||||
|
nsCOMPtr<nsIMenu> menu;
|
||||||
|
menubar->GetMenuAt(i, *getter_AddRefs(menu));
|
||||||
|
if(menu) {
|
||||||
|
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(menu));
|
||||||
|
if(listener) {
|
||||||
|
// Reset menu depth count
|
||||||
|
gMenuDepth = 0;
|
||||||
|
nsEventStatus status = listener->MenuSelected(mevent);
|
||||||
|
if(status != nsEventStatus_eIgnore)
|
||||||
|
{
|
||||||
|
nsPostBuild(menu, theMenu, isChild);
|
||||||
|
gPreviousTopLevelMenuHandle = theMenu;
|
||||||
|
gPreviousTopLevelMenu = menu;
|
||||||
|
|
||||||
|
gPreviousMenuBar = getter_AddRefs(NS_GetWeakReference(menubar));
|
||||||
|
//printf("exit BuildMenu \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not top level, so we can't use recursive MenuSelect <sigh>
|
||||||
|
// We must use the previously chosen menu item in combination
|
||||||
|
// with the current menu to determine what menu needs to be constructed
|
||||||
|
//printf("gCurrentMenuItem = %d \n", gCurrentMenuItem);
|
||||||
|
if (gCurrentMenuItem){
|
||||||
|
if (gPreviousMenuStack.Count() > 0)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIMenu> prevMenu;
|
||||||
|
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(prevMenu));
|
||||||
|
|
||||||
|
//nsIMenu * prevMenu = (nsIMenu *) gPreviousMenuStack[gPreviousMenuStack.Count() - 1];
|
||||||
|
//printf("gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count() );
|
||||||
|
|
||||||
|
if(prevMenu)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupports> supports;
|
||||||
|
prevMenu->GetItemAt(gCurrentMenuItem - 1, *getter_AddRefs(supports));
|
||||||
|
nsCOMPtr<nsIMenu> menu = do_QueryInterface(supports);
|
||||||
|
if (menu)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIMenuListener> menulistener = do_QueryInterface(menu);
|
||||||
|
menulistener->MenuSelected(mevent);
|
||||||
|
nsPostBuild(menu, theMenu, isChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//printf("exit BuildMenu \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsPostBuild(nsIMenu * menu, MenuHandle theMenu, PRBool isChild)
|
||||||
|
{
|
||||||
|
// it is built now
|
||||||
|
if(isChild || (gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1] != theMenu))
|
||||||
|
{
|
||||||
|
nsPushMenu(menu);
|
||||||
|
nsPushMenuHandle(theMenu);
|
||||||
|
//printf("Push: %d items in gMenuHandleStack \n", gMenuHandleStack.Count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsCallSystemMDEF(
|
||||||
|
short message,
|
||||||
|
MenuHandle theMenu,
|
||||||
|
Rect * menuRect,
|
||||||
|
Point hitPt,
|
||||||
|
short * whichItem)
|
||||||
|
{
|
||||||
|
// extract the real system mdef out of the fake one we've stored in the menu
|
||||||
|
Handle fakedMDEF = (**theMenu).menuProc;
|
||||||
|
Handle systemDefProc = DefProcFakery::GetSystemDefProc ( fakedMDEF );
|
||||||
|
|
||||||
|
SInt8 state = ::HGetState(systemDefProc);
|
||||||
|
::HLock(systemDefProc);
|
||||||
|
|
||||||
|
// can't use NewMenuDefProc() here because the routine descriptor has to use kM68kISA
|
||||||
|
CallMenuDefProc((RoutineDescriptorPtr)*systemDefProc, message, theMenu, menuRect, hitPt, whichItem);
|
||||||
|
|
||||||
|
::HSetState(systemDefProc, state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsPushMenu(nsIMenu *aMenu)
|
||||||
|
{
|
||||||
|
gPreviousMenuStack.InsertMenuAt(aMenu, gPreviousMenuStack.Count());
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsPopMenu(nsIMenu ** aMenu)
|
||||||
|
{
|
||||||
|
if(gPreviousMenuStack.Count() > 0)
|
||||||
|
{
|
||||||
|
// *aMenu = (nsIMenu *) gPreviousMenuStack[gPreviousMenuStack.Count() - 1];
|
||||||
|
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, aMenu);
|
||||||
|
gPreviousMenuStack.RemoveMenuAt(gPreviousMenuStack.Count() - 1);
|
||||||
|
} else
|
||||||
|
*aMenu = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsPreviousMenuStackUnwind(nsIMenu * aMenuJustBuilt, MenuHandle aMenuHandleJustBuilt)
|
||||||
|
{
|
||||||
|
//PRBool shouldReleaseMenubar = PR_FALSE;
|
||||||
|
|
||||||
|
//printf("PreviousMenuStackUnwind called \n");
|
||||||
|
//printf("%d items on gPreviousMenuStack \n", gPreviousMenuStack.Count());
|
||||||
|
while (gPreviousMenuHandleStack.Count())
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIMenu> menu; // = (nsIMenu *) gPreviousMenuStack[gPreviousMenuStack.Count() - 1];
|
||||||
|
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(menu));
|
||||||
|
|
||||||
|
MenuHandle menuHandle = (MenuHandle) gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1];
|
||||||
|
|
||||||
|
if (menu)
|
||||||
|
{
|
||||||
|
|
||||||
|
//printf(" gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
|
||||||
|
//printf(" gPreviousMenuHandleStack.Count() = %d \n", gPreviousMenuHandleStack.Count());
|
||||||
|
|
||||||
|
if( menuHandle ) {
|
||||||
|
|
||||||
|
if( menuHandle != aMenuHandleJustBuilt ) {
|
||||||
|
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(menu));
|
||||||
|
if(listener) {
|
||||||
|
nsMenuEvent mevent;
|
||||||
|
mevent.message = NS_MENU_SELECTED;
|
||||||
|
mevent.eventStructType = NS_MENU_EVENT;
|
||||||
|
mevent.point.x = 0;
|
||||||
|
mevent.point.y = 0;
|
||||||
|
mevent.widget = nsnull;
|
||||||
|
mevent.time = PR_IntervalNow();
|
||||||
|
mevent.mCommand = (PRUint32) nsnull;
|
||||||
|
|
||||||
|
// UNDO
|
||||||
|
listener->MenuDeselected(mevent);
|
||||||
|
|
||||||
|
//gPreviousMenuStack.RemoveElementAt(gPreviousMenuStack.Count() - 1);
|
||||||
|
gPreviousMenuStack.RemoveMenuAt(gPreviousMenuStack.Count() - 1);
|
||||||
|
// NS_IF_RELEASE(menu);
|
||||||
|
//shouldReleaseMenubar = PR_TRUE;
|
||||||
|
|
||||||
|
//printf("%d items now on gPreviousMenuStack \n", gPreviousMenuStack.Count());
|
||||||
|
gPreviousMenuHandleStack.RemoveElementAt(gPreviousMenuHandleStack.Count() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//printf(" gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
|
||||||
|
//printf(" gPreviousMenuHandleStack.Count() = %d \n", gPreviousMenuHandleStack.Count());
|
||||||
|
|
||||||
|
// we are the aMenuHandleJustBuilt
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remove the weak ref
|
||||||
|
gPreviousMenuStack.RemoveMenuAt(gPreviousMenuStack.Count() - 1);
|
||||||
|
NS_ASSERTION(menuHandle != aMenuHandleJustBuilt, "Got the menu handle just built");
|
||||||
|
if( menuHandle )
|
||||||
|
gPreviousMenuHandleStack.RemoveElementAt(gPreviousMenuHandleStack.Count() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// relinquish hold of the menubar _after_ releasing the menu so it can finish
|
||||||
|
// unregistering itself.
|
||||||
|
//if ( shouldReleaseMenubar )
|
||||||
|
// gPreviousMenuBar = nsnull;
|
||||||
|
|
||||||
|
//printf(" gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
|
||||||
|
//printf(" gPreviousMenuHandleStack.Count() = %d \n", gPreviousMenuHandleStack.Count());
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsPushMenuHandle(MenuHandle aMenu)
|
||||||
|
{
|
||||||
|
gPreviousMenuHandleStack.AppendElement(aMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void nsPopMenuHandle(MenuHandle * aMenu)
|
||||||
|
{
|
||||||
|
*aMenu = (MenuHandle) gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1];
|
||||||
|
gPreviousMenuHandleStack.RemoveElementAt(gPreviousMenuHandleStack.Count() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma options align=reset
|
|
@ -0,0 +1,125 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
// MDEF for doing dynamic menu construction
|
||||||
|
|
||||||
|
#ifndef nsDynamicMDEF_h__
|
||||||
|
#define nsDynamicMDEF_h__
|
||||||
|
|
||||||
|
#include "nsSupportsArray.h"
|
||||||
|
#include "nsIMenu.h"
|
||||||
|
|
||||||
|
#include <Menus.h>
|
||||||
|
|
||||||
|
pascal void nsDynamicMDEFMain(
|
||||||
|
short message,
|
||||||
|
MenuHandle theMenu,
|
||||||
|
Rect * menuRect,
|
||||||
|
Point hitPt,
|
||||||
|
short * whichItem);
|
||||||
|
|
||||||
|
void nsPreviousMenuStackUnwind(
|
||||||
|
nsIMenu * aMenuJustBuilt,
|
||||||
|
MenuHandle aMenuHandleJustBuilt);
|
||||||
|
|
||||||
|
|
||||||
|
// helper class useful for counting instances
|
||||||
|
class nsInstanceCounter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsInstanceCounter(const char* inDesc)
|
||||||
|
: mInstanceCount(0)
|
||||||
|
, mDescription(inDesc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~nsInstanceCounter()
|
||||||
|
{
|
||||||
|
printf("%s %ld\n", mDescription, mInstanceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsInstanceCounter& operator ++() // prefix
|
||||||
|
{
|
||||||
|
++ mInstanceCount;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsInstanceCounter& operator -- () // prefix
|
||||||
|
{
|
||||||
|
-- mInstanceCount;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
PRInt32 mInstanceCount;
|
||||||
|
const char* mDescription;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class nsMenuStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsMenuStack();
|
||||||
|
~nsMenuStack();
|
||||||
|
|
||||||
|
|
||||||
|
PRInt32 Count()
|
||||||
|
{
|
||||||
|
PRUint32 num;
|
||||||
|
mMenuArray.Count(&num);
|
||||||
|
return (PRInt32)num;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns addreffed nsIMenu
|
||||||
|
nsresult GetMenuAt(PRInt32 aIndex, nsIMenu **outMenu);
|
||||||
|
PRBool HaveMenuAt(PRInt32 aIndex);
|
||||||
|
PRBool RemoveMenuAt(PRInt32 aIndex); // no release
|
||||||
|
PRBool InsertMenuAt(nsIMenu* aElement, PRInt32 aIndex); // no addrefs; weak ref.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
nsSupportsArray mMenuArray; // array of weak refs to nsIMenus
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif nsDynamicMDEF_h__
|
|
@ -0,0 +1,734 @@
|
||||||
|
/* -*- 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 Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Stuart Parmenter <pavlov@netscape.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsReadableUtils.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
|
#include "nsIComponentManager.h"
|
||||||
|
#include "nsILocalFile.h"
|
||||||
|
#ifndef XP_MACOSX
|
||||||
|
#include "nsILocalFileMac.h"
|
||||||
|
#endif
|
||||||
|
#include "nsIURL.h"
|
||||||
|
#include "nsVoidArray.h"
|
||||||
|
#include "nsIFileChannel.h"
|
||||||
|
|
||||||
|
#include <InternetConfig.h>
|
||||||
|
|
||||||
|
#include "nsCarbonHelpers.h"
|
||||||
|
|
||||||
|
#include "nsFilePicker.h"
|
||||||
|
#include "nsWatchTask.h"
|
||||||
|
|
||||||
|
#include "nsIInternetConfigService.h"
|
||||||
|
#include "nsIMIMEInfo.h"
|
||||||
|
|
||||||
|
#include "nsIPlatformCharset.h"
|
||||||
|
#include "nsICharsetConverterManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// copied over from nsMacControl since we it's not being built.
|
||||||
|
//
|
||||||
|
|
||||||
|
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
|
||||||
|
|
||||||
|
static void GetFileSystemCharset(nsString & fileSystemCharset);
|
||||||
|
static void GetFileSystemCharset(nsString & fileSystemCharset)
|
||||||
|
{
|
||||||
|
static nsAutoString aCharset;
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
if (aCharset.Length() < 1) {
|
||||||
|
nsCOMPtr <nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &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.AssignWithConversion("x-mac-roman");
|
||||||
|
}
|
||||||
|
fileSystemCharset = aCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void StringToStr255(const nsString& aText, Str255& aStr255) ;
|
||||||
|
static void StringToStr255(const nsString& aText, Str255& aStr255)
|
||||||
|
{
|
||||||
|
static nsIUnicodeEncoder* sUnicodeEncoder = nsnull;
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
// get file system charset and create a unicode encoder
|
||||||
|
if (!sUnicodeEncoder) {
|
||||||
|
nsAutoString fileSystemCharset;
|
||||||
|
GetFileSystemCharset(fileSystemCharset);
|
||||||
|
|
||||||
|
nsCOMPtr<nsICharsetConverterManager> ccm =
|
||||||
|
do_GetService(kCharsetConverterManagerCID, &rv);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
rv = ccm->GetUnicodeEncoder(&fileSystemCharset, &sUnicodeEncoder);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
rv = sUnicodeEncoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nsnull, (PRUnichar)'?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// converts from unicode to the file system charset
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
PRInt32 inLength = aText.Length();
|
||||||
|
PRInt32 outLength = 255;
|
||||||
|
rv = sUnicodeEncoder->Convert(aText.get(), &inLength, (char *) &aStr255[1], &outLength);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
aStr255[0] = outLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
// NS_ASSERTION(0, "error: charset covnersion");
|
||||||
|
NS_LossyConvertUCS2toASCII buffer(Substring(aText,0,254));
|
||||||
|
PRInt32 len = buffer.Length();
|
||||||
|
memcpy(&aStr255[1], buffer.get(), len);
|
||||||
|
aStr255[0] = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// nsFilePicker constructor
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsFilePicker::nsFilePicker()
|
||||||
|
: mAllFilesDisplayed(PR_TRUE)
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
|
// Zero out the type lists
|
||||||
|
for (int i = 0; i < kMaxTypeListCount; i++)
|
||||||
|
mTypeLists[i] = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// nsFilePicker destructor
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsFilePicker::~nsFilePicker()
|
||||||
|
{
|
||||||
|
// Destroy any filters we have built
|
||||||
|
if ( mFilters.Count() ) {
|
||||||
|
for (int i = 0; i < kMaxTypeListCount; i++) {
|
||||||
|
if (mTypeLists[i])
|
||||||
|
DisposePtr((Ptr)mTypeLists[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mFilters.Clear();
|
||||||
|
mTitles.Clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsFilePicker::InitNative(nsIWidget *aParent, const PRUnichar *aTitle, PRInt16 aMode)
|
||||||
|
{
|
||||||
|
mTitle = aTitle;
|
||||||
|
mMode = aMode;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Ok's the dialog
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsFilePicker::OnOk()
|
||||||
|
{
|
||||||
|
mWasCancelled = PR_FALSE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Cancel the dialog
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsFilePicker::OnCancel()
|
||||||
|
{
|
||||||
|
mWasCancelled = PR_TRUE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Show - Display the file dialog
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsFilePicker::Show(PRInt16 *retval)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(retval);
|
||||||
|
|
||||||
|
*retval = returnCancel;
|
||||||
|
|
||||||
|
nsString filterList;
|
||||||
|
char *filterBuffer = ToNewCString(filterList);
|
||||||
|
|
||||||
|
Str255 title;
|
||||||
|
Str255 defaultName;
|
||||||
|
StringToStr255(mTitle,title);
|
||||||
|
StringToStr255(mDefault,defaultName);
|
||||||
|
|
||||||
|
FSSpec theFile;
|
||||||
|
PRInt16 userClicksOK = returnCancel;
|
||||||
|
|
||||||
|
// XXX Ignore the filter list for now....
|
||||||
|
|
||||||
|
if (mMode == modeOpen)
|
||||||
|
userClicksOK = GetLocalFile(title, &theFile);
|
||||||
|
else if (mMode == modeSave)
|
||||||
|
userClicksOK = PutLocalFile(title, defaultName, &theFile);
|
||||||
|
else if (mMode == modeGetFolder)
|
||||||
|
userClicksOK = GetLocalFolder(title, &theFile);
|
||||||
|
|
||||||
|
// Clean up filter buffers
|
||||||
|
delete[] filterBuffer;
|
||||||
|
|
||||||
|
#ifndef XP_MACOSX
|
||||||
|
if (userClicksOK == returnOK || userClicksOK == returnReplace)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsILocalFile> localFile(do_CreateInstance("@mozilla.org/file/local;1"));
|
||||||
|
nsCOMPtr<nsILocalFileMac> macFile(do_QueryInterface(localFile));
|
||||||
|
|
||||||
|
nsresult rv = macFile->InitWithFSSpec(&theFile);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
mFile = do_QueryInterface(macFile);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*retval = userClicksOK;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// FileDialogEventHandlerProc
|
||||||
|
//
|
||||||
|
// An event filter proc for NavServices so the dialogs will be movable-modals.
|
||||||
|
//
|
||||||
|
static pascal void FileDialogEventHandlerProc( NavEventCallbackMessage msg, NavCBRecPtr cbRec, NavCallBackUserData data )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
switch ( msg ) {
|
||||||
|
case kNavCBEvent:
|
||||||
|
switch ( cbRec->eventData.eventDataParms.event->what ) {
|
||||||
|
case updateEvt:
|
||||||
|
WindowPtr window = reinterpret_cast<WindowPtr>(cbRec->eventData.eventDataParms.event->message);
|
||||||
|
nsMacWindow* macWindow = nsMacMessageSink::GetNSWindowFromMacWindow(window);
|
||||||
|
::BeginUpdate(window);
|
||||||
|
if (macWindow) {
|
||||||
|
EventRecord theEvent = *cbRec->eventData.eventDataParms.event;
|
||||||
|
macWindow->HandleOSEvent(theEvent);
|
||||||
|
}
|
||||||
|
::EndUpdate(window);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// IsFileInFilterList
|
||||||
|
//
|
||||||
|
// Check our |mTypeLists| list to see if the given type is in there.
|
||||||
|
//
|
||||||
|
Boolean
|
||||||
|
nsFilePicker :: IsTypeInFilterList ( ResType inType )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < mFilters.Count(); ++i ) {
|
||||||
|
for ( int j = 0; j < mTypeLists[i]->osTypeCount; ++j ) {
|
||||||
|
if ( mTypeLists[i]->osType[j] == inType )
|
||||||
|
return true;
|
||||||
|
} // foreach type w/in the group
|
||||||
|
} // for each filter group
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} // IsFileInFilterList
|
||||||
|
|
||||||
|
|
||||||
|
Boolean
|
||||||
|
nsFilePicker :: IsExtensionInFilterList ( StrFileName & inFileName )
|
||||||
|
{
|
||||||
|
char extension[256];
|
||||||
|
|
||||||
|
// determine the extension from the file name
|
||||||
|
unsigned char* curr = &inFileName[inFileName[0]];
|
||||||
|
while ( curr != inFileName && *curr-- != '.' ) ;
|
||||||
|
if ( curr == inFileName ) // no '.' in string, fails this check
|
||||||
|
return false;
|
||||||
|
++curr; // we took one too many steps back
|
||||||
|
short extensionLen = (inFileName + inFileName[0]) - curr + 1;
|
||||||
|
strncpy ( extension, (char*)curr, extensionLen);
|
||||||
|
extension[extensionLen] = '\0';
|
||||||
|
|
||||||
|
// see if it is in our list
|
||||||
|
for ( int i = 0; i < mFlatFilters.Count(); ++i ) {
|
||||||
|
if ( mFlatFilters[i]->Equals(extension) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// FileDialogFilterProc
|
||||||
|
//
|
||||||
|
// Called from navServices with our filePicker object as |callbackUD|, check our
|
||||||
|
// internal list to see if the file should be displayed.
|
||||||
|
//
|
||||||
|
pascal
|
||||||
|
Boolean
|
||||||
|
nsFilePicker :: FileDialogFilterProc ( AEDesc* theItem, void* theInfo,
|
||||||
|
NavCallBackUserData callbackUD, NavFilterModes filterMode )
|
||||||
|
{
|
||||||
|
Boolean shouldDisplay = true;
|
||||||
|
nsFilePicker* self = NS_REINTERPRET_CAST(nsFilePicker*, callbackUD);
|
||||||
|
if ( self && !self->mAllFilesDisplayed ) {
|
||||||
|
if ( theItem->descriptorType == typeFSS ) {
|
||||||
|
NavFileOrFolderInfo* info = NS_REINTERPRET_CAST ( NavFileOrFolderInfo*, theInfo );
|
||||||
|
if ( !info->isFolder ) {
|
||||||
|
// check it against our list. If that fails, check the extension directly
|
||||||
|
if ( ! self->IsTypeInFilterList(info->fileAndFolder.fileInfo.finderInfo.fdType) ) {
|
||||||
|
FSSpec fileSpec;
|
||||||
|
if ( ::AEGetDescData(theItem, &fileSpec, sizeof(FSSpec)) == noErr )
|
||||||
|
if ( ! self->IsExtensionInFilterList(fileSpec.name) )
|
||||||
|
shouldDisplay = false;
|
||||||
|
}
|
||||||
|
} // if file isn't a folder
|
||||||
|
} // if the item is an FSSpec
|
||||||
|
}
|
||||||
|
|
||||||
|
return shouldDisplay;
|
||||||
|
|
||||||
|
} // FileDialogFilterProc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// GetFile
|
||||||
|
//
|
||||||
|
// Use NavServices to do a GetFile. Returns PR_TRUE if the user presses OK in the dialog. If
|
||||||
|
// they do so, the selected file is in the FSSpec.
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
PRInt16
|
||||||
|
nsFilePicker::GetLocalFile(Str255 & inTitle, /* filter list here later */ FSSpec* outSpec)
|
||||||
|
{
|
||||||
|
PRInt16 retVal = returnCancel;
|
||||||
|
NavReplyRecord reply;
|
||||||
|
NavDialogOptions dialogOptions;
|
||||||
|
NavEventUPP eventProc = NewNavEventUPP(FileDialogEventHandlerProc); // doesn't really matter if this fails
|
||||||
|
NavObjectFilterUPP filterProc = NewNavObjectFilterUPP(FileDialogFilterProc); // doesn't really matter if this fails
|
||||||
|
|
||||||
|
OSErr anErr = NavGetDefaultDialogOptions(&dialogOptions);
|
||||||
|
if (anErr == noErr) {
|
||||||
|
// Set the options for how the get file dialog will appear
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavNoTypePopup;
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavDontAutoTranslate;
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavDontAddTranslateItems;
|
||||||
|
dialogOptions.dialogOptionFlags ^= kNavAllowMultipleFiles;
|
||||||
|
::BlockMoveData(inTitle, dialogOptions.windowTitle, *inTitle + 1);
|
||||||
|
|
||||||
|
// sets up the |mTypeLists| array so the filter proc can use it
|
||||||
|
MapFilterToFileTypes();
|
||||||
|
|
||||||
|
// allow packages to be chosen if the filter is "*"
|
||||||
|
if ( mAllFilesDisplayed )
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavSupportPackages;
|
||||||
|
|
||||||
|
// Display the get file dialog. Only use a filter proc if there are any
|
||||||
|
// filters registered.
|
||||||
|
nsWatchTask::GetTask().Suspend();
|
||||||
|
anErr = ::NavGetFile(
|
||||||
|
NULL,
|
||||||
|
&reply,
|
||||||
|
&dialogOptions,
|
||||||
|
eventProc,
|
||||||
|
NULL, // preview proc
|
||||||
|
mFilters.Count() ? filterProc : NULL,
|
||||||
|
NULL, //typeList,
|
||||||
|
this); // callbackUD - used by the filterProc
|
||||||
|
nsWatchTask::GetTask().Resume();
|
||||||
|
|
||||||
|
// See if the user has selected save
|
||||||
|
if (anErr == noErr && reply.validRecord) {
|
||||||
|
AEKeyword theKeyword;
|
||||||
|
DescType actualType;
|
||||||
|
Size actualSize;
|
||||||
|
FSSpec theFSSpec;
|
||||||
|
|
||||||
|
// Get the FSSpec for the file to be opened
|
||||||
|
anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS, &theKeyword, &actualType,
|
||||||
|
&theFSSpec, sizeof(theFSSpec), &actualSize);
|
||||||
|
|
||||||
|
if (anErr == noErr)
|
||||||
|
{
|
||||||
|
*outSpec = theFSSpec; // Return the FSSpec
|
||||||
|
retVal = returnOK;
|
||||||
|
|
||||||
|
// Some housekeeping for Nav Services
|
||||||
|
::NavDisposeReply(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // if user clicked OK
|
||||||
|
} // if can get dialog options
|
||||||
|
|
||||||
|
if ( eventProc )
|
||||||
|
::DisposeNavEventUPP(eventProc);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
|
||||||
|
} // GetFile
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// GetFolder
|
||||||
|
//
|
||||||
|
// Use NavServices to do a PutFile. Returns PR_TRUE if the user presses OK in the dialog. If
|
||||||
|
// they do so, the folder location is in the FSSpec.
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
PRInt16
|
||||||
|
nsFilePicker::GetLocalFolder(Str255 & inTitle, FSSpec* outSpec)
|
||||||
|
{
|
||||||
|
PRInt16 retVal = returnCancel;
|
||||||
|
NavReplyRecord reply;
|
||||||
|
NavDialogOptions dialogOptions;
|
||||||
|
NavEventUPP eventProc = NewNavEventUPP(FileDialogEventHandlerProc); // doesn't really matter if this fails
|
||||||
|
|
||||||
|
OSErr anErr = NavGetDefaultDialogOptions(&dialogOptions);
|
||||||
|
if (anErr == noErr) {
|
||||||
|
// Set the options for how the get file dialog will appear
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavNoTypePopup;
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavDontAutoTranslate;
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavDontAddTranslateItems;
|
||||||
|
dialogOptions.dialogOptionFlags ^= kNavAllowMultipleFiles;
|
||||||
|
::BlockMoveData(inTitle, dialogOptions.windowTitle, *inTitle + 1);
|
||||||
|
|
||||||
|
// Display the get file dialog
|
||||||
|
nsWatchTask::GetTask().Suspend();
|
||||||
|
anErr = ::NavChooseFolder(
|
||||||
|
NULL,
|
||||||
|
&reply,
|
||||||
|
&dialogOptions,
|
||||||
|
eventProc,
|
||||||
|
NULL, // filter proc
|
||||||
|
NULL); // callbackUD
|
||||||
|
nsWatchTask::GetTask().Resume();
|
||||||
|
|
||||||
|
// See if the user has selected save
|
||||||
|
if (anErr == noErr && reply.validRecord) {
|
||||||
|
AEKeyword theKeyword;
|
||||||
|
DescType actualType;
|
||||||
|
Size actualSize;
|
||||||
|
FSSpec theFSSpec;
|
||||||
|
|
||||||
|
// Get the FSSpec for the file to be opened
|
||||||
|
anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS, &theKeyword, &actualType,
|
||||||
|
&theFSSpec, sizeof(theFSSpec), &actualSize);
|
||||||
|
|
||||||
|
if (anErr == noErr) {
|
||||||
|
*outSpec = theFSSpec; // Return the FSSpec
|
||||||
|
retVal = returnOK;
|
||||||
|
|
||||||
|
// Some housekeeping for Nav Services
|
||||||
|
::NavDisposeReply(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // if user clicked OK
|
||||||
|
} // if can get dialog options
|
||||||
|
|
||||||
|
if ( eventProc )
|
||||||
|
::DisposeNavEventUPP(eventProc);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
} // GetFolder
|
||||||
|
|
||||||
|
PRInt16
|
||||||
|
nsFilePicker::PutLocalFile(Str255 & inTitle, Str255 & inDefaultName, FSSpec* outFileSpec)
|
||||||
|
{
|
||||||
|
PRInt16 retVal = returnCancel;
|
||||||
|
NavReplyRecord reply;
|
||||||
|
NavDialogOptions dialogOptions;
|
||||||
|
NavEventUPP eventProc = NewNavEventUPP(FileDialogEventHandlerProc); // doesn't really matter if this fails
|
||||||
|
OSType typeToSave = 'TEXT';
|
||||||
|
OSType creatorToSave = 'MOZZ';
|
||||||
|
|
||||||
|
OSErr anErr = NavGetDefaultDialogOptions(&dialogOptions);
|
||||||
|
if (anErr == noErr) {
|
||||||
|
// Set the options for how the get file dialog will appear
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavNoTypePopup;
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavDontAutoTranslate;
|
||||||
|
dialogOptions.dialogOptionFlags |= kNavDontAddTranslateItems;
|
||||||
|
dialogOptions.dialogOptionFlags ^= kNavAllowMultipleFiles;
|
||||||
|
::BlockMoveData(inTitle, dialogOptions.windowTitle, *inTitle + 1);
|
||||||
|
::BlockMoveData(inDefaultName, dialogOptions.savedFileName, *inDefaultName + 1);
|
||||||
|
|
||||||
|
// Display the get file dialog
|
||||||
|
nsWatchTask::GetTask().Suspend();
|
||||||
|
anErr = ::NavPutFile(
|
||||||
|
NULL,
|
||||||
|
&reply,
|
||||||
|
&dialogOptions,
|
||||||
|
eventProc,
|
||||||
|
typeToSave,
|
||||||
|
creatorToSave,
|
||||||
|
NULL); // callbackUD
|
||||||
|
nsWatchTask::GetTask().Resume();
|
||||||
|
|
||||||
|
// See if the user has selected save
|
||||||
|
if (anErr == noErr && reply.validRecord)
|
||||||
|
{
|
||||||
|
AEKeyword theKeyword;
|
||||||
|
DescType actualType;
|
||||||
|
Size actualSize;
|
||||||
|
FSSpec theFSSpec;
|
||||||
|
|
||||||
|
// Get the FSSpec for the file to be opened
|
||||||
|
anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS, &theKeyword, &actualType,
|
||||||
|
&theFSSpec, sizeof(theFSSpec), &actualSize);
|
||||||
|
|
||||||
|
if (anErr == noErr) {
|
||||||
|
*outFileSpec = theFSSpec; // Return the FSSpec
|
||||||
|
|
||||||
|
if (reply.replacing)
|
||||||
|
retVal = returnReplace;
|
||||||
|
else
|
||||||
|
retVal = returnOK;
|
||||||
|
|
||||||
|
// Some housekeeping for Nav Services
|
||||||
|
::NavCompleteSave(&reply, kNavTranslateInPlace);
|
||||||
|
::NavDisposeReply(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // if user clicked OK
|
||||||
|
} // if can get dialog options
|
||||||
|
|
||||||
|
if ( eventProc )
|
||||||
|
::DisposeNavEventUPP(eventProc);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MapFilterToFileTypes
|
||||||
|
//
|
||||||
|
// Take the list of file types (in a nice win32-specific format) and ask IC to give us
|
||||||
|
// the MacOS file type codes for them.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsFilePicker :: MapFilterToFileTypes ( )
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIInternetConfigService> icService ( do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID) );
|
||||||
|
NS_ASSERTION(icService, "Can't get InternetConfig Service, bailing out");
|
||||||
|
if ( !icService ) {
|
||||||
|
// We couldn't get the IC Service, bail. Since |mAllFilesDisplayed| is still
|
||||||
|
// set, the dialog will allow selection of all files.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFilters.Count())
|
||||||
|
{
|
||||||
|
// First we allocate the memory for the Mac type lists
|
||||||
|
for (PRUint32 loop1 = 0; loop1 < mFilters.Count() && loop1 < kMaxTypeListCount; loop1++)
|
||||||
|
{
|
||||||
|
mTypeLists[loop1] =
|
||||||
|
(NavTypeListPtr)NewPtrClear(sizeof(NavTypeList) + kMaxTypesPerFilter * sizeof(OSType));
|
||||||
|
if ( !mTypeLists[loop1] )
|
||||||
|
return; // don't worry, we'll clean up in the dtor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now loop through each of the filter strings
|
||||||
|
for (PRUint32 loop1 = 0; loop1 < mFilters.Count(); loop1++)
|
||||||
|
{
|
||||||
|
const nsString& filterWide = *mFilters[loop1];
|
||||||
|
char* filter = ToNewCString(filterWide);
|
||||||
|
|
||||||
|
NS_ASSERTION ( filterWide.Length(), "Oops. filepicker.properties not correctly installed");
|
||||||
|
if ( filterWide.Length() && filter )
|
||||||
|
{
|
||||||
|
PRUint32 filterIndex = 0; // Index into the filter string
|
||||||
|
PRUint32 typeTempIndex = 0; // Index into the temp string for a single filter type
|
||||||
|
PRUint32 typesInThisFilter = 0; // Count for # of types in this filter
|
||||||
|
bool finishedThisFilter = false; // Flag so we know when we're finsihed with the filter
|
||||||
|
char typeTemp[256];
|
||||||
|
char tempChar; // char we're currently looking at
|
||||||
|
|
||||||
|
// Loop through the characters of filter string. Every time we get to a
|
||||||
|
// semicolon (or a null, meaning we've hit the end of the full string)
|
||||||
|
// then we've found the filter and can pass it off to IC to get a macOS
|
||||||
|
// file type out of it.
|
||||||
|
do
|
||||||
|
{
|
||||||
|
tempChar = filter[filterIndex];
|
||||||
|
if ((tempChar == ';') || (tempChar == 0)) { // End of filter type reached
|
||||||
|
typeTemp[typeTempIndex] = '\0'; // null terminate
|
||||||
|
|
||||||
|
// to make it easier to match file extensions while we're filtering, flatten
|
||||||
|
// out the list. Ignore filters that are just "*" and also remove the
|
||||||
|
// leading "*" from filters we do add.
|
||||||
|
if ( strlen(typeTemp) > 1 )
|
||||||
|
mFlatFilters.AppendCString ( nsCString((char*)&typeTemp[1]) ); // cut out the "*"
|
||||||
|
|
||||||
|
// ask IC if it's not "all files" (designated by "*")
|
||||||
|
if ( !(typeTemp[1] == '\0' && typeTemp[0] == '*') ) {
|
||||||
|
mAllFilesDisplayed = PR_FALSE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIMIMEInfo> icEntry;
|
||||||
|
icService->GetMIMEInfoFromExtension(typeTemp, getter_AddRefs(icEntry));
|
||||||
|
if ( icEntry )
|
||||||
|
{
|
||||||
|
bool addToList = true;
|
||||||
|
OSType tempOSType;
|
||||||
|
icEntry->GetMacType(NS_REINTERPRET_CAST(PRUint32*, (&tempOSType)));
|
||||||
|
for (PRUint32 typeIndex = 0; typeIndex < typesInThisFilter; typeIndex++)
|
||||||
|
{
|
||||||
|
if (mTypeLists[loop1]->osType[typeIndex] == tempOSType)
|
||||||
|
{
|
||||||
|
addToList = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addToList && typesInThisFilter < kMaxTypesPerFilter)
|
||||||
|
mTypeLists[loop1]->osType[typesInThisFilter++] = tempOSType;
|
||||||
|
}
|
||||||
|
} // if not "*"
|
||||||
|
|
||||||
|
typeTempIndex = 0; // Reset the temp string for the type
|
||||||
|
if (tempChar == '\0')
|
||||||
|
finishedThisFilter = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// strip out whitespace as we go
|
||||||
|
if ( tempChar != ' ' )
|
||||||
|
typeTemp[typeTempIndex++] = tempChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
filterIndex++;
|
||||||
|
} while (!finishedThisFilter);
|
||||||
|
|
||||||
|
// Set how many OSTypes we actually found
|
||||||
|
mTypeLists[loop1]->osTypeCount = typesInThisFilter;
|
||||||
|
|
||||||
|
nsMemory :: Free ( NS_REINTERPRET_CAST(void*, filter) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // MapFilterToFileTypes
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsFilePicker::GetFile(nsILocalFile **aFile)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aFile);
|
||||||
|
NS_IF_ADDREF(*aFile = mFile);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsFilePicker::GetFileURL(nsIFileURL **aFileURL)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(mFile, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
NS_NewFileURI(getter_AddRefs(uri), mFile);
|
||||||
|
nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(uri));
|
||||||
|
NS_ENSURE_TRUE(fileURL, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
NS_ADDREF(*aFileURL = fileURL);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Get the file + path
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsFilePicker::SetDefaultString(const PRUnichar *aString)
|
||||||
|
{
|
||||||
|
mDefault = aString;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsFilePicker::GetDefaultString(PRUnichar **aString)
|
||||||
|
{
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Set the display directory
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsFilePicker::SetDisplayDirectory(nsILocalFile *aDirectory)
|
||||||
|
{
|
||||||
|
mDisplayDirectory = aDirectory;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Get the display directory
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsFilePicker::GetDisplayDirectory(nsILocalFile **aDirectory)
|
||||||
|
{
|
||||||
|
*aDirectory = mDisplayDirectory;
|
||||||
|
NS_IF_ADDREF(*aDirectory);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsFilePicker::AppendFilter(const PRUnichar *aTitle, const PRUnichar *aFilter)
|
||||||
|
{
|
||||||
|
mFilters.AppendString(nsDependentString(aFilter));
|
||||||
|
mTitles.AppendString(nsDependentString(aTitle));
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/* -*- 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 Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Stuart Parmenter <pavlov@netscape.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef nsFilePicker_h__
|
||||||
|
#define nsFilePicker_h__
|
||||||
|
|
||||||
|
#include "nsBaseFilePicker.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsIFileChannel.h"
|
||||||
|
#include "nsILocalFile.h"
|
||||||
|
#include <Navigation.h>
|
||||||
|
|
||||||
|
#define kMaxTypeListCount 10
|
||||||
|
#define kMaxTypesPerFilter 9
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native Mac FileSelector wrapper
|
||||||
|
*/
|
||||||
|
|
||||||
|
class nsFilePicker : public nsBaseFilePicker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsFilePicker();
|
||||||
|
virtual ~nsFilePicker();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
// nsIFilePicker (less what's in nsBaseFilePicker)
|
||||||
|
NS_IMETHOD GetDefaultString(PRUnichar * *aDefaultString);
|
||||||
|
NS_IMETHOD SetDefaultString(const PRUnichar * aDefaultString);
|
||||||
|
NS_IMETHOD GetDisplayDirectory(nsILocalFile * *aDisplayDirectory);
|
||||||
|
NS_IMETHOD SetDisplayDirectory(nsILocalFile * aDisplayDirectory);
|
||||||
|
NS_IMETHOD GetFile(nsILocalFile * *aFile);
|
||||||
|
NS_IMETHOD GetFileURL(nsIFileURL * *aFileURL);
|
||||||
|
NS_IMETHOD Show(PRInt16 *_retval);
|
||||||
|
NS_IMETHOD AppendFilter(const PRUnichar *aTitle, const PRUnichar *aFilter) ;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
NS_IMETHOD InitNative(nsIWidget *aParent, const PRUnichar *aTitle, PRInt16 aMode);
|
||||||
|
|
||||||
|
NS_IMETHOD OnOk();
|
||||||
|
NS_IMETHOD OnCancel();
|
||||||
|
|
||||||
|
// actual implementations of get/put dialogs using NavServices
|
||||||
|
PRInt16 PutLocalFile(Str255 & inTitle, Str255 & inDefaultName, FSSpec* outFileSpec) ;
|
||||||
|
PRInt16 GetLocalFile(Str255 & inTitle, FSSpec* outFileSpec);
|
||||||
|
PRInt16 GetLocalFolder(Str255 & inTitle, FSSpec* outFileSpec);
|
||||||
|
|
||||||
|
void MapFilterToFileTypes ( ) ;
|
||||||
|
Boolean IsTypeInFilterList ( ResType inType ) ;
|
||||||
|
Boolean IsExtensionInFilterList ( StrFileName & inFileName ) ;
|
||||||
|
|
||||||
|
// filter routine for file types
|
||||||
|
static pascal Boolean FileDialogFilterProc ( AEDesc* theItem, void* info,
|
||||||
|
NavCallBackUserData callbackUD,
|
||||||
|
NavFilterModes filterMode ) ;
|
||||||
|
|
||||||
|
PRBool mWasCancelled;
|
||||||
|
PRBool mAllFilesDisplayed;
|
||||||
|
nsString mTitle;
|
||||||
|
PRInt16 mMode;
|
||||||
|
nsCOMPtr<nsILocalFile> mFile;
|
||||||
|
nsString mDefault;
|
||||||
|
nsCOMPtr<nsILocalFile> mDisplayDirectory;
|
||||||
|
|
||||||
|
nsStringArray mFilters;
|
||||||
|
nsStringArray mTitles;
|
||||||
|
nsCStringArray mFlatFilters; // all the filters from mFilters, but one per string
|
||||||
|
|
||||||
|
NavTypeListPtr mTypeLists[kMaxTypeListCount];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // nsFilePicker_h__
|
|
@ -0,0 +1,589 @@
|
||||||
|
/* -*- 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):
|
||||||
|
*
|
||||||
|
* 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 "nsLookAndFeel.h"
|
||||||
|
#include "nsXPLookAndFeel.h"
|
||||||
|
#include "nsCarbonHelpers.h"
|
||||||
|
#include "nsIInternetConfigService.h"
|
||||||
|
#include "nsIServiceManager.h"
|
||||||
|
#include "nsSize.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Query interface implementation
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsLookAndFeel, nsILookAndFeel);
|
||||||
|
|
||||||
|
nsLookAndFeel::nsLookAndFeel()
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
|
(void)NS_NewXPLookAndFeel(getter_AddRefs(mXPLookAndFeel));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsLookAndFeel::~nsLookAndFeel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLookAndFeel::GetColor(const nsColorID aID, nscolor &aColor)
|
||||||
|
{
|
||||||
|
nsresult res = NS_OK;
|
||||||
|
|
||||||
|
if (mXPLookAndFeel)
|
||||||
|
{
|
||||||
|
res = mXPLookAndFeel->GetColor(aID, aColor);
|
||||||
|
if (NS_SUCCEEDED(res))
|
||||||
|
return res;
|
||||||
|
res = NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (aID) {
|
||||||
|
case eColor_WindowBackground:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIInternetConfigService> icService_wb (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
|
||||||
|
if (icService_wb)
|
||||||
|
{
|
||||||
|
res = icService_wb->GetColor(nsIInternetConfigService::eICColor_WebBackgroundColour, &aColor);
|
||||||
|
if (NS_SUCCEEDED(res))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
aColor = NS_RGB(0xff,0xff,0xff); // default to white if we didn't find it in internet config
|
||||||
|
res = NS_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case eColor_WindowForeground:
|
||||||
|
aColor = NS_RGB(0x00,0x00,0x00);
|
||||||
|
break;
|
||||||
|
case eColor_WidgetBackground:
|
||||||
|
aColor = NS_RGB(0xdd,0xdd,0xdd);
|
||||||
|
break;
|
||||||
|
case eColor_WidgetForeground:
|
||||||
|
aColor = NS_RGB(0x00,0x00,0x00);
|
||||||
|
break;
|
||||||
|
case eColor_WidgetSelectBackground:
|
||||||
|
aColor = NS_RGB(0x80,0x80,0x80);
|
||||||
|
break;
|
||||||
|
case eColor_WidgetSelectForeground:
|
||||||
|
aColor = NS_RGB(0x00,0x00,0x80);
|
||||||
|
break;
|
||||||
|
case eColor_Widget3DHighlight:
|
||||||
|
aColor = NS_RGB(0xa0,0xa0,0xa0);
|
||||||
|
break;
|
||||||
|
case eColor_Widget3DShadow:
|
||||||
|
aColor = NS_RGB(0x40,0x40,0x40);
|
||||||
|
break;
|
||||||
|
case eColor_TextBackground:
|
||||||
|
aColor = NS_RGB(0xff,0xff,0xff);
|
||||||
|
break;
|
||||||
|
case eColor_TextForeground:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIInternetConfigService> icService_tf (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
|
||||||
|
if (icService_tf)
|
||||||
|
{
|
||||||
|
res = icService_tf->GetColor(nsIInternetConfigService::eICColor_WebTextColor, &aColor);
|
||||||
|
if (NS_SUCCEEDED(res))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
aColor = NS_RGB(0x00,0x00,0x00);
|
||||||
|
res = NS_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case eColor_highlight: // CSS2 color
|
||||||
|
case eColor_TextSelectBackground:
|
||||||
|
RGBColor macColor;
|
||||||
|
GrafPtr thePort;
|
||||||
|
::GetPort(&thePort);
|
||||||
|
if (thePort)
|
||||||
|
{
|
||||||
|
::GetPortHiliteColor(thePort,&macColor);
|
||||||
|
aColor = NS_RGB(macColor.red>>8, macColor.green>>8, macColor.blue>>8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
aColor = NS_RGB(0x00,0x00,0x00);
|
||||||
|
break;
|
||||||
|
case eColor_highlighttext: // CSS2 color
|
||||||
|
case eColor_TextSelectForeground:
|
||||||
|
GetColor(eColor_TextSelectBackground, aColor);
|
||||||
|
if (aColor == 0x000000)
|
||||||
|
aColor = NS_RGB(0xff,0xff,0xff);
|
||||||
|
else
|
||||||
|
aColor = NS_DONT_CHANGE_COLOR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// css2 system colors http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
|
||||||
|
//
|
||||||
|
// It's really hard to effectively map these to the Appearance Manager properly,
|
||||||
|
// since they are modeled word for word after the win32 system colors and don't have any
|
||||||
|
// real counterparts in the Mac world. I'm sure we'll be tweaking these for
|
||||||
|
// years to come.
|
||||||
|
//
|
||||||
|
// Thanks to mpt26@student.canterbury.ac.nz for the hardcoded values that form the defaults
|
||||||
|
// if querying the Appearance Manager fails ;)
|
||||||
|
//
|
||||||
|
|
||||||
|
case eColor_buttontext:
|
||||||
|
res = GetMacTextColor(kThemeTextColorPushButtonActive, aColor, NS_RGB(0x00,0x00,0x00));
|
||||||
|
break;
|
||||||
|
case eColor_captiontext:
|
||||||
|
res = GetMacTextColor(kThemeTextColorWindowHeaderActive, aColor, NS_RGB(0x00,0x00,0x00));
|
||||||
|
break;
|
||||||
|
case eColor_menutext:
|
||||||
|
res = GetMacTextColor(kThemeTextColorMenuItemActive, aColor, NS_RGB(0x00,0x00,0x00));
|
||||||
|
break;
|
||||||
|
case eColor_infotext:
|
||||||
|
//this will only work on MacOS 9. Mac OS < 9 will use hardcoded value
|
||||||
|
res = GetMacTextColor(kThemeTextColorNotification, aColor, NS_RGB(0x00,0x00,0x00));
|
||||||
|
break;
|
||||||
|
case eColor_windowtext:
|
||||||
|
//DialogActive is closest match to "windowtext"
|
||||||
|
res = GetMacTextColor(kThemeTextColorDialogActive, aColor, NS_RGB(0x00,0x00,0x00));
|
||||||
|
break;
|
||||||
|
case eColor_activecaption:
|
||||||
|
//no way to fetch this colour. HARDCODING to Platinum
|
||||||
|
//res = GetMacBrushColor(??, aColor, NS_RGB(0xCC,0xCC,0xCC));
|
||||||
|
//active titlebar etc is #CCCCCC
|
||||||
|
aColor = NS_RGB(0xCC,0xCC,0xCC);
|
||||||
|
res = NS_OK;
|
||||||
|
break;
|
||||||
|
case eColor_activeborder:
|
||||||
|
//If it means anything at all on Mac OS, then its black in every theme I've tried,
|
||||||
|
//but Aqua *has* no border!
|
||||||
|
res = GetMacBrushColor(kThemeBrushBlack, aColor, NS_RGB(0x00,0x00,0x00));
|
||||||
|
break;
|
||||||
|
case eColor_appworkspace:
|
||||||
|
// NOTE: this is an MDI color and does not exist on macOS.
|
||||||
|
//used the closest match, which will likely be white.
|
||||||
|
res = GetMacBrushColor(kThemeBrushDocumentWindowBackground, aColor, NS_RGB(0x63,0x63,0xCE));
|
||||||
|
break;
|
||||||
|
case eColor_background:
|
||||||
|
// NOTE: chances are good this is a pattern, not a pure color. What do we do?
|
||||||
|
// Seconded. This is almost never going to be a flat colour...
|
||||||
|
//incidentally, this is supposed to be the colour of the desktop, though how anyone
|
||||||
|
//is supposed to guess that from the name?
|
||||||
|
aColor = NS_RGB(0x63,0x63,0xCE);
|
||||||
|
res = NS_OK;
|
||||||
|
break;
|
||||||
|
case eColor_buttonface:
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonFaceActive, aColor, NS_RGB(0xDD,0xDD,0xDD));
|
||||||
|
break;
|
||||||
|
case eColor_buttonhighlight:
|
||||||
|
//lighter of 2 possible highlight colours available
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonActiveLightHighlight, aColor, NS_RGB(0xFF,0xFF,0xFF));
|
||||||
|
break;
|
||||||
|
case eColor_buttonshadow:
|
||||||
|
//darker of 2 possible shadow colours available
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonActiveDarkShadow, aColor, NS_RGB(0x77,0x77,0x77));
|
||||||
|
break;
|
||||||
|
case eColor_graytext:
|
||||||
|
res = GetMacTextColor(kThemeTextColorDialogInactive, aColor, NS_RGB(0x77,0x77,0x77));
|
||||||
|
break;
|
||||||
|
case eColor_inactiveborder:
|
||||||
|
//ScrollBar DelimiterInactive looks like an odd constant to use, but gives the right colour in most themes,
|
||||||
|
//also if you look at where this colour is *actually* used, it is pretty much what we want
|
||||||
|
res = GetMacBrushColor(kThemeBrushScrollBarDelimiterInactive, aColor, NS_RGB(0x55,0x55,0x55));
|
||||||
|
break;
|
||||||
|
case eColor_inactivecaption:
|
||||||
|
//best guess. Usually right in most themes I think
|
||||||
|
res = GetMacBrushColor(kThemeBrushDialogBackgroundInactive, aColor, NS_RGB(0xDD,0xDD,0xDD));
|
||||||
|
break;
|
||||||
|
case eColor_inactivecaptiontext:
|
||||||
|
res = GetMacTextColor(kThemeTextColorWindowHeaderInactive, aColor, NS_RGB(0x77,0x77,0x77));
|
||||||
|
break;
|
||||||
|
case eColor_scrollbar:
|
||||||
|
//this is the scrollbar trough. HARDCODING no way to get this colour
|
||||||
|
//res = GetMacBrushColor(??, aColor, NS_RGB(0xAA,0xAA,0xAA));
|
||||||
|
aColor = NS_RGB(0xAA,0xAA,0xAA);
|
||||||
|
res = NS_OK;
|
||||||
|
break;
|
||||||
|
case eColor_threeddarkshadow:
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonActiveDarkShadow, aColor, NS_RGB(0x77,0x77,0x77));
|
||||||
|
break;
|
||||||
|
case eColor_threedshadow:
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonActiveLightShadow, aColor, NS_RGB(0x99,0x99,0x99));
|
||||||
|
break;
|
||||||
|
case eColor_threedface:
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonFaceActive, aColor, NS_RGB(0xDD,0xDD,0xDD));
|
||||||
|
break;
|
||||||
|
case eColor_threedhighlight:
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonActiveLightHighlight, aColor, NS_RGB(0xFF,0xFF,0xFF));
|
||||||
|
break;
|
||||||
|
case eColor_threedlightshadow:
|
||||||
|
//the description in the CSS2 spec says this is on the side facing the lightsource,
|
||||||
|
//so its not a shadow in Mac OS terms, its the darker of the highlights
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonActiveDarkHighlight, aColor, NS_RGB(0xDD,0xDD,0xDD));
|
||||||
|
break;
|
||||||
|
case eColor_menu:
|
||||||
|
//best guess. Menus have similar background to dialogs in most themes
|
||||||
|
res = GetMacBrushColor(kThemeBrushDialogBackgroundActive, aColor, NS_RGB(0xDD,0xDD,0xDD));
|
||||||
|
break;
|
||||||
|
case eColor_infobackground:
|
||||||
|
//Brush exists on on MacOS 9. Earlier Mac OS will use default Platinum colour
|
||||||
|
res = GetMacBrushColor(kThemeBrushNotificationWindowBackground, aColor, NS_RGB(0xFF,0xFF,0xC6));
|
||||||
|
break;
|
||||||
|
case eColor_windowframe:
|
||||||
|
//no way to fetch this colour. HARDCODING to Platinum
|
||||||
|
//res = GetMacBrushColor(??, aColor, NS_RGB(0xCC,0xCC,0xCC));
|
||||||
|
aColor = NS_RGB(0xCC,0xCC,0xCC);
|
||||||
|
res = NS_OK;
|
||||||
|
break;
|
||||||
|
case eColor_window:
|
||||||
|
res = GetMacBrushColor(kThemeBrushDocumentWindowBackground, aColor, NS_RGB(0xFF,0xFF,0xFF));
|
||||||
|
break;
|
||||||
|
case eColor__moz_field:
|
||||||
|
aColor = NS_RGB(0xff,0xff,0xff);
|
||||||
|
break;
|
||||||
|
case eColor__moz_fieldtext:
|
||||||
|
// XXX There may be a better color for this, but I'm making it
|
||||||
|
// the same as WindowText since that's what's currently used where
|
||||||
|
// I will use -moz-FieldText.
|
||||||
|
res = GetMacTextColor(kThemeTextColorDialogActive, aColor, NS_RGB(0x00,0x00,0x00));
|
||||||
|
break;
|
||||||
|
case eColor__moz_dialog:
|
||||||
|
// XXX There may be a better color for this, but I'm making it
|
||||||
|
// the same as ThreeDFace since that's what's currently used where
|
||||||
|
// I will use -moz-Dialog:
|
||||||
|
res = GetMacBrushColor(kThemeBrushButtonFaceActive, aColor, NS_RGB(0xDD,0xDD,0xDD));
|
||||||
|
break;
|
||||||
|
case eColor__moz_dialogtext:
|
||||||
|
// XXX There may be a better color for this, but I'm making it
|
||||||
|
// the same as WindowText since that's what's currently used where
|
||||||
|
// I will use -moz-DialogText.
|
||||||
|
res = GetMacTextColor(kThemeTextColorDialogActive, aColor, NS_RGB(0x00,0x00,0x00));
|
||||||
|
break;
|
||||||
|
case eColor__moz_dragtargetzone:
|
||||||
|
//default to lavender if not available
|
||||||
|
res = GetMacBrushColor(kThemeBrushDragHilite, aColor, NS_RGB(0x63,0x63,0xCE));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_focusring:
|
||||||
|
//default to lavender if not available
|
||||||
|
res = GetMacBrushColor(kThemeBrushFocusHighlight, aColor, NS_RGB(0x63,0x63,0xCE));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_menushadow:
|
||||||
|
res = GetMacBrushColor(kThemeBrushBevelActiveDark, aColor, NS_RGB(0x88,0x88,0x88));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_menutextselect:
|
||||||
|
//default to white, which is what Platinum uses, if not available
|
||||||
|
res = GetMacTextColor(kThemeTextColorMenuItemSelected, aColor, NS_RGB(0xFF,0xFF,0xFF));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_accentlightesthighlight:
|
||||||
|
//get this colour by querying variation table, ows. default to Platinum/Lavendar
|
||||||
|
res = GetMacAccentColor(eColorOffset_mac_accentlightesthighlight, aColor, NS_RGB(0xEE,0xEE,0xEE));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_accentregularhighlight:
|
||||||
|
//get this colour by querying variation table, ows. default to Platinum/Lavendar
|
||||||
|
res = GetMacAccentColor(eColorOffset_mac_accentregularhighlight, aColor, NS_RGB(0xCC,0xCC,0xFF));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_accentface:
|
||||||
|
//get this colour by querying variation table, ows. default to Platinum/Lavendar
|
||||||
|
res = GetMacAccentColor(eColorOffset_mac_accentface, aColor, NS_RGB(0x99,0x99,0xFF));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_accentlightshadow:
|
||||||
|
//get this colour by querying variation table, ows. default to Platinum/Lavendar
|
||||||
|
res = GetMacAccentColor(eColorOffset_mac_accentlightshadow, aColor, NS_RGB(0x66,0x66,0xCC));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_menuselect:
|
||||||
|
case eColor__moz_mac_accentregularshadow:
|
||||||
|
//get this colour by querying variation table, ows. default to Platinum/Lavendar
|
||||||
|
res = GetMacAccentColor(eColorOffset_mac_accentregularshadow, aColor, NS_RGB(0x63,0x63,0xCE));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_accentdarkshadow:
|
||||||
|
//get this colour by querying variation table, ows. default to Platinum/Lavendar
|
||||||
|
res = GetMacAccentColor(eColorOffset_mac_accentdarkshadow, aColor, NS_RGB(0x00,0x00,0x88));
|
||||||
|
break;
|
||||||
|
case eColor__moz_mac_accentdarkestshadow:
|
||||||
|
//get this colour by querying variation table, ows. default to Platinum/Lavendar
|
||||||
|
res = GetMacAccentColor(eColorOffset_mac_accentdarkestshadow, aColor, NS_RGB(0x00,0x00,0x55));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NS_WARNING("Someone asked nsILookAndFeel for a color I don't know about");
|
||||||
|
aColor = NS_RGB(0xff,0xff,0xff);
|
||||||
|
res = NS_ERROR_FAILURE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLookAndFeel::GetMacBrushColor( const PRInt32 aBrushType, nscolor & aColor,
|
||||||
|
const nscolor & aDefaultColor)
|
||||||
|
{
|
||||||
|
OSStatus err = noErr;
|
||||||
|
RGBColor macColor;
|
||||||
|
|
||||||
|
err = ::GetThemeBrushAsColor(aBrushType, 32, true, &macColor);
|
||||||
|
if (err == noErr)
|
||||||
|
aColor = NS_RGB(macColor.red>>8, macColor.green>>8, macColor.blue>>8);
|
||||||
|
else
|
||||||
|
aColor = aDefaultColor;
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLookAndFeel::GetMacTextColor(const PRInt32 aTextType, nscolor & aColor,
|
||||||
|
const nscolor & aDefaultColor)
|
||||||
|
{
|
||||||
|
OSStatus err = noErr;
|
||||||
|
RGBColor macColor;
|
||||||
|
|
||||||
|
err = ::GetThemeTextColor(aTextType, 32, true, &macColor);
|
||||||
|
if (err == noErr)
|
||||||
|
aColor = NS_RGB(macColor.red>>8, macColor.green>>8, macColor.blue>>8);
|
||||||
|
else
|
||||||
|
aColor = aDefaultColor;
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLookAndFeel::GetMacAccentColor( const nsMacAccentColorOffset aAccent,
|
||||||
|
nscolor & aColor,
|
||||||
|
const nscolor & aDefaultColor)
|
||||||
|
{
|
||||||
|
nsresult res = NS_OK;
|
||||||
|
OSStatus err = noErr;
|
||||||
|
ColorTable colourTable;
|
||||||
|
CTabPtr ctPointer = &colourTable;
|
||||||
|
CTabHandle ctHandle = &ctPointer;
|
||||||
|
CTabHandle *colors = &ctHandle;
|
||||||
|
RGBColor *macColor;
|
||||||
|
|
||||||
|
err = ::GetThemeAccentColors(colors);
|
||||||
|
if (err == themeHasNoAccentsErr) {
|
||||||
|
//fine, theme doesn't support accents, use default
|
||||||
|
res = NS_OK;
|
||||||
|
aColor = aDefaultColor;
|
||||||
|
} else if (err != noErr || ! colors) {
|
||||||
|
res = NS_ERROR_FAILURE;
|
||||||
|
aColor = aDefaultColor;
|
||||||
|
} else {
|
||||||
|
if ((**colors)->ctSize ==
|
||||||
|
(eColorOffset_mac_accentdarkestshadow - eColorOffset_mac_accentlightesthighlight +1)) {
|
||||||
|
//if the size is 7 then its likely to be a standard Platinum variation, so lets use it
|
||||||
|
macColor = &((**colors)->ctTable[aAccent].rgb);
|
||||||
|
aColor = NS_RGB(macColor->red>>8, macColor->green>>8, macColor->blue>>8);
|
||||||
|
res = NS_OK;
|
||||||
|
} else if ((**colors)->ctSize == -1) {
|
||||||
|
//this is probably the high contrast Black & White Platinum variation
|
||||||
|
//so lets be high contrast
|
||||||
|
res = NS_OK;
|
||||||
|
if (aAccent <= eColorOffset_mac_accentface) {
|
||||||
|
aColor = NS_RGB(0xFF,0xFF,0xFF);
|
||||||
|
} else {
|
||||||
|
aColor = NS_RGB(0x00,0x00,0x00);
|
||||||
|
}
|
||||||
|
//else if ( ?? ) // add aqua support here?
|
||||||
|
} else {
|
||||||
|
//some other size we've never heard of, no idea what to do with it
|
||||||
|
res = NS_ERROR_FAILURE;
|
||||||
|
aColor = aDefaultColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLookAndFeel::GetMetric(const nsMetricID aID, PRInt32 & aMetric)
|
||||||
|
{
|
||||||
|
nsresult res = NS_OK;
|
||||||
|
|
||||||
|
if (mXPLookAndFeel)
|
||||||
|
{
|
||||||
|
res = mXPLookAndFeel->GetMetric(aID, aMetric);
|
||||||
|
if (NS_SUCCEEDED(res))
|
||||||
|
return res;
|
||||||
|
res = NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (aID) {
|
||||||
|
case eMetric_WindowTitleHeight:
|
||||||
|
aMetric = 0;
|
||||||
|
break;
|
||||||
|
case eMetric_WindowBorderWidth:
|
||||||
|
aMetric = 4;
|
||||||
|
break;
|
||||||
|
case eMetric_WindowBorderHeight:
|
||||||
|
aMetric = 4;
|
||||||
|
break;
|
||||||
|
case eMetric_Widget3DBorder:
|
||||||
|
aMetric = 4;
|
||||||
|
break;
|
||||||
|
case eMetric_TextFieldHeight:
|
||||||
|
aMetric = 16;
|
||||||
|
break;
|
||||||
|
case eMetric_TextFieldBorder:
|
||||||
|
aMetric = 2;
|
||||||
|
break;
|
||||||
|
case eMetric_ButtonHorizontalInsidePaddingNavQuirks:
|
||||||
|
aMetric = 20;
|
||||||
|
break;
|
||||||
|
case eMetric_ButtonHorizontalInsidePaddingOffsetNavQuirks:
|
||||||
|
aMetric = 0;
|
||||||
|
break;
|
||||||
|
case eMetric_CheckboxSize:
|
||||||
|
aMetric = 14;
|
||||||
|
break;
|
||||||
|
case eMetric_RadioboxSize:
|
||||||
|
aMetric = 14;
|
||||||
|
break;
|
||||||
|
case eMetric_TextHorizontalInsideMinimumPadding:
|
||||||
|
aMetric = 4;
|
||||||
|
break;
|
||||||
|
case eMetric_TextVerticalInsidePadding:
|
||||||
|
aMetric = 4;
|
||||||
|
break;
|
||||||
|
case eMetric_TextShouldUseVerticalInsidePadding:
|
||||||
|
aMetric = 1;
|
||||||
|
break;
|
||||||
|
case eMetric_TextShouldUseHorizontalInsideMinimumPadding:
|
||||||
|
aMetric = 1;
|
||||||
|
break;
|
||||||
|
case eMetric_ListShouldUseHorizontalInsideMinimumPadding:
|
||||||
|
aMetric = 0;
|
||||||
|
break;
|
||||||
|
case eMetric_ListHorizontalInsideMinimumPadding:
|
||||||
|
aMetric = 4;
|
||||||
|
break;
|
||||||
|
case eMetric_ListShouldUseVerticalInsidePadding:
|
||||||
|
aMetric = 1;
|
||||||
|
break;
|
||||||
|
case eMetric_ListVerticalInsidePadding:
|
||||||
|
aMetric = 3;
|
||||||
|
break;
|
||||||
|
case eMetric_CaretBlinkTime:
|
||||||
|
aMetric = ::GetCaretTime() * 1000 / 60;
|
||||||
|
break;
|
||||||
|
case eMetric_SingleLineCaretWidth:
|
||||||
|
case eMetric_MultiLineCaretWidth:
|
||||||
|
aMetric = 1;
|
||||||
|
break;
|
||||||
|
case eMetric_ShowCaretDuringSelection:
|
||||||
|
aMetric = 0;
|
||||||
|
break;
|
||||||
|
case eMetric_SubmenuDelay:
|
||||||
|
aMetric = 200;
|
||||||
|
break;
|
||||||
|
case eMetric_MenusCanOverlapOSBar:
|
||||||
|
// xul popups are not allowed to overlap the menubar.
|
||||||
|
aMetric = 0;
|
||||||
|
break;
|
||||||
|
case eMetric_DragFullWindow:
|
||||||
|
aMetric = 1;
|
||||||
|
break;
|
||||||
|
case eMetric_ScrollArrowStyle:
|
||||||
|
ThemeScrollBarArrowStyle arrowStyle;
|
||||||
|
::GetThemeScrollBarArrowStyle ( &arrowStyle );
|
||||||
|
aMetric = arrowStyle;
|
||||||
|
break;
|
||||||
|
case eMetric_ScrollSliderStyle:
|
||||||
|
ThemeScrollBarThumbStyle thumbStyle;
|
||||||
|
::GetThemeScrollBarThumbStyle ( &thumbStyle );
|
||||||
|
aMetric = thumbStyle;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
aMetric = 0;
|
||||||
|
res = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLookAndFeel::GetMetric(const nsMetricFloatID aID, float & aMetric)
|
||||||
|
{
|
||||||
|
nsresult res = NS_OK;
|
||||||
|
|
||||||
|
if (mXPLookAndFeel)
|
||||||
|
{
|
||||||
|
res = mXPLookAndFeel->GetMetric(aID, aMetric);
|
||||||
|
if (NS_SUCCEEDED(res))
|
||||||
|
return res;
|
||||||
|
res = NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (aID) {
|
||||||
|
case eMetricFloat_TextFieldVerticalInsidePadding:
|
||||||
|
aMetric = 0.25f;
|
||||||
|
break;
|
||||||
|
case eMetricFloat_TextFieldHorizontalInsidePadding:
|
||||||
|
aMetric = 0.95f;
|
||||||
|
break;
|
||||||
|
case eMetricFloat_TextAreaVerticalInsidePadding:
|
||||||
|
aMetric = 0.40f;
|
||||||
|
break;
|
||||||
|
case eMetricFloat_TextAreaHorizontalInsidePadding:
|
||||||
|
aMetric = 0.40f;
|
||||||
|
break;
|
||||||
|
case eMetricFloat_ListVerticalInsidePadding:
|
||||||
|
aMetric = 0.08f;
|
||||||
|
break;
|
||||||
|
case eMetricFloat_ListHorizontalInsidePadding:
|
||||||
|
aMetric = 0.40f;
|
||||||
|
break;
|
||||||
|
case eMetricFloat_ButtonVerticalInsidePadding:
|
||||||
|
aMetric = 0.5f;
|
||||||
|
break;
|
||||||
|
case eMetricFloat_ButtonHorizontalInsidePadding:
|
||||||
|
aMetric = 0.5f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
aMetric = -1.0;
|
||||||
|
res = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NS_DEBUG
|
||||||
|
NS_IMETHODIMP nsLookAndFeel::GetNavSize(const nsMetricNavWidgetID aWidgetID,
|
||||||
|
const nsMetricNavFontID aFontID,
|
||||||
|
const PRInt32 aFontSize,
|
||||||
|
nsSize &aSize)
|
||||||
|
{
|
||||||
|
if (mXPLookAndFeel)
|
||||||
|
{
|
||||||
|
nsresult rv = mXPLookAndFeel->GetNavSize(aWidgetID, aFontID, aFontSize, aSize);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
aSize.width = 0;
|
||||||
|
aSize.height = 0;
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* -*- 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):
|
||||||
|
*
|
||||||
|
* 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 __nsLookAndFeel
|
||||||
|
#define __nsLookAndFeel
|
||||||
|
#include "nsILookAndFeel.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
|
||||||
|
class nsLookAndFeel: public nsILookAndFeel {
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsLookAndFeel();
|
||||||
|
virtual ~nsLookAndFeel();
|
||||||
|
|
||||||
|
NS_IMETHOD GetColor(const nsColorID aID, nscolor &aColor);
|
||||||
|
NS_IMETHOD GetMetric(const nsMetricID aID, PRInt32 & aMetric);
|
||||||
|
NS_IMETHOD GetMetric(const nsMetricFloatID aID, float & aMetric);
|
||||||
|
|
||||||
|
#ifdef NS_DEBUG
|
||||||
|
// This method returns the actual (or nearest estimate)
|
||||||
|
// of the Navigator size for a given form control for a given font
|
||||||
|
// and font size. This is used in NavQuirks mode to see how closely
|
||||||
|
// we match its size
|
||||||
|
NS_IMETHOD GetNavSize(const nsMetricNavWidgetID aWidgetID,
|
||||||
|
const nsMetricNavFontID aFontID,
|
||||||
|
const PRInt32 aFontSize,
|
||||||
|
nsSize &aSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
|
||||||
|
//theme accent variation colours on Mac OS,
|
||||||
|
//offsets into Platinum theme variation colour table
|
||||||
|
eColorOffset_mac_accentlightesthighlight,
|
||||||
|
eColorOffset_mac_accentregularhighlight,
|
||||||
|
eColorOffset_mac_accentface,
|
||||||
|
eColorOffset_mac_accentlightshadow,
|
||||||
|
eColorOffset_mac_accentregularshadow,
|
||||||
|
eColorOffset_mac_accentdarkshadow,
|
||||||
|
eColorOffset_mac_accentdarkestshadow
|
||||||
|
} nsMacAccentColorOffset;
|
||||||
|
|
||||||
|
|
||||||
|
nsCOMPtr<nsILookAndFeel> mXPLookAndFeel;
|
||||||
|
NS_IMETHOD GetMacBrushColor(const PRInt32 aBrushType, nscolor & aColor, const nscolor & aDefaultColor);
|
||||||
|
NS_IMETHOD GetMacTextColor(const PRInt32 aTextType, nscolor & aColor, const nscolor & aDefaultColor);
|
||||||
|
NS_IMETHOD GetMacAccentColor(const nsMacAccentColorOffset aAccent, nscolor & aColor, const nscolor & aDefaultColor);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,119 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 "nsMacResources.h"
|
||||||
|
#include <Resources.h>
|
||||||
|
|
||||||
|
|
||||||
|
short nsMacResources::mRefNum = kResFileNotOpened;
|
||||||
|
short nsMacResources::mSaveResFile = 0;
|
||||||
|
|
||||||
|
#if !defined(XP_MACOSX)
|
||||||
|
pascal OSErr __NSInitialize(const CFragInitBlock *theInitBlock);
|
||||||
|
pascal OSErr __initializeResources(const CFragInitBlock *theInitBlock);
|
||||||
|
|
||||||
|
pascal void __NSTerminate(void);
|
||||||
|
pascal void __terminateResources(void);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
pascal OSErr __initializeResources(const CFragInitBlock *theInitBlock)
|
||||||
|
{
|
||||||
|
OSErr err = __NSInitialize(theInitBlock);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
short saveResFile = ::CurResFile();
|
||||||
|
|
||||||
|
short refNum = FSpOpenResFile(theInitBlock->fragLocator.u.onDisk.fileSpec, fsRdPerm);
|
||||||
|
nsMacResources::SetLocalResourceFile(refNum);
|
||||||
|
|
||||||
|
::UseResFile(saveResFile);
|
||||||
|
|
||||||
|
return ::ResError();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
pascal void __terminateResources(void)
|
||||||
|
{
|
||||||
|
::CloseResFile(nsMacResources::GetLocalResourceFile());
|
||||||
|
__NSTerminate();
|
||||||
|
}
|
||||||
|
#endif /*!XP_MACOSX*/
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsresult nsMacResources::OpenLocalResourceFile()
|
||||||
|
{
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
// XXX quick and dirty hack to make resources available so we don't crash.
|
||||||
|
if (mRefNum == kResFileNotOpened) {
|
||||||
|
FSSpec spec = { 0, 0, "\plibwidget.rsrc" };
|
||||||
|
if (FindFolder(kUserDomain, kDomainLibraryFolderType, false, &spec.vRefNum, &spec.parID) == noErr)
|
||||||
|
mRefNum = FSpOpenResFile(&spec, fsRdPerm);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (mRefNum == kResFileNotOpened)
|
||||||
|
return NS_ERROR_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
mSaveResFile = ::CurResFile();
|
||||||
|
::UseResFile(mRefNum);
|
||||||
|
|
||||||
|
return (::ResError() == noErr ? NS_OK : NS_ERROR_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsresult nsMacResources::CloseLocalResourceFile()
|
||||||
|
{
|
||||||
|
if (mRefNum == kResFileNotOpened)
|
||||||
|
return NS_ERROR_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
::UseResFile(mSaveResFile);
|
||||||
|
|
||||||
|
return (::ResError() == noErr ? NS_OK : NS_ERROR_FAILURE);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 nsMacResources_h__
|
||||||
|
#define nsMacResources_h__
|
||||||
|
|
||||||
|
#include "nsError.h"
|
||||||
|
|
||||||
|
class nsMacResources
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static nsresult OpenLocalResourceFile();
|
||||||
|
static nsresult CloseLocalResourceFile();
|
||||||
|
|
||||||
|
// you shouldn't have to use these:
|
||||||
|
static void SetLocalResourceFile(short aRefNum) {mRefNum = aRefNum;}
|
||||||
|
static short GetLocalResourceFile() {return mRefNum;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static short mRefNum;
|
||||||
|
static short mSaveResFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //nsMacResources_h__
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,214 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 nsMenuBarX_h__
|
||||||
|
#define nsMenuBarX_h__
|
||||||
|
|
||||||
|
#include "nsIMenuBar.h"
|
||||||
|
#include "nsIMenuListener.h"
|
||||||
|
#include "nsIDocumentObserver.h"
|
||||||
|
#include "nsIChangeManager.h"
|
||||||
|
#include "nsIMenuCommandDispatcher.h"
|
||||||
|
#include "nsIPresContext.h"
|
||||||
|
#include "nsSupportsArray.h"
|
||||||
|
#include "nsVoidArray.h"
|
||||||
|
#include "nsHashtable.h"
|
||||||
|
#include "nsWeakReference.h"
|
||||||
|
#include "nsIContent.h"
|
||||||
|
|
||||||
|
#include <MacTypes.h>
|
||||||
|
#include <UnicodeConverter.h>
|
||||||
|
#include <Menus.h>
|
||||||
|
#include <CarbonEvents.h>
|
||||||
|
|
||||||
|
extern nsWeakPtr gMacMenubarX;
|
||||||
|
|
||||||
|
class nsIWidget;
|
||||||
|
class nsIDocument;
|
||||||
|
class nsIDOMNode;
|
||||||
|
|
||||||
|
namespace MenuHelpersX
|
||||||
|
{
|
||||||
|
// utility routine for getting a PresContext out of a webShell
|
||||||
|
nsresult WebShellToPresContext ( nsIWebShell* inWebShell, nsIPresContext** outContext ) ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native Mac MenuBar wrapper
|
||||||
|
*/
|
||||||
|
|
||||||
|
class nsMenuBarX : public nsIMenuBar,
|
||||||
|
public nsIMenuListener,
|
||||||
|
public nsIDocumentObserver,
|
||||||
|
public nsIChangeManager,
|
||||||
|
public nsIMenuCommandDispatcher,
|
||||||
|
public nsSupportsWeakReference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsMenuBarX();
|
||||||
|
virtual ~nsMenuBarX();
|
||||||
|
|
||||||
|
enum { kAppleMenuID = 1 } ;
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSICHANGEMANAGER
|
||||||
|
NS_DECL_NSIMENUCOMMANDDISPATCHER
|
||||||
|
|
||||||
|
// nsIMenuListener interface
|
||||||
|
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow,
|
||||||
|
void * menuNode, void * aWebShell);
|
||||||
|
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus CheckRebuild(PRBool & aMenuEvent);
|
||||||
|
nsEventStatus SetRebuild(PRBool aMenuEvent);
|
||||||
|
|
||||||
|
// nsIDocumentObserver
|
||||||
|
NS_IMETHOD BeginUpdate(nsIDocument *aDocument);
|
||||||
|
NS_IMETHOD EndUpdate(nsIDocument *aDocument);
|
||||||
|
NS_IMETHOD BeginLoad(nsIDocument *aDocument);
|
||||||
|
NS_IMETHOD EndLoad(nsIDocument *aDocument);
|
||||||
|
NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell);
|
||||||
|
NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell);
|
||||||
|
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
|
||||||
|
nsIContent* aContent,
|
||||||
|
nsISupports* aSubContent);
|
||||||
|
NS_IMETHOD ContentStatesChanged(nsIDocument *aDocument,
|
||||||
|
nsIContent* aContent1,
|
||||||
|
nsIContent* aContent2);
|
||||||
|
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
||||||
|
nsIContent* aContent,
|
||||||
|
PRInt32 aNameSpaceID,
|
||||||
|
nsIAtom* aAttribute,
|
||||||
|
PRInt32 aModType,
|
||||||
|
PRInt32 aHint);
|
||||||
|
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
|
||||||
|
nsIContent* aContainer,
|
||||||
|
PRInt32 aNewIndexInContainer);
|
||||||
|
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
|
||||||
|
nsIContent* aContainer,
|
||||||
|
nsIContent* aChild,
|
||||||
|
PRInt32 aIndexInContainer);
|
||||||
|
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
|
||||||
|
nsIContent* aContainer,
|
||||||
|
nsIContent* aOldChild,
|
||||||
|
nsIContent* aNewChild,
|
||||||
|
PRInt32 aIndexInContainer);
|
||||||
|
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
|
||||||
|
nsIContent* aContainer,
|
||||||
|
nsIContent* aChild,
|
||||||
|
PRInt32 aIndexInContainer);
|
||||||
|
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
|
||||||
|
nsIStyleSheet* aStyleSheet);
|
||||||
|
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
|
||||||
|
nsIStyleSheet* aStyleSheet);
|
||||||
|
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
|
||||||
|
nsIStyleSheet* aStyleSheet,
|
||||||
|
PRBool aDisabled);
|
||||||
|
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
|
||||||
|
nsIStyleSheet* aStyleSheet,
|
||||||
|
nsIStyleRule* aStyleRule,
|
||||||
|
PRInt32 aHint);
|
||||||
|
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
|
||||||
|
nsIStyleSheet* aStyleSheet,
|
||||||
|
nsIStyleRule* aStyleRule);
|
||||||
|
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
|
||||||
|
nsIStyleSheet* aStyleSheet,
|
||||||
|
nsIStyleRule* aStyleRule);
|
||||||
|
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
|
||||||
|
|
||||||
|
NS_IMETHOD Create(nsIWidget * aParent);
|
||||||
|
|
||||||
|
// nsIMenuBar Methods
|
||||||
|
NS_IMETHOD GetParent(nsIWidget *&aParent);
|
||||||
|
NS_IMETHOD SetParent(nsIWidget * aParent);
|
||||||
|
NS_IMETHOD AddMenu(nsIMenu * aMenu);
|
||||||
|
NS_IMETHOD GetMenuCount(PRUint32 &aCount);
|
||||||
|
NS_IMETHOD GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu);
|
||||||
|
NS_IMETHOD InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu);
|
||||||
|
NS_IMETHOD RemoveMenu(const PRUint32 aCount);
|
||||||
|
NS_IMETHOD RemoveAll();
|
||||||
|
NS_IMETHOD GetNativeData(void*& aData);
|
||||||
|
NS_IMETHOD Paint();
|
||||||
|
NS_IMETHOD SetNativeData(void* aData);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void GetDocument ( nsIWebShell* inWebShell, nsIDocument** outDocument ) ;
|
||||||
|
void RegisterAsDocumentObserver ( nsIWebShell* inWebShell ) ;
|
||||||
|
|
||||||
|
// Make our menubar conform to Aqua UI guidelines
|
||||||
|
void AquifyMenuBar ( ) ;
|
||||||
|
void HideItem ( nsIDOMDocument* inDoc, nsAReadableString & inID, nsIContent** outHiddenNode ) ;
|
||||||
|
OSStatus InstallCommandEventHandler ( ) ;
|
||||||
|
|
||||||
|
// command handler for some special menu items (prefs/quit/etc)
|
||||||
|
pascal static OSStatus CommandEventHandler ( EventHandlerCallRef inHandlerChain,
|
||||||
|
EventRef inEvent, void* userData ) ;
|
||||||
|
nsEventStatus ExecuteCommand ( nsIContent* inDispatchTo ) ;
|
||||||
|
|
||||||
|
// build the Apple menu shared by all menu bars.
|
||||||
|
nsresult CreateAppleMenu ( nsIMenu* inMenu ) ;
|
||||||
|
|
||||||
|
nsHashtable mObserverTable; // stores observers for content change notification
|
||||||
|
nsHashtable mCommandMapTable; // maps CommandIDs to content nodes for CarbonEvent item selection
|
||||||
|
PRUint32 mCurrentCommandID; // unique command id (per menu-bar) to give to next item that asks
|
||||||
|
|
||||||
|
PRUint32 mNumMenus;
|
||||||
|
nsSupportsArray mMenusArray; // holds refs
|
||||||
|
nsCOMPtr<nsIContent> mMenuBarContent; // menubar content node, strong ref
|
||||||
|
nsCOMPtr<nsIContent> mPrefItemContent; // on X, holds the content node for the prefs item that has
|
||||||
|
// been removed from the menubar
|
||||||
|
nsCOMPtr<nsIContent> mQuitItemContent; // as above, but for quit
|
||||||
|
nsIWidget* mParent; // weak ref
|
||||||
|
|
||||||
|
PRBool mIsMenuBarAdded;
|
||||||
|
|
||||||
|
nsWeakPtr mWebShellWeakRef; // weak ref to webshell
|
||||||
|
nsIDocument* mDocument; // pointer to document
|
||||||
|
|
||||||
|
MenuRef mRootMenu; // root menu, representing entire menu bar.
|
||||||
|
|
||||||
|
static MenuRef sAppleMenu; // AppleMenu shared by all menubars
|
||||||
|
|
||||||
|
static EventHandlerUPP sCommandEventHandler; // carbon event handler for commands, shared
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // nsMenuBarX_h__
|
|
@ -0,0 +1,418 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 "nsCOMPtr.h"
|
||||||
|
#include "nsIDocumentViewer.h"
|
||||||
|
#include "nsIContent.h"
|
||||||
|
#include "nsIPresContext.h"
|
||||||
|
|
||||||
|
#include "nsMenuBarX.h" // for MenuHelpers namespace
|
||||||
|
#include "nsMenuItemX.h"
|
||||||
|
#include "nsIMenu.h"
|
||||||
|
#include "nsIMenuBar.h"
|
||||||
|
#include "nsIWidget.h"
|
||||||
|
#include "nsIMenuListener.h"
|
||||||
|
#include "nsDynamicMDEF.h"
|
||||||
|
#include "nsINameSpaceManager.h"
|
||||||
|
#include "nsWidgetAtoms.h"
|
||||||
|
#include "nsIServiceManager.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIDOMDocument.h"
|
||||||
|
|
||||||
|
#include "nsGUIEvent.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
nsInstanceCounter gMenuItemCounterX("nsMenuItemX");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS4(nsMenuItemX, nsIMenuItem, nsIMenuListener, nsIChangeObserver, nsISupportsWeakReference)
|
||||||
|
|
||||||
|
//
|
||||||
|
// nsMenuItemX constructor
|
||||||
|
//
|
||||||
|
nsMenuItemX::nsMenuItemX()
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
mMenuParent = nsnull;
|
||||||
|
mIsSeparator = PR_FALSE;
|
||||||
|
mKeyEquivalent.AssignWithConversion(" ");
|
||||||
|
mEnabled = PR_TRUE;
|
||||||
|
mIsChecked = PR_FALSE;
|
||||||
|
mMenuType = eRegular;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
++gMenuItemCounterX;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// nsMenuItemX destructor
|
||||||
|
//
|
||||||
|
nsMenuItemX::~nsMenuItemX()
|
||||||
|
{
|
||||||
|
mManager->Unregister(mContent);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
--gMenuItemCounterX;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_METHOD nsMenuItemX::Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
|
||||||
|
EMenuItemType aItemType, PRBool aEnabled,
|
||||||
|
nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode )
|
||||||
|
{
|
||||||
|
mContent = aNode; // addref
|
||||||
|
mMenuParent = aParent; // weak
|
||||||
|
mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell));
|
||||||
|
|
||||||
|
mEnabled = aEnabled;
|
||||||
|
mMenuType = aItemType;
|
||||||
|
|
||||||
|
// register for AttributeChanged messages
|
||||||
|
mManager = aManager;
|
||||||
|
nsCOMPtr<nsIChangeObserver> obs = do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*,this));
|
||||||
|
mManager->Register(mContent, obs); // does not addref this
|
||||||
|
|
||||||
|
mIsSeparator = aIsSeparator;
|
||||||
|
mLabel = aLabel;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsMenuItemX::GetLabel(nsString &aText)
|
||||||
|
{
|
||||||
|
aText = mLabel;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsMenuItemX::GetEnabled(PRBool *aIsEnabled)
|
||||||
|
{
|
||||||
|
*aIsEnabled = mEnabled;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_METHOD nsMenuItemX::SetChecked(PRBool aIsEnabled)
|
||||||
|
{
|
||||||
|
mIsChecked = aIsEnabled;
|
||||||
|
|
||||||
|
// update the content model. This will also handle unchecking our siblings
|
||||||
|
// if we are a radiomenu
|
||||||
|
mContent->SetAttr(kNameSpaceID_None, nsWidgetAtoms::checked,
|
||||||
|
mIsChecked ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false"), PR_TRUE);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::GetChecked(PRBool *aIsEnabled)
|
||||||
|
{
|
||||||
|
*aIsEnabled = mIsChecked;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::GetMenuItemType(EMenuItemType *aType)
|
||||||
|
{
|
||||||
|
*aType = mMenuType;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::GetTarget(nsIWidget *& aTarget)
|
||||||
|
{
|
||||||
|
NS_IF_ADDREF(aTarget = mTarget);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::GetNativeData(void *& aData)
|
||||||
|
{
|
||||||
|
//aData = (void *)mMenu;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::AddMenuListener(nsIMenuListener * aMenuListener)
|
||||||
|
{
|
||||||
|
mXULCommandListener = aMenuListener; // addref
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::RemoveMenuListener(nsIMenuListener * aMenuListener)
|
||||||
|
{
|
||||||
|
if (mXULCommandListener.get() == aMenuListener)
|
||||||
|
mXULCommandListener = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::IsSeparator(PRBool & aIsSep)
|
||||||
|
{
|
||||||
|
aIsSep = mIsSeparator;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// nsIMenuListener interface
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsEventStatus nsMenuItemX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
|
||||||
|
{
|
||||||
|
// this is all handled by Carbon Events
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsEventStatus nsMenuItemX::MenuSelected(const nsMenuEvent & aMenuEvent)
|
||||||
|
{
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// nsIMenuListener interface
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsEventStatus nsMenuItemX::MenuDeselected(const nsMenuEvent & aMenuEvent)
|
||||||
|
{
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsEventStatus nsMenuItemX::MenuConstruct(
|
||||||
|
const nsMenuEvent & aMenuEvent,
|
||||||
|
nsIWidget * aParentWindow,
|
||||||
|
void * menuNode,
|
||||||
|
void * aWebShell)
|
||||||
|
{
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsEventStatus nsMenuItemX::MenuDestruct(const nsMenuEvent & aMenuEvent)
|
||||||
|
{
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsEventStatus nsMenuItemX::CheckRebuild(PRBool & aNeedsRebuild)
|
||||||
|
{
|
||||||
|
aNeedsRebuild = PR_TRUE;
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsEventStatus nsMenuItemX::SetRebuild(PRBool aNeedsRebuild)
|
||||||
|
{
|
||||||
|
//mNeedsRebuild = aNeedsRebuild;
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Executes the "cached" JavaScript Command
|
||||||
|
* @return NS_OK if the command was executed properly, otherwise an error code
|
||||||
|
*/
|
||||||
|
NS_METHOD nsMenuItemX::DoCommand()
|
||||||
|
{
|
||||||
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPresContext> presContext;
|
||||||
|
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
|
||||||
|
if (!webShell)
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
MenuHelpersX::WebShellToPresContext(webShell, getter_AddRefs(presContext));
|
||||||
|
|
||||||
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
|
nsMouseEvent event;
|
||||||
|
event.eventStructType = NS_MOUSE_EVENT;
|
||||||
|
event.message = NS_XUL_COMMAND;
|
||||||
|
|
||||||
|
// See if we have a command element. If so, we execute on the command instead
|
||||||
|
// of on our content element.
|
||||||
|
nsAutoString command;
|
||||||
|
mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::command, command);
|
||||||
|
if (!command.IsEmpty()) {
|
||||||
|
nsCOMPtr<nsIDocument> doc;
|
||||||
|
mContent->GetDocument(*getter_AddRefs(doc));
|
||||||
|
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
||||||
|
nsCOMPtr<nsIDOMElement> commandElt;
|
||||||
|
domDoc->GetElementById(command, getter_AddRefs(commandElt));
|
||||||
|
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
|
||||||
|
if (commandContent)
|
||||||
|
commandContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||||
|
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::GetModifiers(PRUint8 * aModifiers)
|
||||||
|
{
|
||||||
|
nsresult res = NS_OK;
|
||||||
|
*aModifiers = mModifiers;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::SetModifiers(PRUint8 aModifiers)
|
||||||
|
{
|
||||||
|
nsresult res = NS_OK;
|
||||||
|
|
||||||
|
mModifiers = aModifiers;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::SetShortcutChar(const nsString &aText)
|
||||||
|
{
|
||||||
|
nsresult res = NS_OK;
|
||||||
|
mKeyEquivalent = aText;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD nsMenuItemX::GetShortcutChar(nsString &aText)
|
||||||
|
{
|
||||||
|
nsresult res = NS_OK;
|
||||||
|
aText = mKeyEquivalent;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// UncheckRadioSiblings
|
||||||
|
//
|
||||||
|
// walk the sibling list looking for nodes with the same name and
|
||||||
|
// uncheck them all.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsMenuItemX :: UncheckRadioSiblings(nsIContent* inCheckedContent)
|
||||||
|
{
|
||||||
|
nsAutoString myGroupName;
|
||||||
|
inCheckedContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::name, myGroupName);
|
||||||
|
if ( ! myGroupName.Length() ) // no groupname, nothing to do
|
||||||
|
return;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> parent;
|
||||||
|
inCheckedContent->GetParent(*getter_AddRefs(parent));
|
||||||
|
if ( !parent )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// loop over siblings
|
||||||
|
PRInt32 count;
|
||||||
|
parent->ChildCount(count);
|
||||||
|
for ( PRInt32 i = 0; i < count; ++i ) {
|
||||||
|
nsCOMPtr<nsIContent> sibling;
|
||||||
|
parent->ChildAt(i, *getter_AddRefs(sibling));
|
||||||
|
if ( sibling ) {
|
||||||
|
if ( sibling.get() != inCheckedContent ) { // skip this node
|
||||||
|
// if the current sibling is in the same group, clear it
|
||||||
|
nsAutoString currGroupName;
|
||||||
|
sibling->GetAttr(kNameSpaceID_None, nsWidgetAtoms::name, currGroupName);
|
||||||
|
if ( currGroupName == myGroupName )
|
||||||
|
sibling->SetAttr(kNameSpaceID_None, nsWidgetAtoms::checked, NS_LITERAL_STRING("false"), PR_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // for each sibling
|
||||||
|
|
||||||
|
} // UncheckRadioSiblings
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
//
|
||||||
|
// nsIChangeObserver
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsMenuItemX :: AttributeChanged ( nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom *aAttribute,
|
||||||
|
PRInt32 aHint)
|
||||||
|
{
|
||||||
|
if (aAttribute == nsWidgetAtoms::checked) {
|
||||||
|
// if we're a radio menu, uncheck our sibling radio items. No need to
|
||||||
|
// do any of this if we're just a normal check menu.
|
||||||
|
if ( mMenuType == eRadio ) {
|
||||||
|
nsAutoString checked;
|
||||||
|
mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::checked, checked);
|
||||||
|
if (checked == NS_LITERAL_STRING("true") )
|
||||||
|
UncheckRadioSiblings(mContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
|
||||||
|
listener->SetRebuild(PR_TRUE);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (aAttribute == nsWidgetAtoms::disabled || aAttribute == nsWidgetAtoms::hidden ||
|
||||||
|
aAttribute == nsWidgetAtoms::collapsed ) {
|
||||||
|
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
|
||||||
|
listener->SetRebuild(PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
} // AttributeChanged
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsMenuItemX :: ContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
|
||||||
|
{
|
||||||
|
|
||||||
|
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
|
||||||
|
listener->SetRebuild(PR_TRUE);
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
} // ContentRemoved
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsMenuItemX :: ContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
|
||||||
|
{
|
||||||
|
|
||||||
|
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
|
||||||
|
listener->SetRebuild(PR_TRUE);
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
} // ContentInserted
|
|
@ -0,0 +1,122 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 nsMenuItemX_h__
|
||||||
|
#define nsMenuItemX_h__
|
||||||
|
|
||||||
|
|
||||||
|
#include "nsIMenuItem.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsIMenuListener.h"
|
||||||
|
#include "nsIChangeManager.h"
|
||||||
|
#include "nsWeakReference.h"
|
||||||
|
#include "nsIWidget.h"
|
||||||
|
|
||||||
|
class nsIMenu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native Motif MenuItem wrapper
|
||||||
|
*/
|
||||||
|
|
||||||
|
class nsMenuItemX : public nsIMenuItem,
|
||||||
|
public nsIMenuListener,
|
||||||
|
public nsIChangeObserver,
|
||||||
|
public nsSupportsWeakReference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsMenuItemX();
|
||||||
|
virtual ~nsMenuItemX();
|
||||||
|
|
||||||
|
// nsISupports
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSICHANGEOBSERVER
|
||||||
|
|
||||||
|
// nsIMenuItem Methods
|
||||||
|
NS_IMETHOD Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
|
||||||
|
EMenuItemType aItemType, PRBool aEnabled,
|
||||||
|
nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode ) ;
|
||||||
|
NS_IMETHOD GetLabel(nsString &aText);
|
||||||
|
NS_IMETHOD SetShortcutChar(const nsString &aText);
|
||||||
|
NS_IMETHOD GetShortcutChar(nsString &aText);
|
||||||
|
NS_IMETHOD GetEnabled(PRBool *aIsEnabled);
|
||||||
|
NS_IMETHOD SetChecked(PRBool aIsEnabled);
|
||||||
|
NS_IMETHOD GetChecked(PRBool *aIsEnabled);
|
||||||
|
NS_IMETHOD GetMenuItemType(EMenuItemType *aIsCheckbox);
|
||||||
|
NS_IMETHOD GetTarget(nsIWidget *& aTarget);
|
||||||
|
NS_IMETHOD GetNativeData(void*& aData);
|
||||||
|
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
|
||||||
|
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
|
||||||
|
NS_IMETHOD IsSeparator(PRBool & aIsSep);
|
||||||
|
|
||||||
|
NS_IMETHOD DoCommand();
|
||||||
|
NS_IMETHOD SetModifiers(PRUint8 aModifiers);
|
||||||
|
NS_IMETHOD GetModifiers(PRUint8 * aModifiers);
|
||||||
|
|
||||||
|
// nsIMenuListener interface
|
||||||
|
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow,
|
||||||
|
void * menuNode, void * aWebShell);
|
||||||
|
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus CheckRebuild(PRBool & aMenuEvent);
|
||||||
|
nsEventStatus SetRebuild(PRBool aMenuEvent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void UncheckRadioSiblings ( nsIContent* inCheckedElement ) ;
|
||||||
|
|
||||||
|
nsString mLabel;
|
||||||
|
nsString mKeyEquivalent;
|
||||||
|
|
||||||
|
nsIMenu* mMenuParent; // weak, parent owns us
|
||||||
|
nsIChangeManager* mManager; // weak
|
||||||
|
|
||||||
|
nsCOMPtr<nsIWidget> mTarget; // never set?
|
||||||
|
nsCOMPtr<nsIMenuListener> mXULCommandListener;
|
||||||
|
|
||||||
|
nsWeakPtr mWebShellWeakRef; // weak ref to webshell
|
||||||
|
nsCOMPtr<nsIContent> mContent;
|
||||||
|
|
||||||
|
PRUint8 mModifiers;
|
||||||
|
PRPackedBool mIsSeparator;
|
||||||
|
PRPackedBool mEnabled;
|
||||||
|
PRPackedBool mIsChecked;
|
||||||
|
EMenuItemType mMenuType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // nsMenuItem_h__
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,165 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 nsMenuX_h__
|
||||||
|
#define nsMenuX_h__
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIMenu.h"
|
||||||
|
#include "nsSupportsArray.h"
|
||||||
|
#include "nsIMenuListener.h"
|
||||||
|
#include "nsIChangeManager.h"
|
||||||
|
#include "nsWeakReference.h"
|
||||||
|
|
||||||
|
#include <Menus.h>
|
||||||
|
#include <UnicodeConverter.h>
|
||||||
|
#include <CarbonEvents.h>
|
||||||
|
|
||||||
|
|
||||||
|
class nsIMenuBar;
|
||||||
|
class nsIMenuListener;
|
||||||
|
|
||||||
|
|
||||||
|
//static PRInt16 mMacMenuIDCount; // use GetUniqueMenuID()
|
||||||
|
extern PRInt16 mMacMenuIDCount;// = kMacMenuID;
|
||||||
|
|
||||||
|
|
||||||
|
class nsMenuX : public nsIMenu,
|
||||||
|
public nsIMenuListener,
|
||||||
|
public nsIChangeObserver,
|
||||||
|
public nsSupportsWeakReference
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsMenuX();
|
||||||
|
virtual ~nsMenuX();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSICHANGEOBSERVER
|
||||||
|
|
||||||
|
// nsIMenuListener methods
|
||||||
|
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow,
|
||||||
|
void * menuNode, void * aWebShell);
|
||||||
|
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
|
||||||
|
nsEventStatus CheckRebuild(PRBool & aMenuEvent);
|
||||||
|
nsEventStatus SetRebuild(PRBool aMenuEvent);
|
||||||
|
|
||||||
|
// nsIMenu Methods
|
||||||
|
NS_IMETHOD Create ( nsISupports * aParent, const nsAReadableString &aLabel, const nsAReadableString &aAccessKey,
|
||||||
|
nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode ) ;
|
||||||
|
NS_IMETHOD GetParent(nsISupports *&aParent);
|
||||||
|
NS_IMETHOD GetLabel(nsString &aText);
|
||||||
|
NS_IMETHOD SetLabel(const nsAReadableString &aText);
|
||||||
|
NS_IMETHOD GetAccessKey(nsString &aText);
|
||||||
|
NS_IMETHOD SetAccessKey(const nsAReadableString &aText);
|
||||||
|
NS_IMETHOD AddItem(nsISupports* aText);
|
||||||
|
NS_IMETHOD AddSeparator();
|
||||||
|
NS_IMETHOD GetItemCount(PRUint32 &aCount);
|
||||||
|
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem);
|
||||||
|
NS_IMETHOD InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem);
|
||||||
|
NS_IMETHOD RemoveItem(const PRUint32 aPos);
|
||||||
|
NS_IMETHOD RemoveAll();
|
||||||
|
NS_IMETHOD GetNativeData(void** aData);
|
||||||
|
NS_IMETHOD SetNativeData(void* aData);
|
||||||
|
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
|
||||||
|
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
|
||||||
|
NS_IMETHOD GetMenuContent(nsIContent ** aMenuNode);
|
||||||
|
NS_IMETHOD SetEnabled(PRBool aIsEnabled);
|
||||||
|
NS_IMETHOD GetEnabled(PRBool* aIsEnabled);
|
||||||
|
NS_IMETHOD IsHelpMenu(PRBool* aIsEnabled);
|
||||||
|
|
||||||
|
//
|
||||||
|
NS_IMETHOD AddMenuItem(nsIMenuItem * aMenuItem);
|
||||||
|
NS_IMETHOD AddMenu(nsIMenu * aMenu);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Determines how many menus are visible among the siblings that are before me.
|
||||||
|
// It doesn't matter if I am visible.
|
||||||
|
nsresult CountVisibleBefore ( PRUint32* outVisibleBefore ) ;
|
||||||
|
|
||||||
|
// fetch the content node associated with the menupopup item
|
||||||
|
void GetMenuPopupContent ( nsIContent** aResult ) ;
|
||||||
|
|
||||||
|
// Insert a new item in this menu with index |inItemIndex| with the text |inItemLabel|,
|
||||||
|
// middle-truncated to a certain pixel width with an elipsis.
|
||||||
|
void InsertMenuItemWithTruncation ( nsAutoString & inItemLabel,
|
||||||
|
PRUint32 inItemIndex ) ;
|
||||||
|
|
||||||
|
// fire handlers for oncreate/ondestroy
|
||||||
|
PRBool OnDestroy() ;
|
||||||
|
PRBool OnCreate() ;
|
||||||
|
PRBool OnDestroyed() ;
|
||||||
|
PRBool OnCreated() ;
|
||||||
|
|
||||||
|
void LoadMenuItem ( nsIMenu* pParentMenu, nsIContent* menuitemContent );
|
||||||
|
void LoadSubMenu ( nsIMenu * pParentMenu, nsIContent* menuitemContent );
|
||||||
|
void LoadSeparator ( nsIContent* menuitemContent );
|
||||||
|
|
||||||
|
nsEventStatus HelpMenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow,
|
||||||
|
void* unused, void* aWebShell);
|
||||||
|
|
||||||
|
MenuHandle NSStringNewMenu(short menuID, nsString& menuTitle);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsString mLabel;
|
||||||
|
PRUint32 mNumMenuItems;
|
||||||
|
nsSupportsArray mMenuItemsArray; // array holds refs
|
||||||
|
|
||||||
|
nsISupports* mParent; // weak, my parent owns me
|
||||||
|
nsIChangeManager* mManager; // weak ref, it will outlive us [menubar]
|
||||||
|
nsWeakPtr mWebShellWeakRef; // weak ref to webshell
|
||||||
|
nsCOMPtr<nsIContent> mMenuContent; // the |menu| tag, strong ref
|
||||||
|
nsCOMPtr<nsIMenuListener> mListener; // strong ref
|
||||||
|
|
||||||
|
// MacSpecific
|
||||||
|
PRInt16 mMacMenuID;
|
||||||
|
MenuHandle mMacMenuHandle;
|
||||||
|
PRInt16 mHelpMenuOSItemsCount;
|
||||||
|
PRPackedBool mIsHelpMenu;
|
||||||
|
PRPackedBool mIsEnabled;
|
||||||
|
PRPackedBool mDestroyHandlerCalled;
|
||||||
|
PRPackedBool mNeedsRebuild;
|
||||||
|
PRPackedBool mConstructed;
|
||||||
|
PRPackedBool mVisible; // are we visible to the user?
|
||||||
|
|
||||||
|
EventHandlerRef mHandler; // our event handler
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // nsMenuX_h__
|
|
@ -0,0 +1,278 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mike Pinkerton
|
||||||
|
// Netscape Communications
|
||||||
|
//
|
||||||
|
// See header file for details
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "nsMimeMapper.h"
|
||||||
|
#include "nsITransferable.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsReadableUtils.h"
|
||||||
|
|
||||||
|
#include <Drag.h>
|
||||||
|
#include <Scrap.h>
|
||||||
|
|
||||||
|
nsMimeMapperMac :: nsMimeMapperMac ( const char* inMappings )
|
||||||
|
: mCounter(0)
|
||||||
|
{
|
||||||
|
if (inMappings && strlen(inMappings) )
|
||||||
|
ParseMappings ( inMappings );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsMimeMapperMac :: ~nsMimeMapperMac ( )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MapMimeTypeToMacOSType
|
||||||
|
//
|
||||||
|
// Given a mime type, map this into the appropriate MacOS clipboard type. For
|
||||||
|
// types that we don't know about intrinsicly, use a trick to get a unique 4
|
||||||
|
// character code.
|
||||||
|
//
|
||||||
|
// When a mapping is made, store it in the current mapping list so it can
|
||||||
|
// be exported along with the data.
|
||||||
|
//
|
||||||
|
ResType
|
||||||
|
nsMimeMapperMac :: MapMimeTypeToMacOSType ( const char* aMimeStr, PRBool inAddIfNotPresent )
|
||||||
|
{
|
||||||
|
ResType format = 0;
|
||||||
|
|
||||||
|
// first check if it is already in our list.
|
||||||
|
for ( MimeMapConstIterator it = mMappings.begin(); it != mMappings.end(); ++it ) {
|
||||||
|
if ( it->second.Equals(aMimeStr) ) {
|
||||||
|
format = it->first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's not there, do a mapping and put it there. Some things we want to map
|
||||||
|
// to specific MacOS types, like 'TEXT'. Others are internal and we don't really
|
||||||
|
// care about what they look like, just that they have a fairly unique flavor type.
|
||||||
|
//
|
||||||
|
// Don't put standard MacOS flavor mappings into the mapping list because we'll
|
||||||
|
// pick them up by special casing MapMacsOSTypeToMimeType(). This means that
|
||||||
|
// the low two bytes of the generated flavor can be used as an index into the list.
|
||||||
|
if ( !format ) {
|
||||||
|
if ( PL_strcmp(aMimeStr, kTextMime) == 0 )
|
||||||
|
format = kScrapFlavorTypeText;
|
||||||
|
else if ( PL_strcmp(aMimeStr, kFileMime) == 0 )
|
||||||
|
format = flavorTypeHFS;
|
||||||
|
else if ( PL_strcmp(aMimeStr, kPNGImageMime) == 0 )
|
||||||
|
format = kScrapFlavorTypePicture;
|
||||||
|
else if ( PL_strcmp(aMimeStr, kJPEGImageMime) == 0 )
|
||||||
|
format = kScrapFlavorTypePicture;
|
||||||
|
else if ( PL_strcmp(aMimeStr, kGIFImageMime) == 0 )
|
||||||
|
format = kScrapFlavorTypePicture;
|
||||||
|
else if ( PL_strcmp(aMimeStr, kUnicodeMime) == 0 )
|
||||||
|
format = kScrapFlavorTypeUnicode;
|
||||||
|
|
||||||
|
else if ( inAddIfNotPresent ) {
|
||||||
|
// create the flavor based on the unique id in the lower two bytes and 'MZ' in the
|
||||||
|
// upper two bytes.
|
||||||
|
format = mCounter++;
|
||||||
|
format |= ('..MZ' << 16);
|
||||||
|
|
||||||
|
// stick it in the mapping list
|
||||||
|
mMappings.push_back ( MimePair(format, nsCAutoString(aMimeStr)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( inAddIfNotPresent )
|
||||||
|
NS_ASSERTION ( format, "Didn't map mimeType to a macOS type for some reason" );
|
||||||
|
return format;
|
||||||
|
|
||||||
|
} // MapMimeTypeToMacOSType
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MapMacOSTypeToMimeType
|
||||||
|
//
|
||||||
|
// Given a MacOS flavor, map this back into the Mozilla mimetype. Uses the mappings
|
||||||
|
// that have already been loaded into this class. If there aren't any, that's ok too, but
|
||||||
|
// we probably won't get a match in that case.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsMimeMapperMac :: MapMacOSTypeToMimeType ( ResType inMacType, nsCAutoString & outMimeStr )
|
||||||
|
{
|
||||||
|
switch ( inMacType ) {
|
||||||
|
|
||||||
|
case kScrapFlavorTypeText: outMimeStr = kTextMime; break;
|
||||||
|
case kScrapFlavorTypeUnicode: outMimeStr = kUnicodeMime; break;
|
||||||
|
case flavorTypeHFS: outMimeStr = kFileMime; break;
|
||||||
|
|
||||||
|
// This flavor is the old 4.x Composer flavor for HTML. The actual data is a binary
|
||||||
|
// data structure which we do NOT want to deal with in any way shape or form. I am
|
||||||
|
// only including this flavor here so we don't accidentally use it ourselves and
|
||||||
|
// get very very confused.
|
||||||
|
case 'EHTM':
|
||||||
|
// Fall through to the unknown case.
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
outMimeStr = "unknown";
|
||||||
|
|
||||||
|
// if the flavor starts with 'MZ' then it's probably one of our encoded ones. If not,
|
||||||
|
// we have no idea what it is. The way this was encoded means that we can use the
|
||||||
|
// lower two byts of the flavor as an index into our mapping list.
|
||||||
|
if ( inMacType & ('..MZ' << 16) ) {
|
||||||
|
unsigned short index = inMacType & 0x0000FFFF; // extract the index into our internal list
|
||||||
|
if ( index < mMappings.size() )
|
||||||
|
outMimeStr = mMappings[index].second;
|
||||||
|
else
|
||||||
|
NS_WARNING("Found a flavor starting with 'MZ..' that isn't one of ours!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // case of which flavor
|
||||||
|
|
||||||
|
} // MapMacOSTypeToMimeType
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ParseMappings
|
||||||
|
//
|
||||||
|
// The mappings are of the form
|
||||||
|
// 1..N of (<4 char code> <space> <mime type>).
|
||||||
|
//
|
||||||
|
// It is perfectly acceptable for there to be no mappings (either |inMappings|
|
||||||
|
// is null or an emtpy string).
|
||||||
|
//
|
||||||
|
// NOTE: we make the assumption that the data is NULL terminated.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsMimeMapperMac :: ParseMappings ( const char* inMappings )
|
||||||
|
{
|
||||||
|
if ( !inMappings )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* currPosition = inMappings;
|
||||||
|
while ( *currPosition ) {
|
||||||
|
char mimeType[100];
|
||||||
|
ResType flavor = nsnull;
|
||||||
|
|
||||||
|
sscanf ( currPosition, "%ld %s ", &flavor, mimeType );
|
||||||
|
mMappings.push_back( MimePair(flavor, nsCAutoString(mimeType)) );
|
||||||
|
|
||||||
|
currPosition += 10 + 2 + strlen(mimeType); // see ExportMapping() for explanation of this calculation
|
||||||
|
|
||||||
|
++mCounter;
|
||||||
|
} // while we're not at the end yet
|
||||||
|
|
||||||
|
} // ParseMappings
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ExportMapping
|
||||||
|
//
|
||||||
|
// The mappings are of the form
|
||||||
|
// <# of pairs> 1..N of (<4 char code> <space> <mime type> <space>)
|
||||||
|
//
|
||||||
|
// Caller is responsible for disposing of the memory allocated here. |outLength| counts
|
||||||
|
// the null at the end of the string.
|
||||||
|
//
|
||||||
|
char*
|
||||||
|
nsMimeMapperMac :: ExportMapping ( short * outLength ) const
|
||||||
|
{
|
||||||
|
NS_WARN_IF_FALSE ( outLength, "No out param provided" );
|
||||||
|
if ( outLength )
|
||||||
|
*outLength = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// I'm leaving this code in here just to prove a point. If we were allowed to
|
||||||
|
// use string stream's (we're not, because of bloat), this is all the code I'd have
|
||||||
|
// to write to do all the crap down below.
|
||||||
|
ostringstream ostr;
|
||||||
|
|
||||||
|
// for each pair, write out flavor and mime types
|
||||||
|
for ( MimeMapConstIterator it = mMappings.begin(); it != mMappings.end(); ++it ) {
|
||||||
|
const char* mimeType = ToNewCString(it->second);
|
||||||
|
ostr << it->first << ' ' << mimeType << ' ';
|
||||||
|
delete [] mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ostr.str().c_str();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char* exportBuffer = nsnull;
|
||||||
|
|
||||||
|
// figure out about how long the composed string will be
|
||||||
|
short len = 0;
|
||||||
|
for ( MimeMapConstIterator it = mMappings.begin(); it != mMappings.end(); ++it ) {
|
||||||
|
len += 10; // <4 char code> (any decimal representation of 'MZXX' will be 10 digits)
|
||||||
|
len += 2; // for the two spaces
|
||||||
|
len += it->second.Length(); // <mime type>
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a string of that length and fill it in with each mapping. We have to
|
||||||
|
// consider the possibility that there aren't any generic (internal mozilla) flavors
|
||||||
|
// so the map could be empty.
|
||||||
|
exportBuffer = NS_STATIC_CAST(char*, nsMemory::Alloc(len + 1)); // don't forget the NULL
|
||||||
|
if ( !exportBuffer )
|
||||||
|
return nsnull;
|
||||||
|
*exportBuffer = '\0'; // null terminate at the start for strcat()
|
||||||
|
if ( len ) {
|
||||||
|
char* posInString = exportBuffer;
|
||||||
|
for ( MimeMapConstIterator it = mMappings.begin(); it != mMappings.end(); ++it ) {
|
||||||
|
// create a buffer for this mapping, fill it in, and append it to our
|
||||||
|
// ongoing result buffer, |exportBuffer|.
|
||||||
|
char* currMapping = new char[10 + 2 + it->second.Length() + 1]; // same computation as above, plus NULL
|
||||||
|
char* mimeType = ToNewCString(it->second);
|
||||||
|
if ( currMapping && mimeType ) {
|
||||||
|
sprintf(currMapping, "%ld %s ", it->first, mimeType);
|
||||||
|
strcat(posInString, currMapping);
|
||||||
|
posInString += strlen(currMapping); // advance marker to get ready for next mapping
|
||||||
|
}
|
||||||
|
nsCRT::free ( mimeType );
|
||||||
|
nsCRT::free ( currMapping );
|
||||||
|
}
|
||||||
|
|
||||||
|
*posInString = '\0'; // null terminate our resulting string
|
||||||
|
} // if there is anything in our list
|
||||||
|
|
||||||
|
if ( outLength )
|
||||||
|
*outLength = len + 1; // don't forget the NULL
|
||||||
|
return exportBuffer;
|
||||||
|
|
||||||
|
} // ExportMapping
|
|
@ -0,0 +1,115 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 ***** */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mike Pinkerton
|
||||||
|
// Netscape Communications
|
||||||
|
//
|
||||||
|
// Contains the interface for |nsMimeMapper|, which is used to map between
|
||||||
|
// mozilla defined mime types (such as text/html or mozilla/toolbaritem) and
|
||||||
|
// MacOS flavors which are 4-character codes. Since's it's not easy to go
|
||||||
|
// from N characters down to 4 and back to N without loss, we need a different
|
||||||
|
// mechanism than just some hash algorithm.
|
||||||
|
//
|
||||||
|
// The way this is generally used is to instantiate a mime mapper when you're
|
||||||
|
// about to hand data to the OS and then ask it to map the mime type into a
|
||||||
|
// 4-character code. If it's not one that the mapper knows about intrinsically,
|
||||||
|
// it creates a unique type and remembers the mapping internally. Do this for each
|
||||||
|
// different flavor of data you have. Then, when you're ready to hand the
|
||||||
|
// data to the OS for real, ask the mapper to export its mapping list (with
|
||||||
|
// ExportMapping()) which can be put into a special, well known, data flavor
|
||||||
|
// that goes into the OS along with the data.
|
||||||
|
//
|
||||||
|
// When pulling data out of the OS and into mozilla, the mapper is used to
|
||||||
|
// convert from the 4-character codes the OS knows about back to the original mime
|
||||||
|
// types. At this stage, depending the originator of the data (mozilla or some other
|
||||||
|
// mac app), you may or may not have a mapping flavor which explicitly lays out the
|
||||||
|
// conversions. If you do, load it (you have to do this yourself) and pass it to the
|
||||||
|
// ctor. If you don't, that's ok too and the well-known mappings can still be performed.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef nsMimeMapper_h__
|
||||||
|
#define nsMimeMapper_h__
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include <Types.h>
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
using std::pair;
|
||||||
|
|
||||||
|
class nsMimeMapperMac
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { kMappingFlavor = 'MOZm' } ;
|
||||||
|
|
||||||
|
nsMimeMapperMac ( const char* inMappings = nsnull ) ;
|
||||||
|
~nsMimeMapperMac ( ) ;
|
||||||
|
|
||||||
|
// Converts from mime type (eg: text/plain) to MacOS type (eg: 'TEXT'). If
|
||||||
|
// the mapping failed, the resulting restype will be null.
|
||||||
|
ResType MapMimeTypeToMacOSType ( const char* aMimeStr, PRBool inAddIfNotPresent = PR_TRUE ) ;
|
||||||
|
void MapMacOSTypeToMimeType ( ResType inMacType, nsCAutoString & outMimeStr ) ;
|
||||||
|
|
||||||
|
// Takes the internal mappings and converts them to a string for
|
||||||
|
// placing on the clipboard or in a drag item. |outLength| includes
|
||||||
|
// the NULL at the end of the string.
|
||||||
|
char* ExportMapping ( short * outLength ) const;
|
||||||
|
|
||||||
|
static ResType MappingFlavor ( ) { return kMappingFlavor; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void ParseMappings ( const char* inMappings ) ;
|
||||||
|
|
||||||
|
typedef pair<ResType, nsCAutoString> MimePair;
|
||||||
|
typedef std::vector<MimePair> MimeMap;
|
||||||
|
typedef MimeMap::iterator MimeMapIterator;
|
||||||
|
typedef MimeMap::const_iterator MimeMapConstIterator;
|
||||||
|
|
||||||
|
// the keeper of the data
|
||||||
|
MimeMap mMappings;
|
||||||
|
// an increasing counter for generating unique flavors
|
||||||
|
short mCounter;
|
||||||
|
|
||||||
|
// don't want people copying this until copy ctor does the right thing
|
||||||
|
nsMimeMapperMac ( const nsMimeMapperMac & ) ;
|
||||||
|
|
||||||
|
}; // nsMimeMapperMac
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,526 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "nsRegionMac.h"
|
||||||
|
#include "prmem.h"
|
||||||
|
#include "nsCarbonHelpers.h"
|
||||||
|
|
||||||
|
NS_EXPORT nsNativeRegionPool sNativeRegionPool;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsNativeRegionPool::nsNativeRegionPool()
|
||||||
|
{
|
||||||
|
mRegionSlots = nsnull;
|
||||||
|
mEmptySlots = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsNativeRegionPool::~nsNativeRegionPool()
|
||||||
|
{
|
||||||
|
// Release all of the regions.
|
||||||
|
if (mRegionSlots != nsnull) {
|
||||||
|
nsRegionSlot* slot = mRegionSlots;
|
||||||
|
while (slot != nsnull) {
|
||||||
|
::DisposeRgn(slot->mRegion);
|
||||||
|
nsRegionSlot* next = slot->mNext;
|
||||||
|
delete slot;
|
||||||
|
slot = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release all empty slots.
|
||||||
|
if (mEmptySlots != nsnull) {
|
||||||
|
nsRegionSlot* slot = mEmptySlots;
|
||||||
|
while (slot != nsnull) {
|
||||||
|
nsRegionSlot* next = slot->mNext;
|
||||||
|
delete slot;
|
||||||
|
slot = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RgnHandle nsNativeRegionPool::GetNewRegion()
|
||||||
|
{
|
||||||
|
nsRegionSlot* slot = mRegionSlots;
|
||||||
|
if (slot != nsnull) {
|
||||||
|
RgnHandle region = slot->mRegion;
|
||||||
|
|
||||||
|
// remove this slot from the free list.
|
||||||
|
mRegionSlots = slot->mNext;
|
||||||
|
|
||||||
|
// transfer this slot to the empty slot list for reuse.
|
||||||
|
slot->mRegion = nsnull;
|
||||||
|
slot->mNext = mEmptySlots;
|
||||||
|
mEmptySlots = slot;
|
||||||
|
|
||||||
|
// initialize the region.
|
||||||
|
::SetEmptyRgn(region);
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return a fresh new region. a slot will be created to hold it
|
||||||
|
// if and when the region is released.
|
||||||
|
return (::NewRgn());
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsNativeRegionPool::ReleaseRegion(RgnHandle aRgnHandle)
|
||||||
|
{
|
||||||
|
nsRegionSlot* slot = mEmptySlots;
|
||||||
|
if (slot != nsnull)
|
||||||
|
mEmptySlots = slot->mNext;
|
||||||
|
else
|
||||||
|
slot = new nsRegionSlot;
|
||||||
|
|
||||||
|
if (slot != nsnull) {
|
||||||
|
// put this region on the region list.
|
||||||
|
slot->mRegion = aRgnHandle;
|
||||||
|
slot->mNext = mRegionSlots;
|
||||||
|
mRegionSlots = slot;
|
||||||
|
} else {
|
||||||
|
// couldn't allocate a slot, toss the region.
|
||||||
|
::DisposeRgn(aRgnHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsRegionMac::nsRegionMac()
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
mRegion = nsnull;
|
||||||
|
mRegionType = eRegionComplexity_empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsRegionMac::~nsRegionMac()
|
||||||
|
{
|
||||||
|
if (mRegion != nsnull) {
|
||||||
|
sNativeRegionPool.ReleaseRegion(mRegion);
|
||||||
|
mRegion = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsRegionMac, nsIRegion)
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsresult nsRegionMac::Init(void)
|
||||||
|
{
|
||||||
|
if (mRegion != nsnull)
|
||||||
|
::SetEmptyRgn(mRegion);
|
||||||
|
else
|
||||||
|
mRegion = sNativeRegionPool.GetNewRegion();
|
||||||
|
if (mRegion != nsnull) {
|
||||||
|
mRegionType = eRegionComplexity_empty;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::SetTo(const nsIRegion &aRegion)
|
||||||
|
{
|
||||||
|
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
|
||||||
|
::CopyRgn(pRegion->mRegion, mRegion);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||||
|
{
|
||||||
|
::SetRectRgn(mRegion, aX, aY, aX + aWidth, aY + aHeight);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::Intersect(const nsIRegion &aRegion)
|
||||||
|
{
|
||||||
|
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
|
||||||
|
::SectRgn(mRegion, pRegion->mRegion, mRegion);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||||
|
{
|
||||||
|
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion();
|
||||||
|
if (rectRgn != nsnull) {
|
||||||
|
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
|
||||||
|
::SectRgn(mRegion, rectRgn, mRegion);
|
||||||
|
sNativeRegionPool.ReleaseRegion(rectRgn);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::Union(const nsIRegion &aRegion)
|
||||||
|
{
|
||||||
|
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
|
||||||
|
::UnionRgn(mRegion, pRegion->mRegion, mRegion);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||||
|
{
|
||||||
|
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion();
|
||||||
|
if (rectRgn != nsnull) {
|
||||||
|
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
|
||||||
|
::UnionRgn(mRegion, rectRgn, mRegion);
|
||||||
|
sNativeRegionPool.ReleaseRegion(rectRgn);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::Subtract(const nsIRegion &aRegion)
|
||||||
|
{
|
||||||
|
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
|
||||||
|
::DiffRgn(mRegion, pRegion->mRegion, mRegion);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||||
|
{
|
||||||
|
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion();
|
||||||
|
if (rectRgn != nsnull) {
|
||||||
|
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
|
||||||
|
::DiffRgn(mRegion, rectRgn, mRegion);
|
||||||
|
sNativeRegionPool.ReleaseRegion(rectRgn);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
PRBool nsRegionMac::IsEmpty(void)
|
||||||
|
{
|
||||||
|
if (mRegionType == eRegionComplexity_empty)
|
||||||
|
return PR_TRUE;
|
||||||
|
else
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
PRBool nsRegionMac::IsEqual(const nsIRegion &aRegion)
|
||||||
|
{
|
||||||
|
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
|
||||||
|
return(::EqualRgn(mRegion, pRegion->mRegion));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight)
|
||||||
|
{
|
||||||
|
Rect macRect;
|
||||||
|
::GetRegionBounds (mRegion, &macRect);
|
||||||
|
|
||||||
|
*aX = macRect.left;
|
||||||
|
*aY = macRect.top;
|
||||||
|
*aWidth = macRect.right - macRect.left;
|
||||||
|
*aHeight = macRect.bottom - macRect.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
void nsRegionMac::Offset(PRInt32 aXOffset, PRInt32 aYOffset)
|
||||||
|
{
|
||||||
|
::OffsetRgn(mRegion, aXOffset, aYOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
PRBool nsRegionMac::ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||||
|
{
|
||||||
|
Rect macRect;
|
||||||
|
::SetRect(&macRect, aX, aY, aX + aWidth, aY + aHeight);
|
||||||
|
return(::RectInRgn(&macRect, mRegion));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
|
||||||
|
{
|
||||||
|
nsRegionRectSet *rects;
|
||||||
|
|
||||||
|
NS_ASSERTION(!(nsnull == aRects), "bad ptr");
|
||||||
|
|
||||||
|
rects = *aRects;
|
||||||
|
|
||||||
|
if (nsnull == rects) {
|
||||||
|
rects = (nsRegionRectSet *)PR_Malloc(sizeof(nsRegionRectSet) + (sizeof(nsRegionRect) << 3));
|
||||||
|
|
||||||
|
if (nsnull == rects) {
|
||||||
|
*aRects = nsnull;
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
rects->mRectsLen = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
rects->mNumRects = 0;
|
||||||
|
rects->mArea = 0;
|
||||||
|
|
||||||
|
/* This is a minor adaptation of code written by Hugh Fisher
|
||||||
|
and published in the RegionToRectangles example in the InfoMac archives.
|
||||||
|
ported to raptor from old macfe. MMP
|
||||||
|
*/
|
||||||
|
#define EndMark 32767
|
||||||
|
#define MaxY 32767
|
||||||
|
#define StackMax 1024
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
short size;
|
||||||
|
Rect bbox;
|
||||||
|
short data[0];
|
||||||
|
} ** Internal;
|
||||||
|
|
||||||
|
Internal region;
|
||||||
|
short width, xAdjust, y, index, x1, x2, x;
|
||||||
|
short stackStorage[1024];
|
||||||
|
short *buffer;
|
||||||
|
|
||||||
|
region = (Internal)mRegion;
|
||||||
|
|
||||||
|
/* Check for plain rectangle */
|
||||||
|
if ((**region).size == 10) {
|
||||||
|
rects->mRects[0].x = (**region).bbox.left;
|
||||||
|
rects->mRects[0].y = (**region).bbox.top;
|
||||||
|
rects->mRects[0].width = (**region).bbox.right - (**region).bbox.left;
|
||||||
|
rects->mRects[0].height = (**region).bbox.bottom - (**region).bbox.top;
|
||||||
|
|
||||||
|
rects->mNumRects = 1;
|
||||||
|
rects->mArea = rects->mRects[0].width * rects->mRects[0].height;
|
||||||
|
|
||||||
|
*aRects = rects;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Got to scale x coordinates into range 0..something */
|
||||||
|
xAdjust = (**region).bbox.left;
|
||||||
|
width = (**region).bbox.right - xAdjust;
|
||||||
|
|
||||||
|
/* Most regions will be less than 1024 pixels wide */
|
||||||
|
|
||||||
|
if (width < StackMax)
|
||||||
|
buffer = stackStorage;
|
||||||
|
else {
|
||||||
|
buffer = (short *)PR_Malloc(width * 2);
|
||||||
|
|
||||||
|
if (buffer == NULL) {
|
||||||
|
/* Truly humungous region or very low on memory.
|
||||||
|
Quietly doing nothing seems to be the
|
||||||
|
traditional Quickdraw response. */
|
||||||
|
*aRects = rects;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialise scan line list to bottom edges */
|
||||||
|
|
||||||
|
for (x = (**region).bbox.left; x < (**region).bbox.right; x++)
|
||||||
|
buffer[x - xAdjust] = MaxY;
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
/* Loop until we hit an empty scan line */
|
||||||
|
|
||||||
|
while ((**region).data[index] != EndMark) {
|
||||||
|
y = (**region).data[index];
|
||||||
|
index++;
|
||||||
|
|
||||||
|
/* Loop through horizontal runs on this line */
|
||||||
|
|
||||||
|
while ((**region).data[index] != EndMark) {
|
||||||
|
x1 = (**region).data[index];
|
||||||
|
index ++;
|
||||||
|
x2 = (**region).data[index];
|
||||||
|
index ++;
|
||||||
|
x = x1;
|
||||||
|
|
||||||
|
while (x < x2) {
|
||||||
|
if (buffer[x - xAdjust] < y) {
|
||||||
|
nsRegionRect box;
|
||||||
|
|
||||||
|
/* We have a bottom edge - how long for? */
|
||||||
|
|
||||||
|
box.x = x;
|
||||||
|
box.y = buffer[x - xAdjust];
|
||||||
|
|
||||||
|
while (x < x2 && buffer[x - xAdjust] == box.y) {
|
||||||
|
buffer[x - xAdjust] = MaxY;
|
||||||
|
x ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pass to client proc */
|
||||||
|
box.width = x - box.x;
|
||||||
|
box.height = y - box.y;
|
||||||
|
|
||||||
|
if (rects->mNumRects == rects->mRectsLen) {
|
||||||
|
void *buf = PR_Realloc((void *)rects, sizeof(nsRegionRectSet) + sizeof(nsRegionRect) * (rects->mRectsLen + 7));
|
||||||
|
|
||||||
|
if (nsnull != buf) {
|
||||||
|
rects = (nsRegionRectSet *)buf;
|
||||||
|
rects->mRectsLen += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rects->mNumRects != rects->mRectsLen) {
|
||||||
|
rects->mArea += box.width * box.height;
|
||||||
|
rects->mRects[rects->mNumRects] = box;
|
||||||
|
rects->mNumRects++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* This becomes a top edge */
|
||||||
|
|
||||||
|
buffer[x - xAdjust] = y;
|
||||||
|
x ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up after ourselves */
|
||||||
|
|
||||||
|
if (width >= StackMax)
|
||||||
|
PR_Free((void *)buffer);
|
||||||
|
|
||||||
|
#undef EndMark
|
||||||
|
#undef MaxY
|
||||||
|
#undef StackMax
|
||||||
|
|
||||||
|
*aRects = rects;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsRegionMac::FreeRects(nsRegionRectSet *aRects)
|
||||||
|
{
|
||||||
|
if (nsnull != aRects)
|
||||||
|
PR_Free((void *)aRects);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsRegionMac::GetNativeRegion(void *&aRegion) const
|
||||||
|
{
|
||||||
|
aRegion = (void *)mRegion;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsresult nsRegionMac::SetNativeRegion(void *aRegion)
|
||||||
|
{
|
||||||
|
if (aRegion) {
|
||||||
|
::CopyRgn((RgnHandle)aRegion, mRegion);
|
||||||
|
SetRegionType();
|
||||||
|
} else {
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsRegionMac::GetRegionComplexity(nsRegionComplexity &aComplexity) const
|
||||||
|
{
|
||||||
|
aComplexity = mRegionType;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void nsRegionMac::SetRegionType()
|
||||||
|
{
|
||||||
|
if (::EmptyRgn(mRegion) == PR_TRUE)
|
||||||
|
mRegionType = eRegionComplexity_empty;
|
||||||
|
else
|
||||||
|
if ( ::IsRegionRectangular(mRegion) )
|
||||||
|
mRegionType = eRegionComplexity_rect;
|
||||||
|
else
|
||||||
|
mRegionType = eRegionComplexity_complex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void nsRegionMac::SetRegionEmpty()
|
||||||
|
{
|
||||||
|
::SetEmptyRgn(mRegion);
|
||||||
|
SetRegionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
RgnHandle nsRegionMac::CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||||
|
{
|
||||||
|
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion();
|
||||||
|
if (rectRgn != nsnull)
|
||||||
|
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
|
||||||
|
return rectRgn;
|
||||||
|
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,75 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 __nsSound_h__
|
||||||
|
#define __nsSound_h__
|
||||||
|
|
||||||
|
#include "nsISound.h"
|
||||||
|
#include "nsSupportsArray.h"
|
||||||
|
|
||||||
|
class nsIURI;
|
||||||
|
class nsIChannel;
|
||||||
|
class nsICacheSession;
|
||||||
|
|
||||||
|
class nsSound : public nsISound
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
nsSound();
|
||||||
|
virtual ~nsSound();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSISOUND
|
||||||
|
|
||||||
|
nsresult AddRequest(nsISupports* aSoundRequest);
|
||||||
|
nsresult RemoveRequest(nsISupports* aSoundRequest);
|
||||||
|
|
||||||
|
nsresult GetCacheSession(nsICacheSession** outCacheSession);
|
||||||
|
nsresult GetSoundFromCache(nsIURI* inURI, nsISupports** outSound);
|
||||||
|
nsresult PutSoundInCache(nsIChannel* inChannel, PRUint32 inDataSize, nsISupports* inSound);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
nsresult GetSoundResourceName(const char* inSoundName, StringPtr outResourceName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
nsSupportsArray mSoundRequests; // array of outstanding/playing sounds
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __nsSound_h__ */
|
|
@ -0,0 +1,89 @@
|
||||||
|
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||||
|
/* ***** 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) 1999
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Frank Yung-Fong Tang <ftang@netscape.com>
|
||||||
|
*
|
||||||
|
* 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 <Gestalt.h>
|
||||||
|
#include "nsTSMStrategy.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
//#define FORCE_USE_UNICODE_API
|
||||||
|
//#define FORCE_NOT_USE_UNICODE_API
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
PRBool nsTSMStrategy::gUseUnicodeForInputMethod = PR_FALSE;
|
||||||
|
PRBool nsTSMStrategy::gUseUnicodeForKeyboard = PR_FALSE;
|
||||||
|
PRBool nsTSMStrategy::gInit = PR_FALSE;
|
||||||
|
|
||||||
|
void nsTSMStrategy::Init()
|
||||||
|
{
|
||||||
|
if ( !gInit)
|
||||||
|
{
|
||||||
|
gInit = PR_TRUE;
|
||||||
|
OSErr err;
|
||||||
|
long version;
|
||||||
|
err = Gestalt(gestaltTSMgrVersion, &version);
|
||||||
|
if ((err == noErr) && (version >= gestaltTSMgr15))
|
||||||
|
{
|
||||||
|
gUseUnicodeForInputMethod = PR_TRUE;
|
||||||
|
gUseUnicodeForKeyboard = PR_TRUE;
|
||||||
|
}
|
||||||
|
#ifdef FORCE_USE_UNICODE_API
|
||||||
|
gUseUnicodeForInputMethod = PR_TRUE;
|
||||||
|
#elif defined( FORCE_NOT_USE_UNICODE_API )
|
||||||
|
gUseUnicodeForInputMethod = PR_FALSE;
|
||||||
|
#endif
|
||||||
|
// there are no way we can use unicode for keyboard, but not using
|
||||||
|
// Unicode for IME
|
||||||
|
if ( !gUseUnicodeForInputMethod)
|
||||||
|
gUseUnicodeForKeyboard = PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsTSMStrategy::UseUnicodeForInputMethod()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
return gUseUnicodeForInputMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool nsTSMStrategy::UseUnicodeForKeyboard()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
return gUseUnicodeForKeyboard;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||||
|
/* ***** 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) 1999
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Frank Yung-Fong Tang <ftang@netscape.com>
|
||||||
|
*
|
||||||
|
* 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 nsTSMStrategy_h__
|
||||||
|
#define nsTSMStrategyr_h__
|
||||||
|
#include "nscore.h"
|
||||||
|
|
||||||
|
class nsTSMStrategy {
|
||||||
|
public:
|
||||||
|
PRBool UseUnicodeForInputMethod();
|
||||||
|
PRBool UseUnicodeForKeyboard();
|
||||||
|
private:
|
||||||
|
static PRBool gUseUnicodeForInputMethod;
|
||||||
|
static PRBool gUseUnicodeForKeyboard;
|
||||||
|
static PRBool gInit;
|
||||||
|
void Init();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // nsTSMStrategy_h__
|
|
@ -0,0 +1,402 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 "nsToolkit.h"
|
||||||
|
#include "nsGUIEvent.h"
|
||||||
|
#include "nsWidgetAtoms.h"
|
||||||
|
|
||||||
|
#include <Gestalt.h>
|
||||||
|
#include <Appearance.h>
|
||||||
|
|
||||||
|
#include "nsIEventQueue.h"
|
||||||
|
#include "nsIEventQueueService.h"
|
||||||
|
#include "nsIServiceManager.h"
|
||||||
|
#include "nsGfxCIID.h"
|
||||||
|
|
||||||
|
// Class IDs...
|
||||||
|
static NS_DEFINE_CID(kEventQueueCID, NS_EVENTQUEUE_CID);
|
||||||
|
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||||
|
|
||||||
|
static nsMacNSPREventQueueHandler* gEventQueueHandler = nsnull;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Static thread local storage index of the Toolkit
|
||||||
|
// object associated with a given thread...
|
||||||
|
//
|
||||||
|
static PRUintn gToolkitTLSIndex = 0;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsMacNSPREventQueueHandler::nsMacNSPREventQueueHandler(): Repeater()
|
||||||
|
{
|
||||||
|
mRefCnt = 0;
|
||||||
|
mEventQueueService = do_GetService(kEventQueueServiceCID);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsMacNSPREventQueueHandler::~nsMacNSPREventQueueHandler()
|
||||||
|
{
|
||||||
|
StopRepeating();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
void nsMacNSPREventQueueHandler::StartPumping()
|
||||||
|
{
|
||||||
|
++mRefCnt;
|
||||||
|
NS_LOG_ADDREF(this, mRefCnt, "nsMacNSPREventQueueHandler", sizeof(*this));
|
||||||
|
StartRepeating();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
PRBool nsMacNSPREventQueueHandler::StopPumping()
|
||||||
|
{
|
||||||
|
if (mRefCnt > 0) {
|
||||||
|
--mRefCnt;
|
||||||
|
NS_LOG_RELEASE(this, mRefCnt, "nsMacNSPREventQueueHandler");
|
||||||
|
if (mRefCnt == 0) {
|
||||||
|
StopRepeating();
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
void nsMacNSPREventQueueHandler::RepeatAction(const EventRecord& inMacEvent)
|
||||||
|
{
|
||||||
|
ProcessPLEventQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
PRBool nsMacNSPREventQueueHandler::EventsArePending()
|
||||||
|
{
|
||||||
|
PRBool pendingEvents = PR_FALSE;
|
||||||
|
|
||||||
|
if (mEventQueueService)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIEventQueue> queue;
|
||||||
|
mEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
|
||||||
|
|
||||||
|
if (queue)
|
||||||
|
queue->PendingEvents(&pendingEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pendingEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
void nsMacNSPREventQueueHandler::ProcessPLEventQueue()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mEventQueueService, "Need event queue service here");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIEventQueue> queue;
|
||||||
|
mEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
|
||||||
|
if (queue)
|
||||||
|
{
|
||||||
|
nsresult rv = queue->ProcessPendingEvents();
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Error processing PLEvents");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
NS_IMPL_THREADSAFE_ISUPPORTS1(nsToolkit, nsIToolkit);
|
||||||
|
|
||||||
|
|
||||||
|
// assume we begin as the fg app
|
||||||
|
bool nsToolkit::sInForeground = true;
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsToolkit::nsToolkit() : mInited(false)
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
if (gEventQueueHandler == nsnull)
|
||||||
|
gEventQueueHandler = new nsMacNSPREventQueueHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsToolkit::~nsToolkit()
|
||||||
|
{
|
||||||
|
nsWidgetAtoms::ReleaseAtoms();
|
||||||
|
|
||||||
|
/* StopPumping decrements a refcount on gEventQueueHandler; a prelude toward
|
||||||
|
stopping event handling. This is not something you want to do unless you've
|
||||||
|
bloody well started event handling and incremented the refcount. That's
|
||||||
|
done in the Init method, not the constructor, and that's what mInited is about.
|
||||||
|
*/
|
||||||
|
if (mInited && gEventQueueHandler) {
|
||||||
|
if (gEventQueueHandler->StopPumping()) {
|
||||||
|
delete gEventQueueHandler;
|
||||||
|
gEventQueueHandler = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove the TLS reference to the toolkit...
|
||||||
|
PR_SetThreadPrivate(gToolkitTLSIndex, nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsToolkit::Init(PRThread */*aThread*/)
|
||||||
|
{
|
||||||
|
if (gEventQueueHandler)
|
||||||
|
gEventQueueHandler->StartPumping();
|
||||||
|
|
||||||
|
nsWidgetAtoms::AddRefAtoms();
|
||||||
|
|
||||||
|
mInited = true;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
PRBool nsToolkit::ToolkitBusy()
|
||||||
|
{
|
||||||
|
return (gEventQueueHandler) ? gEventQueueHandler->EventsArePending() : PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
bool nsToolkit::HasAppearanceManager()
|
||||||
|
{
|
||||||
|
|
||||||
|
#define APPEARANCE_MIN_VERSION 0x0110 // we require version 1.1
|
||||||
|
|
||||||
|
static bool inited = false;
|
||||||
|
static bool hasAppearanceManager = false;
|
||||||
|
|
||||||
|
if (inited)
|
||||||
|
return hasAppearanceManager;
|
||||||
|
inited = true;
|
||||||
|
|
||||||
|
SInt32 result;
|
||||||
|
if (::Gestalt(gestaltAppearanceAttr, &result) != noErr)
|
||||||
|
return false; // no Appearance Mgr
|
||||||
|
|
||||||
|
if (::Gestalt(gestaltAppearanceVersion, &result) != noErr)
|
||||||
|
return false; // still version 1.0
|
||||||
|
|
||||||
|
hasAppearanceManager = (result >= APPEARANCE_MIN_VERSION);
|
||||||
|
|
||||||
|
return hasAppearanceManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsToolkit :: AppInForeground ( )
|
||||||
|
{
|
||||||
|
sInForeground = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsToolkit :: AppInBackground ( )
|
||||||
|
{
|
||||||
|
sInForeground = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsToolkit :: IsAppInForeground ( )
|
||||||
|
{
|
||||||
|
return sInForeground;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Return the nsIToolkit for the current thread. If a toolkit does not
|
||||||
|
// yet exist, then one will be created...
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
|
||||||
|
{
|
||||||
|
nsIToolkit* toolkit = nsnull;
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
PRStatus status;
|
||||||
|
|
||||||
|
// Create the TLS index the first time through...
|
||||||
|
if (0 == gToolkitTLSIndex) {
|
||||||
|
status = PR_NewThreadPrivateIndex(&gToolkitTLSIndex, NULL);
|
||||||
|
if (PR_FAILURE == status) {
|
||||||
|
rv = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
toolkit = (nsIToolkit*)PR_GetThreadPrivate(gToolkitTLSIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a new toolkit for this thread...
|
||||||
|
//
|
||||||
|
if (!toolkit) {
|
||||||
|
toolkit = new nsToolkit();
|
||||||
|
|
||||||
|
if (!toolkit) {
|
||||||
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
} else {
|
||||||
|
NS_ADDREF(toolkit);
|
||||||
|
toolkit->Init(PR_GetCurrentThread());
|
||||||
|
//
|
||||||
|
// The reference stored in the TLS is weak. It is removed in the
|
||||||
|
// nsToolkit destructor...
|
||||||
|
//
|
||||||
|
PR_SetThreadPrivate(gToolkitTLSIndex, (void*)toolkit);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NS_ADDREF(toolkit);
|
||||||
|
}
|
||||||
|
*aResult = toolkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
Handle nsMacMemoryCushion::sMemoryReserve;
|
||||||
|
|
||||||
|
nsMacMemoryCushion::nsMacMemoryCushion()
|
||||||
|
: mBufferHandle(nsnull)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMacMemoryCushion::~nsMacMemoryCushion()
|
||||||
|
{
|
||||||
|
::SetGrowZone(nsnull);
|
||||||
|
if (sMemoryReserve)
|
||||||
|
::DisposeHandle(sMemoryReserve);
|
||||||
|
|
||||||
|
if (mBufferHandle)
|
||||||
|
::DisposeHandle(mBufferHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OSErr nsMacMemoryCushion::Init(Size bufferSize, Size reserveSize)
|
||||||
|
{
|
||||||
|
sMemoryReserve = ::NewHandle(reserveSize);
|
||||||
|
if (sMemoryReserve == nsnull)
|
||||||
|
return ::MemError();
|
||||||
|
|
||||||
|
mBufferHandle = ::NewHandle(bufferSize);
|
||||||
|
if (mBufferHandle == nsnull)
|
||||||
|
return ::MemError();
|
||||||
|
|
||||||
|
// make this purgable
|
||||||
|
::HPurge(mBufferHandle);
|
||||||
|
|
||||||
|
#if !TARGET_CARBON
|
||||||
|
::SetGrowZone(NewGrowZoneProc(GrowZoneProc));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void nsMacMemoryCushion::RepeatAction(const EventRecord &aMacEvent)
|
||||||
|
{
|
||||||
|
if (!RecoverMemoryReserve(kMemoryReserveSize))
|
||||||
|
{
|
||||||
|
// NS_ASSERTION(0, "Failed to recallocate memory reserve. Flushing caches");
|
||||||
|
nsMemory::HeapMinimize(PR_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Boolean nsMacMemoryCushion::RecoverMemoryReserve(Size reserveSize)
|
||||||
|
{
|
||||||
|
if (!sMemoryReserve) return true; // not initted yet
|
||||||
|
if (*sMemoryReserve != nsnull) return true; // everything is OK
|
||||||
|
|
||||||
|
::ReallocateHandle(sMemoryReserve, reserveSize);
|
||||||
|
if (::MemError() != noErr || !*sMemoryReserve) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean nsMacMemoryCushion::RecoverMemoryBuffer(Size bufferSize)
|
||||||
|
{
|
||||||
|
if (!mBufferHandle) return true; // not initted yet
|
||||||
|
if (*mBufferHandle != nsnull) return true; // everything is OK
|
||||||
|
|
||||||
|
::ReallocateHandle(mBufferHandle, bufferSize);
|
||||||
|
if (::MemError() != noErr || !*mBufferHandle) return false;
|
||||||
|
|
||||||
|
// make this purgable
|
||||||
|
::HPurge(mBufferHandle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pascal long nsMacMemoryCushion::GrowZoneProc(Size amountNeeded)
|
||||||
|
{
|
||||||
|
long freedMem = 0;
|
||||||
|
|
||||||
|
if (sMemoryReserve && *sMemoryReserve && sMemoryReserve != ::GZSaveHnd())
|
||||||
|
{
|
||||||
|
freedMem = ::GetHandleSize(sMemoryReserve);
|
||||||
|
::EmptyHandle(sMemoryReserve);
|
||||||
|
}
|
||||||
|
|
||||||
|
return freedMem;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
* 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 TOOLKIT_H
|
||||||
|
#define TOOLKIT_H
|
||||||
|
|
||||||
|
#include "nsIToolkit.h"
|
||||||
|
#include "nsRepeater.h"
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIEventQueueService.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The toolkit abstraction is necessary because the message pump must
|
||||||
|
* execute within the same thread that created the widget under Win32.
|
||||||
|
* We don't care about that on Mac: we have only one thread for the UI
|
||||||
|
* and maybe even for the whole application.
|
||||||
|
*
|
||||||
|
* So on the Mac, the nsToolkit used to be a unique object, created once
|
||||||
|
* at startup along with nsAppShell and passed to all the top-level
|
||||||
|
* windows and it became a convenient place to throw in everything we
|
||||||
|
* didn't know where else to put, like the NSPR event queue and
|
||||||
|
* the handling of global pointers on some special widgets (focused
|
||||||
|
* widget, widget hit, widget pointed).
|
||||||
|
*
|
||||||
|
* All this has changed: the application now usually creates one copy of
|
||||||
|
* the nsToolkit per window and the special widgets had to be moved
|
||||||
|
* to the nsMacEventHandler. Also, to avoid creating several repeaters,
|
||||||
|
* the NSPR event queue has been moved to a global object of its own:
|
||||||
|
* the nsMacNSPREventQueueHandler declared below.
|
||||||
|
*
|
||||||
|
* If by any chance we support one day several threads for the UI
|
||||||
|
* on the Mac, will have to create one instance of the NSPR
|
||||||
|
* event queue per nsToolkit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <MacTypes.h>
|
||||||
|
|
||||||
|
class nsToolkit : public nsIToolkit
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsToolkit();
|
||||||
|
virtual ~nsToolkit();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
NS_IMETHOD Init(PRThread *aThread);
|
||||||
|
|
||||||
|
// are there pending events on the toolkit's event queue?
|
||||||
|
PRBool ToolkitBusy();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Appearance Mgr
|
||||||
|
static bool HasAppearanceManager();
|
||||||
|
|
||||||
|
// helpers to determine if the app is in the fg or bg
|
||||||
|
static void AppInForeground ( ) ;
|
||||||
|
static void AppInBackground ( ) ;
|
||||||
|
static bool IsAppInForeground ( ) ;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool mInited;
|
||||||
|
static bool sInForeground;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class nsMacNSPREventQueueHandler : public Repeater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsMacNSPREventQueueHandler();
|
||||||
|
virtual ~nsMacNSPREventQueueHandler();
|
||||||
|
|
||||||
|
virtual void StartPumping();
|
||||||
|
virtual PRBool StopPumping();
|
||||||
|
|
||||||
|
// Repeater interface
|
||||||
|
virtual void RepeatAction(const EventRecord& inMacEvent);
|
||||||
|
|
||||||
|
PRBool EventsArePending();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void ProcessPLEventQueue();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
nsrefcnt mRefCnt;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIEventQueueService> mEventQueueService;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// class for low memory detection and handling
|
||||||
|
class nsMacMemoryCushion : public Repeater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kMemoryBufferSize = 64 * 1024, // 64k reserve, purgeable handle purged first
|
||||||
|
kMemoryReserveSize = 32 * 1024 // 32k memory reserve, freed by the GrowZoneProc
|
||||||
|
};
|
||||||
|
|
||||||
|
nsMacMemoryCushion();
|
||||||
|
~nsMacMemoryCushion();
|
||||||
|
|
||||||
|
OSErr Init(Size bufferSize, Size reserveSize);
|
||||||
|
|
||||||
|
|
||||||
|
void RepeatAction(const EventRecord &aMacEvent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// reallocate the memory buffer. Returns true on success
|
||||||
|
Boolean RecoverMemoryBuffer(Size bufferSize);
|
||||||
|
|
||||||
|
// allocate or recover the memory reserve. Returns true on success
|
||||||
|
Boolean RecoverMemoryReserve(Size reserveSize);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static pascal long GrowZoneProc(Size amountNeeded);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
static Handle sMemoryReserve;
|
||||||
|
|
||||||
|
Handle mBufferHandle; // this is first to go
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // TOOLKIT_H
|
|
@ -0,0 +1,171 @@
|
||||||
|
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "nsWatchTask.h"
|
||||||
|
#include <LowMem.h>
|
||||||
|
#include <Appearance.h>
|
||||||
|
|
||||||
|
|
||||||
|
// our global, as soon as the gfx code fragment loads, this will setup
|
||||||
|
// the VBL task automagically.
|
||||||
|
nsWatchTask gWatchTask;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetTask
|
||||||
|
//
|
||||||
|
// A nice little getter to avoid exposing the global variable
|
||||||
|
nsWatchTask&
|
||||||
|
nsWatchTask :: GetTask ( )
|
||||||
|
{
|
||||||
|
return gWatchTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsWatchTask :: nsWatchTask ( )
|
||||||
|
: mChecksum('mozz'), mSelf(this), mTicks(::TickCount()), mBusy(PR_FALSE), mSuspended(PR_FALSE),
|
||||||
|
mInstallSucceeded(PR_FALSE), mAnimation(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsWatchTask :: ~nsWatchTask ( )
|
||||||
|
{
|
||||||
|
#if !TARGET_CARBON
|
||||||
|
if ( mInstallSucceeded )
|
||||||
|
::VRemove ( (QElemPtr)&mTask );
|
||||||
|
#endif
|
||||||
|
InitCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start
|
||||||
|
//
|
||||||
|
// Registers the VBL task and does other various init tasks to begin
|
||||||
|
// watching for time away from the event loop. It is ok to call other
|
||||||
|
// methods on this object w/out calling Start().
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsWatchTask :: Start ( )
|
||||||
|
{
|
||||||
|
#if !TARGET_CARBON
|
||||||
|
// get the watch cursor and lock it high
|
||||||
|
CursHandle watch = ::GetCursor ( watchCursor );
|
||||||
|
if ( !watch )
|
||||||
|
return;
|
||||||
|
mWatchCursor = **watch;
|
||||||
|
|
||||||
|
// setup the task
|
||||||
|
mTask.qType = vType;
|
||||||
|
mTask.vblAddr = NewVBLProc((VBLProcPtr)DoWatchTask);
|
||||||
|
mTask.vblCount = kRepeatInterval;
|
||||||
|
mTask.vblPhase = 0;
|
||||||
|
|
||||||
|
// install it
|
||||||
|
mInstallSucceeded = ::VInstall((QElemPtr)&mTask) == noErr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // Start
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// DoWatchTask
|
||||||
|
//
|
||||||
|
// Called at vertical retrace. If we haven't been to the event loop for
|
||||||
|
// |kTicksToShowWatch| ticks, animate the cursor.
|
||||||
|
//
|
||||||
|
// Note: assumes that the VBLTask, mTask, is the first member variable, so
|
||||||
|
// that we can piggy-back off the pointer to get to the rest of our data.
|
||||||
|
//
|
||||||
|
// (Do we still need the check for LMGetCrsrBusy()? It's not in carbon...)
|
||||||
|
//
|
||||||
|
pascal void
|
||||||
|
nsWatchTask :: DoWatchTask ( nsWatchTask* inSelf )
|
||||||
|
{
|
||||||
|
if ( inSelf->mChecksum == 'mozz' ) {
|
||||||
|
if ( !inSelf->mSuspended ) {
|
||||||
|
#if TARGET_CARBON
|
||||||
|
PRBool busy = inSelf->mBusy;
|
||||||
|
#else
|
||||||
|
PRBool busy = inSelf->mBusy && LMGetCrsrBusy();
|
||||||
|
#endif
|
||||||
|
if ( !busy ) {
|
||||||
|
if ( ::TickCount() - inSelf->mTicks > kTicksToShowWatch ) {
|
||||||
|
::SetCursor ( &(inSelf->mWatchCursor) );
|
||||||
|
inSelf->mBusy = PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
::SetCursor ( &(inSelf->mWatchCursor) );
|
||||||
|
|
||||||
|
// next frame in cursor animation
|
||||||
|
++inSelf->mAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !TARGET_CARBON
|
||||||
|
// reset the task to fire again
|
||||||
|
inSelf->mTask.vblCount = kRepeatInterval;
|
||||||
|
#endif
|
||||||
|
} // if valid checksum
|
||||||
|
|
||||||
|
} // DoWatchTask
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// EventLoopReached
|
||||||
|
//
|
||||||
|
// Called every time we reach the event loop (or an event loop), this tickles
|
||||||
|
// our internal tick count to reset the time since our last visit to WNE and
|
||||||
|
// if we were busy, we're not any more.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsWatchTask :: EventLoopReached ( )
|
||||||
|
{
|
||||||
|
// reset the cursor if we were animating it
|
||||||
|
if ( mBusy )
|
||||||
|
::InitCursor();
|
||||||
|
|
||||||
|
mBusy = PR_FALSE;
|
||||||
|
mTicks = ::TickCount();
|
||||||
|
mAnimation = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,425 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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):
|
||||||
|
* Dan Rosen <dr@netscape.com>
|
||||||
|
*
|
||||||
|
* 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 "nsIFactory.h"
|
||||||
|
#include "nsISupports.h"
|
||||||
|
#include "nsWidgetsCID.h"
|
||||||
|
|
||||||
|
#include "nsToolkit.h"
|
||||||
|
#include "nsChildView.h"
|
||||||
|
#include "nsCocoaWindow.h"
|
||||||
|
#include "nsAppShellCocoa.h"
|
||||||
|
#include "nsFilePicker.h"
|
||||||
|
|
||||||
|
#if TARGET_CARBON
|
||||||
|
#include "nsMenuBarX.h"
|
||||||
|
#include "nsMenuX.h"
|
||||||
|
#include "nsMenuItemX.h"
|
||||||
|
|
||||||
|
#define nsMenuBar nsMenuBarX
|
||||||
|
#define nsMenu nsMenuX
|
||||||
|
#define nsMenuItem nsMenuItemX
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include "nsMenuBar.h"
|
||||||
|
#include "nsMenu.h"
|
||||||
|
#include "nsMenuItem.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nsClipboard.h"
|
||||||
|
#include "nsClipboardHelper.h"
|
||||||
|
#include "nsTransferable.h"
|
||||||
|
#include "nsHTMLFormatConverter.h"
|
||||||
|
#include "nsDragService.h"
|
||||||
|
|
||||||
|
#if USE_NATIVE_VERSION
|
||||||
|
# include "nsCheckButton.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nsLookAndFeel.h"
|
||||||
|
|
||||||
|
#include "nsIComponentManager.h"
|
||||||
|
|
||||||
|
#include "nsSound.h"
|
||||||
|
#include "nsTimerMac.h"
|
||||||
|
|
||||||
|
#ifdef IBMBIDI
|
||||||
|
#include "nsBidiKeyboard.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
|
||||||
|
#include "nsIGenericFactory.h"
|
||||||
|
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCocoaWindow)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildView)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAppShellCocoa)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMenuBar)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMenu)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMenuItem)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
|
||||||
|
//NS_GENERIC_FACTORY_CONSTRUCTOR(nsFileSpecWithUIImpl)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
|
||||||
|
#ifdef IBMBIDI
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static nsModuleComponentInfo components[] =
|
||||||
|
{
|
||||||
|
{ "Timer",
|
||||||
|
NS_TIMER_CID,
|
||||||
|
"@mozilla.org/timer;1",
|
||||||
|
nsTimerImplConstructor },
|
||||||
|
{ "nsWindow",
|
||||||
|
NS_WINDOW_CID,
|
||||||
|
"@mozilla.org/widgets/window/mac;1",
|
||||||
|
nsCocoaWindowConstructor },
|
||||||
|
{ "Popup nsWindow",
|
||||||
|
NS_POPUP_CID,
|
||||||
|
"@mozilla.org/widgets/popup/mac;1",
|
||||||
|
nsCocoaWindowConstructor },
|
||||||
|
{ "Child nsWindow",
|
||||||
|
NS_CHILD_CID,
|
||||||
|
"@mozilla.org/widgets/childwindow/mac;1",
|
||||||
|
nsChildViewConstructor },
|
||||||
|
{ "File Picker",
|
||||||
|
NS_FILEPICKER_CID,
|
||||||
|
"@mozilla.org/filepicker;1",
|
||||||
|
nsFilePickerConstructor },
|
||||||
|
{ "AppShell",
|
||||||
|
NS_APPSHELL_CID,
|
||||||
|
"@mozilla.org/widget/appshell/mac;1",
|
||||||
|
nsAppShellCocoaConstructor },
|
||||||
|
{ "Toolkit",
|
||||||
|
NS_TOOLKIT_CID,
|
||||||
|
"@mozilla.org/widget/toolkit/mac;1",
|
||||||
|
nsToolkitConstructor },
|
||||||
|
{ "Look And Feel",
|
||||||
|
NS_LOOKANDFEEL_CID,
|
||||||
|
"@mozilla.org/widget/lookandfeel/mac;1",
|
||||||
|
nsLookAndFeelConstructor },
|
||||||
|
{ "Menubar",
|
||||||
|
NS_MENUBAR_CID,
|
||||||
|
"@mozilla.org/widget/menubar/mac;1",
|
||||||
|
nsMenuBarConstructor },
|
||||||
|
{ "Menu",
|
||||||
|
NS_MENU_CID,
|
||||||
|
"@mozilla.org/widget/menu/mac;1",
|
||||||
|
nsMenuConstructor },
|
||||||
|
{ "MenuItem",
|
||||||
|
NS_MENUITEM_CID,
|
||||||
|
"@mozilla.org/widget/menuitem/mac;1",
|
||||||
|
nsMenuItemConstructor },
|
||||||
|
{ "Sound",
|
||||||
|
NS_SOUND_CID,
|
||||||
|
"@mozilla.org/sound;1",
|
||||||
|
nsSoundConstructor },
|
||||||
|
{ "Transferable",
|
||||||
|
NS_TRANSFERABLE_CID,
|
||||||
|
"@mozilla.org/widget/transferable;1",
|
||||||
|
nsTransferableConstructor },
|
||||||
|
{ "HTML Format Converter",
|
||||||
|
NS_HTMLFORMATCONVERTER_CID,
|
||||||
|
"@mozilla.org/widget/htmlformatconverter/mac;1",
|
||||||
|
nsHTMLFormatConverterConstructor },
|
||||||
|
{ "Clipboard",
|
||||||
|
NS_CLIPBOARD_CID,
|
||||||
|
"@mozilla.org/widget/clipboard;1",
|
||||||
|
nsClipboardConstructor },
|
||||||
|
{ "Clipboard Helper",
|
||||||
|
NS_CLIPBOARDHELPER_CID,
|
||||||
|
"@mozilla.org/widget/clipboardhelper;1",
|
||||||
|
nsClipboardHelperConstructor },
|
||||||
|
{ "Drag Service",
|
||||||
|
NS_DRAGSERVICE_CID,
|
||||||
|
"@mozilla.org/widget/dragservice;1",
|
||||||
|
nsDragServiceConstructor },
|
||||||
|
#ifdef IBMBIDI
|
||||||
|
{ "Gtk Bidi Keyboard",
|
||||||
|
NS_BIDIKEYBOARD_CID,
|
||||||
|
"@mozilla.org/widget/bidikeyboard;1",
|
||||||
|
nsBidiKeyboardConstructor },
|
||||||
|
#endif // IBMBIDI
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_NSGETMODULE(nsWidgetModule, components)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// NOTE the following does not match MAC_STATIC actually used below in this file!
|
||||||
|
#define MACSTATIC
|
||||||
|
|
||||||
|
static NS_DEFINE_CID(kCWindow, NS_WINDOW_CID);
|
||||||
|
static NS_DEFINE_IID(kCTimer, NS_TIMER_CID);
|
||||||
|
static NS_DEFINE_CID(kCPopUp, NS_POPUP_CID);
|
||||||
|
static NS_DEFINE_CID(kCChild, NS_CHILD_CID);
|
||||||
|
static NS_DEFINE_CID(kCButton, NS_BUTTON_CID);
|
||||||
|
static NS_DEFINE_CID(kCCheckButton, NS_CHECKBUTTON_CID);
|
||||||
|
static NS_DEFINE_CID(kCFilePicker, NS_FILEPICKER_CID);
|
||||||
|
static NS_DEFINE_CID(kCHorzScrollbar, NS_HORZSCROLLBAR_CID);
|
||||||
|
static NS_DEFINE_CID(kCVertScrollbar, NS_VERTSCROLLBAR_CID);
|
||||||
|
static NS_DEFINE_CID(kCTextField, NS_TEXTFIELD_CID);
|
||||||
|
static NS_DEFINE_CID(kCAppShell, NS_APPSHELL_CID);
|
||||||
|
static NS_DEFINE_CID(kCToolkit, NS_TOOLKIT_CID);
|
||||||
|
static NS_DEFINE_CID(kCLookAndFeel, NS_LOOKANDFEEL_CID);
|
||||||
|
static NS_DEFINE_CID(kCLabel, NS_LABEL_CID);
|
||||||
|
static NS_DEFINE_CID(kCMenuBar, NS_MENUBAR_CID);
|
||||||
|
static NS_DEFINE_CID(kCMenu, NS_MENU_CID);
|
||||||
|
static NS_DEFINE_CID(kCMenuItem, NS_MENUITEM_CID);
|
||||||
|
static NS_DEFINE_CID(kCPopUpMenu, NS_POPUPMENU_CID);
|
||||||
|
|
||||||
|
// Drag and Drop/Clipboard
|
||||||
|
static NS_DEFINE_CID(kCDataFlavor, NS_DATAFLAVOR_CID);
|
||||||
|
static NS_DEFINE_CID(kCClipboard, NS_CLIPBOARD_CID);
|
||||||
|
static NS_DEFINE_CID(kCClipboardHelper, NS_CLIPBOARDHELPER_CID);
|
||||||
|
static NS_DEFINE_CID(kCTransferable, NS_TRANSFERABLE_CID);
|
||||||
|
static NS_DEFINE_CID(kCHTMLFormatConverter, NS_HTMLFORMATCONVERTER_CID);
|
||||||
|
static NS_DEFINE_CID(kCDragService, NS_DRAGSERVICE_CID);
|
||||||
|
|
||||||
|
// Sound services (just Beep for now)
|
||||||
|
static NS_DEFINE_CID(kCSound, NS_SOUND_CID);
|
||||||
|
|
||||||
|
#ifdef IBMBIDI
|
||||||
|
static NS_DEFINE_CID(kCBidiKeyboard, NS_BIDIKEYBOARD_CID);
|
||||||
|
#endif
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
class nsWidgetFactory : public nsIFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
// nsIFactory methods
|
||||||
|
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
||||||
|
const nsIID &aIID,
|
||||||
|
void **aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD LockFactory(PRBool aLock);
|
||||||
|
|
||||||
|
nsWidgetFactory(const nsCID &aClass);
|
||||||
|
virtual ~nsWidgetFactory();
|
||||||
|
private:
|
||||||
|
nsCID mClassID;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsWidgetFactory::nsWidgetFactory(const nsCID &aClass)
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
mClassID = aClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsWidgetFactory::~nsWidgetFactory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMPL_ISUPPORTS1(nsWidgetFactory, nsIFactory)
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ***IMPORTANT***
|
||||||
|
// On all platforms, we are assuming in places that the implementation of |nsIWidget|
|
||||||
|
// is really |nsWindow| and then calling methods specific to nsWindow to finish the job.
|
||||||
|
// This is by design and the assumption is safe because an nsIWidget can only be created through
|
||||||
|
// our Widget factory where all our widgets, including the XP widgets, inherit from nsWindow.
|
||||||
|
// A similar warning is in nsWindow.cpp.
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsresult nsWidgetFactory::CreateInstance(nsISupports *aOuter,
|
||||||
|
const nsIID &aIID,
|
||||||
|
void **aResult)
|
||||||
|
{
|
||||||
|
if (aResult == NULL) {
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
*aResult = NULL;
|
||||||
|
if (nsnull != aOuter) {
|
||||||
|
return NS_ERROR_NO_AGGREGATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsISupports *inst = nsnull;
|
||||||
|
|
||||||
|
if (mClassID.Equals(kCTimer)) {
|
||||||
|
inst = (nsISupports*)new nsTimerImpl();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCWindow)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)new nsCocoaWindow();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCPopUp)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)new nsCocoaWindow();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCChild)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)new nsChildView();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCButton)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsButton();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCFilePicker)) {
|
||||||
|
inst = (nsISupports*)(nsBaseFilePicker*)new nsFilePicker();
|
||||||
|
}
|
||||||
|
#if USE_NATIVE_VERSION
|
||||||
|
else if (mClassID.Equals(kCCheckButton)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsCheckButton();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (mClassID.Equals(kCHorzScrollbar)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsScrollbar(PR_FALSE);
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCVertScrollbar)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsScrollbar(PR_TRUE);
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCTextField)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsTextWidget();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCAppShell)) {
|
||||||
|
inst = (nsISupports*)new nsAppShellCocoa();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCToolkit)) {
|
||||||
|
inst = (nsISupports*)new nsToolkit();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCLookAndFeel)) {
|
||||||
|
inst = (nsISupports*)new nsLookAndFeel();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCLabel)) {
|
||||||
|
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsLabel();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCMenuBar)) {
|
||||||
|
inst = (nsISupports*)(nsIMenuBar*) new nsMenuBar();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCMenu)) {
|
||||||
|
inst = (nsISupports*)(nsIMenu*) new nsMenu();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCMenuItem)) {
|
||||||
|
inst = (nsISupports*)(nsIMenuItem*) new nsMenuItem();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCPopUpMenu)) {
|
||||||
|
// inst = (nsISupports*)new nsPopUpMenu();
|
||||||
|
NS_NOTYETIMPLEMENTED("nsPopUpMenu");
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCSound)) {
|
||||||
|
inst = (nsISupports*)(nsISound*) new nsSound();
|
||||||
|
}
|
||||||
|
else if (mClassID.Equals(kCTransferable))
|
||||||
|
inst = (nsISupports*)new nsTransferable();
|
||||||
|
else if (mClassID.Equals(kCHTMLFormatConverter))
|
||||||
|
inst = (nsISupports*)new nsHTMLFormatConverter();
|
||||||
|
else if (mClassID.Equals(kCClipboard))
|
||||||
|
inst = (nsISupports*)new nsClipboard();
|
||||||
|
else if (mClassID.Equals(kCClipboardHelper))
|
||||||
|
inst = (nsISupports*)new nsClipboardHelper();
|
||||||
|
else if (mClassID.Equals(kCDragService))
|
||||||
|
inst = (nsISupports*)NS_STATIC_CAST(nsIDragService*, new nsDragService());
|
||||||
|
#ifdef IBMBIDI
|
||||||
|
else if (mClassID.Equals(kCBidiKeyboard))
|
||||||
|
inst = (nsISupports*)(nsIBidiKeyboard*) new nsBidiKeyboard();
|
||||||
|
#endif // IBMBIDI
|
||||||
|
|
||||||
|
if (inst == NULL) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(inst);
|
||||||
|
nsresult res = inst->QueryInterface(aIID, aResult);
|
||||||
|
NS_RELEASE(inst);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
nsresult nsWidgetFactory::LockFactory(PRBool aLock)
|
||||||
|
{
|
||||||
|
// Not implemented in simplest case.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// return the proper factory to the caller
|
||||||
|
#if defined(XP_MAC) && defined(MAC_STATIC)
|
||||||
|
extern "C" NS_WIDGET nsresult
|
||||||
|
NSGetFactory_WIDGET_DLL(nsISupports* serviceMgr,
|
||||||
|
const nsCID &aClass,
|
||||||
|
const char *aClassName,
|
||||||
|
const char *aContractID,
|
||||||
|
nsIFactory **aFactory)
|
||||||
|
#else
|
||||||
|
extern "C" NS_WIDGET nsresult
|
||||||
|
NSGetFactory(nsISupports* serviceMgr,
|
||||||
|
const nsCID &aClass,
|
||||||
|
const char *aClassName,
|
||||||
|
const char *aContractID,
|
||||||
|
nsIFactory **aFactory)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (nsnull == aFactory) {
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aFactory = new nsWidgetFactory(aClass);
|
||||||
|
|
||||||
|
if (nsnull == aFactory) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*aFactory)->QueryInterface(NS_GET_IID(nsIFactory), (void**)aFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Загрузка…
Ссылка в новой задаче