Back to index

lightning-sunbird  0.9+nobinonly
nsCommonWidget.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  *  Zack Rusin <zack@kde.org>.
00020  * Portions created by the Initial Developer are Copyright (C) 2004
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Lars Knoll <knoll@kde.org>
00025  *   Zack Rusin <zack@kde.org>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 #include "nsCommonWidget.h"
00041 
00042 #include "nsGUIEvent.h"
00043 #include "nsQtEventDispatcher.h"
00044 #include "nsIRenderingContext.h"
00045 #include "nsIServiceManager.h"
00046 #include "nsGfxCIID.h"
00047 #include "nsIPrefBranch.h"
00048 #include "nsIPrefService.h"
00049 
00050 #include "mozqwidget.h"
00051 
00052 #include <qapplication.h>
00053 #include <qdesktopwidget.h>
00054 #include <qwidget.h>
00055 #include <qcursor.h>
00056 #include <execinfo.h>
00057 #include <stdlib.h>
00058 
00059 #include <execinfo.h>
00060 #include <stdlib.h>
00061 
00062 static const int WHEEL_DELTA = 120;
00063 static const int kWindowPositionSlop = 20;
00064 
00065 struct nsKeyConverter
00066 {
00067     int vkCode; // Platform independent key code
00068     int keysym; // Qt key code
00069 };
00070 
00071 static void backTrace()
00072 {
00073     int levels = -1;
00074     QString s;
00075     void* trace[256];
00076     int n = backtrace(trace, 256);
00077     if (!n)
00078        return;
00079     char** strings = backtrace_symbols (trace, n);
00080 
00081     if ( levels != -1 )
00082         n = QMIN( n, levels );
00083     s = "[\n";
00084 
00085     for (int i = 0; i < n; ++i)
00086         s += QString::number(i) +
00087              QString::fromLatin1(": ") +
00088              QString::fromLatin1(strings[i]) + QString::fromLatin1("\n");
00089     s += "]\n";
00090     if (strings)
00091         free (strings);
00092     qDebug("stacktrace:\n%s", s.latin1());
00093 }
00094 
00095 static struct nsKeyConverter nsKeycodes[] =
00096 {
00097 //  { NS_VK_CANCEL,        Qt::Key_Cancel },
00098     { NS_VK_BACK,          Qt::Key_BackSpace },
00099     { NS_VK_TAB,           Qt::Key_Tab },
00100 //  { NS_VK_CLEAR,         Qt::Key_Clear },
00101     { NS_VK_RETURN,        Qt::Key_Return },
00102     { NS_VK_RETURN,        Qt::Key_Enter },
00103     { NS_VK_SHIFT,         Qt::Key_Shift },
00104     { NS_VK_CONTROL,       Qt::Key_Control },
00105     { NS_VK_ALT,           Qt::Key_Alt },
00106     { NS_VK_PAUSE,         Qt::Key_Pause },
00107     { NS_VK_CAPS_LOCK,     Qt::Key_CapsLock },
00108     { NS_VK_ESCAPE,        Qt::Key_Escape },
00109     { NS_VK_SPACE,         Qt::Key_Space },
00110     { NS_VK_PAGE_UP,       Qt::Key_PageUp },
00111     { NS_VK_PAGE_DOWN,     Qt::Key_PageDown },
00112     { NS_VK_END,           Qt::Key_End },
00113     { NS_VK_HOME,          Qt::Key_Home },
00114     { NS_VK_LEFT,          Qt::Key_Left },
00115     { NS_VK_UP,            Qt::Key_Up },
00116     { NS_VK_RIGHT,         Qt::Key_Right },
00117     { NS_VK_DOWN,          Qt::Key_Down },
00118     { NS_VK_PRINTSCREEN,   Qt::Key_Print },
00119     { NS_VK_INSERT,        Qt::Key_Insert },
00120     { NS_VK_DELETE,        Qt::Key_Delete },
00121 
00122     { NS_VK_0,             Qt::Key_0 },
00123     { NS_VK_1,             Qt::Key_1 },
00124     { NS_VK_2,             Qt::Key_2 },
00125     { NS_VK_3,             Qt::Key_3 },
00126     { NS_VK_4,             Qt::Key_4 },
00127     { NS_VK_5,             Qt::Key_5 },
00128     { NS_VK_6,             Qt::Key_6 },
00129     { NS_VK_7,             Qt::Key_7 },
00130     { NS_VK_8,             Qt::Key_8 },
00131     { NS_VK_9,             Qt::Key_9 },
00132 
00133     { NS_VK_SEMICOLON,     Qt::Key_Semicolon },
00134     { NS_VK_EQUALS,        Qt::Key_Equal },
00135 
00136     { NS_VK_A,             Qt::Key_A },
00137     { NS_VK_B,             Qt::Key_B },
00138     { NS_VK_C,             Qt::Key_C },
00139     { NS_VK_D,             Qt::Key_D },
00140     { NS_VK_E,             Qt::Key_E },
00141     { NS_VK_F,             Qt::Key_F },
00142     { NS_VK_G,             Qt::Key_G },
00143     { NS_VK_H,             Qt::Key_H },
00144     { NS_VK_I,             Qt::Key_I },
00145     { NS_VK_J,             Qt::Key_J },
00146     { NS_VK_K,             Qt::Key_K },
00147     { NS_VK_L,             Qt::Key_L },
00148     { NS_VK_M,             Qt::Key_M },
00149     { NS_VK_N,             Qt::Key_N },
00150     { NS_VK_O,             Qt::Key_O },
00151     { NS_VK_P,             Qt::Key_P },
00152     { NS_VK_Q,             Qt::Key_Q },
00153     { NS_VK_R,             Qt::Key_R },
00154     { NS_VK_S,             Qt::Key_S },
00155     { NS_VK_T,             Qt::Key_T },
00156     { NS_VK_U,             Qt::Key_U },
00157     { NS_VK_V,             Qt::Key_V },
00158     { NS_VK_W,             Qt::Key_W },
00159     { NS_VK_X,             Qt::Key_X },
00160     { NS_VK_Y,             Qt::Key_Y },
00161     { NS_VK_Z,             Qt::Key_Z },
00162 
00163     { NS_VK_NUMPAD0,       Qt::Key_0 },
00164     { NS_VK_NUMPAD1,       Qt::Key_1 },
00165     { NS_VK_NUMPAD2,       Qt::Key_2 },
00166     { NS_VK_NUMPAD3,       Qt::Key_3 },
00167     { NS_VK_NUMPAD4,       Qt::Key_4 },
00168     { NS_VK_NUMPAD5,       Qt::Key_5 },
00169     { NS_VK_NUMPAD6,       Qt::Key_6 },
00170     { NS_VK_NUMPAD7,       Qt::Key_7 },
00171     { NS_VK_NUMPAD8,       Qt::Key_8 },
00172     { NS_VK_NUMPAD9,       Qt::Key_9 },
00173     { NS_VK_MULTIPLY,      Qt::Key_Asterisk },
00174     { NS_VK_ADD,           Qt::Key_Plus },
00175 //  { NS_VK_SEPARATOR,     Qt::Key_Separator },
00176     { NS_VK_SUBTRACT,      Qt::Key_Minus },
00177     { NS_VK_DECIMAL,       Qt::Key_Period },
00178     { NS_VK_DIVIDE,        Qt::Key_Slash },
00179     { NS_VK_F1,            Qt::Key_F1 },
00180     { NS_VK_F2,            Qt::Key_F2 },
00181     { NS_VK_F3,            Qt::Key_F3 },
00182     { NS_VK_F4,            Qt::Key_F4 },
00183     { NS_VK_F5,            Qt::Key_F5 },
00184     { NS_VK_F6,            Qt::Key_F6 },
00185     { NS_VK_F7,            Qt::Key_F7 },
00186     { NS_VK_F8,            Qt::Key_F8 },
00187     { NS_VK_F9,            Qt::Key_F9 },
00188     { NS_VK_F10,           Qt::Key_F10 },
00189     { NS_VK_F11,           Qt::Key_F11 },
00190     { NS_VK_F12,           Qt::Key_F12 },
00191     { NS_VK_F13,           Qt::Key_F13 },
00192     { NS_VK_F14,           Qt::Key_F14 },
00193     { NS_VK_F15,           Qt::Key_F15 },
00194     { NS_VK_F16,           Qt::Key_F16 },
00195     { NS_VK_F17,           Qt::Key_F17 },
00196     { NS_VK_F18,           Qt::Key_F18 },
00197     { NS_VK_F19,           Qt::Key_F19 },
00198     { NS_VK_F20,           Qt::Key_F20 },
00199     { NS_VK_F21,           Qt::Key_F21 },
00200     { NS_VK_F22,           Qt::Key_F22 },
00201     { NS_VK_F23,           Qt::Key_F23 },
00202     { NS_VK_F24,           Qt::Key_F24 },
00203 
00204     { NS_VK_NUM_LOCK,      Qt::Key_NumLock },
00205     { NS_VK_SCROLL_LOCK,   Qt::Key_ScrollLock },
00206 
00207     { NS_VK_COMMA,         Qt::Key_Comma },
00208     { NS_VK_PERIOD,        Qt::Key_Period },
00209     { NS_VK_SLASH,         Qt::Key_Slash },
00210     { NS_VK_BACK_QUOTE,    Qt::Key_QuoteLeft },
00211     { NS_VK_OPEN_BRACKET,  Qt::Key_ParenLeft },
00212     { NS_VK_CLOSE_BRACKET, Qt::Key_ParenRight },
00213     { NS_VK_QUOTE,         Qt::Key_QuoteDbl },
00214 
00215     { NS_VK_META,          Qt::Key_Meta }
00216 };
00217 
00218 static PRInt32 NS_GetKey(PRInt32 aKey)
00219 {
00220     PRInt32 length = sizeof(nsKeycodes) / sizeof(nsKeyConverter);
00221 
00222     for (PRInt32 i = 0; i < length; i++) {
00223         if (nsKeycodes[i].keysym == aKey) {
00224             return nsKeycodes[i].vkCode;
00225         }
00226     }
00227     return 0;
00228 }
00229 
00230 static PRBool
00231 isContextMenuKey(const nsKeyEvent &aKeyEvent)
00232 {
00233     return ((aKeyEvent.keyCode == NS_VK_F10 && aKeyEvent.isShift &&
00234              !aKeyEvent.isControl && !aKeyEvent.isMeta && !aKeyEvent.isAlt) ||
00235             (aKeyEvent.keyCode == NS_VK_CONTEXT_MENU && !aKeyEvent.isShift &&
00236              !aKeyEvent.isControl && !aKeyEvent.isMeta && !aKeyEvent.isAlt));
00237 }
00238 
00239 static void
00240 keyEventToContextMenuEvent(const nsKeyEvent* aKeyEvent,
00241                            nsMouseEvent* aCMEvent)
00242 {
00243     memcpy(aCMEvent, aKeyEvent, sizeof(nsInputEvent));
00244     aCMEvent->message = NS_CONTEXTMENU_KEY;
00245     aCMEvent->isShift = aCMEvent->isControl = PR_FALSE;
00246     aCMEvent->isAlt = aCMEvent->isMeta = PR_FALSE;
00247     aCMEvent->clickCount = 0;
00248     aCMEvent->acceptActivation = PR_FALSE;
00249 }
00250 
00251 nsCommonWidget::nsCommonWidget()
00252     : mContainer(0),
00253       mWidget(0),
00254       mListenForResizes(PR_FALSE),
00255       mNeedsResize(PR_FALSE),
00256       mNeedsShow(PR_FALSE),
00257       mIsShown(PR_FALSE)
00258 {
00259 }
00260 
00261 NS_IMPL_ISUPPORTS_INHERITED0(nsCommonWidget,nsBaseWidget)
00262 nsCommonWidget::~nsCommonWidget()
00263 {
00264     mWidget->deleteLater();
00265     mWidget = 0;
00266 }
00267 
00268 void
00269 nsCommonWidget::Initialize(QWidget *widget)
00270 {
00271     Q_ASSERT(widget);
00272 
00273     mWidget = widget;
00274     mWidget->setMouseTracking(PR_TRUE);
00275     mWidget->setFocusPolicy(QWidget::WheelFocus);
00276 }
00277 
00278 NS_IMETHODIMP
00279 nsCommonWidget::Show(PRBool aState)
00280 {
00281     mIsShown = aState;
00282 
00283     // Ok, someone called show on a window that isn't sized to a sane
00284     // value.  Mark this window as needing to have Show() called on it
00285     // and return.
00286     if ((aState && !AreBoundsSane()) || !mWidget) {
00287 #ifdef DEBUG_WIDGETS
00288         qWarning("XX Bounds are insane or window hasn't been created yet");
00289 #endif
00290         mNeedsShow = PR_TRUE;
00291         return NS_OK;
00292     }
00293 
00294     // If someone is hiding this widget, clear any needing show flag.
00295     if (!aState)
00296         mNeedsShow = PR_FALSE;
00297 
00298     // If someone is showing this window and it needs a resize then
00299     // resize the widget.
00300     if (aState && mNeedsResize) {
00301 #ifdef DEBUG_WIDGETS
00302         qDebug("\tresizing [%d, %d, %d, %d]", mBounds.x, mBounds.y,
00303                mBounds.width, mBounds.height);
00304 #endif
00305         NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height,
00306                      PR_FALSE);
00307     }
00308 
00309     NativeShow(aState);
00310 
00311     return NS_OK;
00312 }
00313 
00314 NS_IMETHODIMP
00315 nsCommonWidget::IsVisible(PRBool &visible)
00316 {
00317     if (mWidget)
00318         visible = mWidget->isVisible();
00319     else
00320         visible = PR_FALSE;
00321     return NS_OK;
00322 }
00323 
00324 NS_IMETHODIMP
00325 nsCommonWidget::ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY)
00326 {
00327     if (mContainer) {
00328         PRInt32 screenWidth  = QApplication::desktop()->width();
00329         PRInt32 screenHeight = QApplication::desktop()->height();
00330         if (aAllowSlop) {
00331             if (*aX < (kWindowPositionSlop - mBounds.width))
00332                 *aX = kWindowPositionSlop - mBounds.width;
00333             if (*aX > (screenWidth - kWindowPositionSlop))
00334                 *aX = screenWidth - kWindowPositionSlop;
00335             if (*aY < (kWindowPositionSlop - mBounds.height))
00336                 *aY = kWindowPositionSlop - mBounds.height;
00337             if (*aY > (screenHeight - kWindowPositionSlop))
00338                 *aY = screenHeight - kWindowPositionSlop;
00339         } else {
00340             if (*aX < 0)
00341                 *aX = 0;
00342             if (*aX > (screenWidth - mBounds.width))
00343                 *aX = screenWidth - mBounds.width;
00344             if (*aY < 0)
00345                 *aY = 0;
00346             if (*aY > (screenHeight - mBounds.height))
00347                 *aY = screenHeight - mBounds.height;
00348         }
00349     }
00350     return NS_OK;
00351 }
00352 
00353 NS_IMETHODIMP
00354 nsCommonWidget::Move(PRInt32 x, PRInt32 y)
00355 {
00356     bool popup = mWidget ? mWidget->isPopup() : false;
00357 
00358     if (!mWidget || (x == mBounds.x && y == mBounds.y &&
00359                      !popup))
00360         return NS_OK;
00361 
00362 #ifdef DEBUG_WIDGETS
00363     qDebug("Move [%d,%d] (%s)", x, y, popup?"popup":"widget");
00364 #endif
00365 
00366     if (!mWidget)
00367         return NS_OK;
00368 
00369     QPoint pos(x, y);
00370     if (mContainer) {
00371         if (mParent && mWidget->isPopup()) {
00372             nsRect oldrect, newrect;
00373             oldrect.x = x;
00374             oldrect.y = y;
00375 
00376             mParent->WidgetToScreen(oldrect, newrect);
00377 
00378             pos = QPoint(newrect.x, newrect.y);
00379 #ifdef DEBUG_WIDGETS
00380             qDebug("pos is [%d,%d]", pos.x(), pos.y());
00381 #endif
00382         } else {
00383             qDebug("Widget within another? (%p)", (void*)mWidget);
00384         }
00385     }
00386 
00387     mBounds.x = pos.x();
00388     mBounds.y = pos.y();
00389 
00390     mWidget->move(pos);
00391 
00392     return NS_OK;
00393 }
00394 
00395 NS_IMETHODIMP
00396 nsCommonWidget::Resize(PRInt32 aWidth,
00397                        PRInt32 aHeight,
00398                        PRBool  aRepaint)
00399 {
00400     mBounds.width = aWidth;
00401     mBounds.height = aHeight;
00402 
00403     if (!mWidget || (mWidget->width() == aWidth &&
00404                      mWidget->height() == aHeight))
00405         return NS_OK;
00406 
00407     // There are several cases here that we need to handle, based on a
00408     // matrix of the visibility of the widget, the sanity of this resize
00409     // and whether or not the widget was previously sane.
00410 
00411     // Has this widget been set to visible?
00412     if (mIsShown) {
00413         // Are the bounds sane?
00414         if (AreBoundsSane()) {
00415             // Yep?  Resize the window
00416             //Maybe, the toplevel has moved
00417             if (mContainer || mNeedsShow)
00418                 NativeResize(mBounds.x, mBounds.y,
00419                              mBounds.width, mBounds.height, aRepaint);
00420             else
00421                 NativeResize(mBounds.width, mBounds.height, aRepaint);
00422 
00423             // Does it need to be shown because it was previously insane?
00424             if (mNeedsShow)
00425                 NativeShow(PR_TRUE);
00426         }
00427         else {
00428             // If someone has set this so that the needs show flag is false
00429             // and it needs to be hidden, update the flag and hide the
00430             // window.  This flag will be cleared the next time someone
00431             // hides the window or shows it.  It also prevents us from
00432             // calling NativeShow(PR_FALSE) excessively on the window which
00433             // causes unneeded X traffic.
00434             if (!mNeedsShow) {
00435                 mNeedsShow = PR_TRUE;
00436                 NativeShow(PR_FALSE);
00437             }
00438         }
00439     }
00440     // If the widget hasn't been shown, mark the widget as needing to be
00441     // resized before it is shown.
00442     else {
00443         if (AreBoundsSane() && mListenForResizes) {
00444             // For widgets that we listen for resizes for (widgets created
00445             // with native parents) we apparently _always_ have to resize.  I
00446             // dunno why, but apparently we're lame like that.
00447             NativeResize(aWidth, aHeight, aRepaint);
00448         }
00449         else {
00450             mNeedsResize = PR_TRUE;
00451         }
00452     }
00453 
00454     // synthesize a resize event if this isn't a toplevel
00455     if (mContainer || mListenForResizes) {
00456         nsRect rect(mBounds.x, mBounds.y, aWidth, aHeight);
00457         nsEventStatus status;
00458         DispatchResizeEvent(rect, status);
00459     }
00460 
00461     return NS_OK;
00462 }
00463 
00464 /*
00465  * XXXX: This sucks because it basically hardcore duplicates the
00466  *       code from the above function.
00467  */
00468 NS_IMETHODIMP
00469 nsCommonWidget::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight,
00470                        PRBool aRepaint)
00471 {
00472 #ifdef DEBUG_WIDGETS
00473     qDebug("Resize : [%d,%d,%d,%d]", aX, aY, aWidth, aHeight);
00474 #endif
00475     if (!mWidget || (mWidget->x() == aX &&
00476                      mWidget->y() == aY &&
00477                      mWidget->height() == aHeight &&
00478                      mWidget->width() == aWidth))
00479         return NS_OK;
00480 
00481     mBounds.x = aX;
00482     mBounds.y = aY;
00483     mBounds.width = aWidth;
00484     mBounds.height = aHeight;
00485 
00486     // There are several cases here that we need to handle, based on a
00487     // matrix of the visibility of the widget, the sanity of this resize
00488     // and whether or not the widget was previously sane.
00489 
00490     // Has this widget been set to visible?
00491     if (mIsShown) {
00492         // Are the bounds sane?
00493         if (AreBoundsSane()) {
00494             // Yep?  Resize the window
00495             NativeResize(aX, aY, aWidth, aHeight, aRepaint);
00496 
00497             // Does it need to be shown because it was previously insane?
00498             if (mNeedsShow)
00499                 NativeShow(PR_TRUE);
00500         }
00501         else {
00502             // If someone has set this so that the needs show flag is false
00503             // and it needs to be hidden, update the flag and hide the
00504             // window.  This flag will be cleared the next time someone
00505             // hides the window or shows it.  It also prevents us from
00506             // calling NativeShow(PR_FALSE) excessively on the window which
00507             // causes unneeded X traffic.
00508             if (!mNeedsShow) {
00509                 mNeedsShow = PR_TRUE;
00510                 NativeShow(PR_FALSE);
00511             }
00512         }
00513     }
00514     // If the widget hasn't been shown, mark the widget as needing to be
00515     // resized before it is shown
00516     else {
00517         if (AreBoundsSane() && mListenForResizes){
00518             // For widgets that we listen for resizes for (widgets created
00519             // with native parents) we apparently _always_ have to resize.  I
00520             // dunno why, but apparently we're lame like that.
00521             NativeResize(aX, aY, aWidth, aHeight, aRepaint);
00522         }
00523         else {
00524             mNeedsResize = PR_TRUE;
00525         }
00526     }
00527 
00528     // synthesize a resize event if this isn't a toplevel
00529     if (mContainer || mListenForResizes) {
00530         nsRect rect(mBounds.x, mBounds.y, mBounds.width, mBounds.height);
00531         nsEventStatus status;
00532         DispatchResizeEvent(rect, status);
00533     }
00534 
00535     return NS_OK;
00536 }
00537 
00538 NS_IMETHODIMP
00539 nsCommonWidget::Enable(PRBool aState)
00540 {
00541     if (mWidget)
00542         mWidget->setEnabled(aState);
00543 
00544     return NS_OK;
00545 }
00546 
00547 NS_IMETHODIMP
00548 nsCommonWidget::IsEnabled(PRBool *aState)
00549 {
00550     if (mWidget)
00551         *aState = mWidget->isEnabled();
00552 
00553     return NS_OK;
00554 }
00555 
00556 NS_IMETHODIMP
00557 nsCommonWidget::SetFocus(PRBool aRaise)
00558 {
00559 #ifdef DEBUG_WIDGETS
00560     qDebug("SetFocus mWidget=%p, mContainer=%p, focuswidget=%p (%d)",
00561            (void*)mWidget, (void*)mContainer, (void*)mWidget->focusWidget());
00562 #endif
00563     if (mWidget) {
00564         if (aRaise)
00565             mWidget->raise();
00566         mWidget->setFocus();
00567 
00568         DispatchGotFocusEvent();
00569     }
00570 
00571     return NS_OK;
00572 }
00573 
00574 nsIFontMetrics*
00575 nsCommonWidget::GetFont()
00576 {
00577 #ifdef DEBUG_WIDGETS
00578     qWarning("nsCommonWidget.cpp: GetFont not implemented");
00579 #endif
00580     return nsnull;
00581 }
00582 
00583 NS_IMETHODIMP
00584 nsCommonWidget::SetFont(const nsFont&)
00585 {
00586     return NS_OK;
00587 }
00588 
00589 NS_IMETHODIMP
00590 nsCommonWidget::Invalidate(PRBool aIsSynchronous)
00591 {
00592 #ifdef DEBUG_WIDGETS
00593     qDebug("nsCommonWidget::Invalidate1 container=%p widget=%p", (void*)mContainer, (void*)mWidget);
00594 #endif
00595     if (!mWidget)
00596         return NS_OK;
00597 
00598     if (aIsSynchronous)
00599         mWidget->repaint();
00600     else
00601         mWidget->update();
00602 
00603     return NS_OK;
00604 }
00605 
00606 NS_IMETHODIMP
00607 nsCommonWidget::Invalidate(const nsRect & aRect, PRBool aIsSynchronous)
00608 {
00609 #ifdef DEBUG_WIDGETS
00610     qDebug("nsCommonWidget::Invalidate2 container=%p widget=%p", (void*)mContainer, (void*)mWidget);
00611 #endif
00612     if (!mWidget)
00613         return NS_OK;
00614 
00615     if (aIsSynchronous)
00616         mWidget->repaint(aRect.x, aRect.y, aRect.width, aRect.height);
00617     else
00618         mWidget->update(aRect.x, aRect.y, aRect.width, aRect.height);
00619 
00620     return NS_OK;
00621 }
00622 
00623 NS_IMETHODIMP
00624 nsCommonWidget::Update()
00625 {
00626 #ifdef DEBUG_WIDGETS
00627     qDebug("nsCommonWidget::Update container=%p widget=%p", (void*)mContainer, (void*)mWidget);
00628 #endif
00629     if (!mWidget)
00630         return NS_OK;
00631     mWidget->update();
00632 
00633     return NS_OK;
00634 }
00635 
00636 NS_IMETHODIMP
00637 nsCommonWidget::SetColorMap(nsColorMap*)
00638 {
00639     return NS_OK;
00640 }
00641 
00642 NS_IMETHODIMP
00643 nsCommonWidget::Scroll(int aDx, int aDy, nsRect *aClipRect)
00644 {
00645     if (mWidget)
00646         mWidget->scroll(aDx, aDy);
00647 
00648     // Update bounds on our child windows
00649     for (nsIWidget* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
00650         nsRect bounds;
00651         kid->GetBounds(bounds);
00652         bounds.x += aDx;
00653         bounds.y += aDy;
00654         NS_STATIC_CAST(nsBaseWidget*, kid)->SetBounds(bounds);
00655     }
00656     return NS_OK;
00657 }
00658 
00659 NS_IMETHODIMP
00660 nsCommonWidget::ScrollWidgets(PRInt32 aDx,
00661                               PRInt32 aDy)
00662 {
00663     if (mWidget)
00664         mWidget->scroll(aDx, aDy);
00665 
00666     return NS_OK;
00667 }
00668 
00669 void*
00670 nsCommonWidget::GetNativeData(PRUint32 aDataType)
00671 {
00672     switch(aDataType) {
00673     case NS_NATIVE_WINDOW:
00674         return mWidget;
00675         break;
00676 
00677     case NS_NATIVE_DISPLAY:
00678         if (mWidget)
00679             return mWidget->x11Display();
00680         break;
00681 
00682     case NS_NATIVE_WIDGET:
00683         return mWidget;
00684         break;
00685 
00686     case NS_NATIVE_PLUGIN_PORT:
00687         if (mWidget)
00688             return (void*)mWidget->winId();
00689         break;
00690 
00691     default:
00692         break;
00693     }
00694 
00695     return nsnull;
00696 }
00697 
00698 NS_IMETHODIMP
00699 nsCommonWidget::SetTitle(const nsAString &str)
00700 {
00701     nsAString::const_iterator it;
00702     QString qStr = QString::fromUcs2(str.BeginReading(it).get());
00703 
00704     if (mContainer)
00705         mContainer->setCaption(qStr);
00706 
00707     return NS_OK;
00708 }
00709 
00710 NS_IMETHODIMP
00711 nsCommonWidget::SetMenuBar(nsIMenuBar*)
00712 {
00713     qWarning("XXXXX SetMenuBar");
00714     return NS_ERROR_NOT_IMPLEMENTED;
00715 }
00716 
00717 NS_IMETHODIMP
00718 nsCommonWidget::ShowMenuBar(int)
00719 {
00720 
00721     qWarning("XXXXX ShowMenuBar");
00722     return NS_ERROR_NOT_IMPLEMENTED;
00723 }
00724 
00725 NS_IMETHODIMP
00726 nsCommonWidget::WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect)
00727 {
00728     aNewRect.width = aOldRect.width;
00729     aNewRect.height = aOldRect.height;
00730 
00731     if (mWidget) {
00732         PRInt32 x,y;
00733 
00734         QPoint offset(0,0);
00735         offset = mWidget->mapToGlobal(offset);
00736         x = offset.x();
00737         y = offset.y();
00738 
00739         aNewRect.x = aOldRect.x + x;
00740         aNewRect.y = aOldRect.y + y;
00741     }
00742 
00743     return NS_OK;
00744 }
00745 
00746 NS_IMETHODIMP
00747 nsCommonWidget::ScreenToWidget(const nsRect &aOldRect, nsRect &aNewRect)
00748 {
00749     if (mWidget) {
00750         PRInt32 X,Y;
00751 
00752         QPoint offset(0,0);
00753         offset = mWidget->mapFromGlobal(offset);
00754         X = offset.x();
00755         Y = offset.y();
00756 
00757         aNewRect.x = aOldRect.x + X;
00758         aNewRect.y = aOldRect.y + Y;
00759     }
00760     return NS_OK;
00761 }
00762 
00763 NS_IMETHODIMP
00764 nsCommonWidget::BeginResizingChildren()
00765 {
00766     qWarning("XXXXXX BeginResizingChildren");
00767     return  NS_ERROR_NOT_IMPLEMENTED;
00768 }
00769 
00770 NS_IMETHODIMP
00771 nsCommonWidget::EndResizingChildren()
00772 {
00773     qWarning("XXXXXXX EndResizingChildren");
00774     return NS_ERROR_NOT_IMPLEMENTED;
00775 }
00776 
00777 NS_IMETHODIMP
00778 nsCommonWidget::GetPreferredSize(PRInt32 &aWidth, PRInt32 &aHeight)
00779 {
00780     if (!mWidget)
00781         return NS_ERROR_FAILURE;
00782 
00783     QSize sh = mWidget->sizeHint();
00784     aWidth = QMAX(0, sh.width());
00785     aHeight = QMAX(0, sh.height());
00786     return NS_OK;
00787 }
00788 
00789 NS_IMETHODIMP
00790 nsCommonWidget::SetPreferredSize(int w, int h)
00791 {
00792     qWarning("XXX SetPreferredSize %d %d", w, h);
00793     return NS_ERROR_NOT_IMPLEMENTED;
00794 }
00795 
00796 NS_IMETHODIMP
00797 nsCommonWidget::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus)
00798 {
00799     aStatus = nsEventStatus_eIgnore;
00800 
00801     // hold a widget reference while we dispatch this event
00802     NS_ADDREF(aEvent->widget);
00803 
00804     if (mEventCallback)
00805         aStatus = (*mEventCallback)(aEvent);
00806 
00807     // dispatch to event listener if event was not consumed
00808     if ((aStatus != nsEventStatus_eIgnore) && mEventListener)
00809         aStatus = mEventListener->ProcessEvent(*aEvent);
00810 
00811     NS_IF_RELEASE(aEvent->widget);
00812 
00813     return NS_OK;
00814 }
00815 
00816 NS_IMETHODIMP
00817 nsCommonWidget::CaptureRollupEvents(nsIRollupListener*, PRBool, PRBool)
00818 {
00819     return NS_OK;
00820 }
00821 
00822 void
00823 nsCommonWidget::DispatchGotFocusEvent(void)
00824 {
00825     nsGUIEvent event(PR_TRUE, NS_GOTFOCUS, this);
00826     nsEventStatus status;
00827     DispatchEvent(&event, status);
00828 }
00829 
00830 void
00831 nsCommonWidget::DispatchLostFocusEvent(void)
00832 {
00833     nsGUIEvent event(PR_TRUE, NS_LOSTFOCUS, this);
00834     nsEventStatus status;
00835     DispatchEvent(&event, status);
00836 }
00837 
00838 void
00839 nsCommonWidget::DispatchActivateEvent(void)
00840 {
00841     nsGUIEvent event(PR_TRUE, NS_ACTIVATE, this);
00842     nsEventStatus status;
00843     DispatchEvent(&event, status);
00844 }
00845 
00846 void
00847 nsCommonWidget::DispatchDeactivateEvent(void)
00848 {
00849     nsGUIEvent event(PR_TRUE, NS_DEACTIVATE, this);
00850     nsEventStatus status;
00851     DispatchEvent(&event, status);
00852 }
00853 
00854 void
00855 nsCommonWidget::DispatchResizeEvent(nsRect &aRect, nsEventStatus &aStatus)
00856 {
00857     nsSizeEvent event(PR_TRUE, NS_SIZE, this);
00858 
00859     event.windowSize = &aRect;
00860     event.point.x = aRect.x;
00861     event.point.y = aRect.y;
00862     event.mWinWidth = aRect.width;
00863     event.mWinHeight = aRect.height;
00864 
00865     DispatchEvent(&event, aStatus);
00866 }
00867 
00868 bool
00869 nsCommonWidget::mousePressEvent(QMouseEvent *e)
00870 {
00871     //qDebug("mousePressEvent mWidget=%p", (void*)mWidget);
00872 //     backTrace();
00873     PRUint32      eventType;
00874 
00875     switch (e->button()) {
00876     case Qt::MidButton:
00877         eventType = NS_MOUSE_MIDDLE_BUTTON_DOWN;
00878         break;
00879     case Qt::RightButton:
00880         eventType = NS_MOUSE_RIGHT_BUTTON_DOWN;
00881         break;
00882     default:
00883         eventType = NS_MOUSE_LEFT_BUTTON_DOWN;
00884         break;
00885     }
00886 
00887     nsMouseEvent event(PR_TRUE, eventType, this, nsMouseEvent::eReal);
00888 
00889     InitMouseEvent(&event, e, 1);
00890 
00891     nsEventStatus status;
00892     DispatchEvent(&event, status);
00893 
00894     // right menu click on linux should also pop up a context menu
00895     if (eventType == NS_MOUSE_RIGHT_BUTTON_DOWN) {
00896         nsMouseEvent contextMenuEvent(PR_TRUE, NS_CONTEXTMENU, this,
00897                                       nsMouseEvent::eReal);
00898         InitMouseEvent(&contextMenuEvent, e, 1);
00899         DispatchEvent(&contextMenuEvent, status);
00900     }
00901 
00902     return ignoreEvent(status);
00903 }
00904 
00905 bool
00906 nsCommonWidget::mouseReleaseEvent(QMouseEvent *e)
00907 {
00908     //qDebug("mouseReleaseEvent mWidget=%p", (void*)mWidget);
00909     PRUint32      eventType;
00910 
00911     switch (e->button()) {
00912     case Qt::MidButton:
00913         eventType = NS_MOUSE_MIDDLE_BUTTON_UP;
00914         break;
00915     case Qt::RightButton:
00916         eventType = NS_MOUSE_RIGHT_BUTTON_UP;
00917         break;
00918     default:
00919         eventType = NS_MOUSE_LEFT_BUTTON_UP;
00920         break;
00921     }
00922 
00923     nsMouseEvent event(PR_TRUE, eventType, this, nsMouseEvent::eReal);
00924 
00925     InitMouseEvent(&event, e, 1);
00926 
00927     //not pressed
00928     nsEventStatus status;
00929     DispatchEvent(&event, status);
00930     return ignoreEvent(status);
00931 }
00932 
00933 bool
00934 nsCommonWidget::mouseDoubleClickEvent(QMouseEvent *e)
00935 {
00936     PRUint32      eventType;
00937 
00938     switch (e->button()) {
00939     case Qt::MidButton:
00940         eventType = NS_MOUSE_MIDDLE_BUTTON_DOWN;
00941         break;
00942     case Qt::RightButton:
00943         eventType = NS_MOUSE_RIGHT_BUTTON_DOWN;
00944         break;
00945     default:
00946         eventType = NS_MOUSE_LEFT_BUTTON_DOWN;
00947         break;
00948     }
00949 
00950     nsMouseEvent event(PR_TRUE, eventType, this, nsMouseEvent::eReal);
00951 
00952     InitMouseEvent(&event, e, 2);
00953     //pressed
00954     nsEventStatus status;
00955     DispatchEvent(&event, status);
00956     return ignoreEvent(status);
00957 }
00958 
00959 bool
00960 nsCommonWidget::mouseMoveEvent(QMouseEvent *e)
00961 {
00962     nsMouseEvent event(PR_TRUE, NS_MOUSE_MOVE, this, nsMouseEvent::eReal);
00963 
00964     InitMouseEvent(&event, e, 0);
00965     nsEventStatus status;
00966     DispatchEvent(&event, status);
00967     return ignoreEvent(status);
00968 }
00969 
00970 bool
00971 nsCommonWidget::wheelEvent(QWheelEvent *e)
00972 {
00973     nsMouseScrollEvent nsEvent(PR_TRUE, NS_MOUSE_SCROLL, this);
00974 
00975     InitMouseWheelEvent(&nsEvent, e);
00976 
00977     nsEventStatus status;
00978     DispatchEvent(&nsEvent, status);
00979     return ignoreEvent(status);
00980 }
00981 
00982 bool
00983 nsCommonWidget::keyPressEvent(QKeyEvent *e)
00984 {
00985     //qDebug("keyPressEvent");
00986 
00987     nsEventStatus status;
00988 
00989     // If the key repeat flag isn't set then set it so we don't send
00990     // another key down event on the next key press -- DOM events are
00991     // key down, key press and key up.  X only has key press and key
00992     // release.  gtk2 already filters the extra key release events for
00993     // us.
00994 
00995     nsKeyEvent pressEvent(PR_TRUE, NS_KEY_PRESS, this);
00996     InitKeyEvent(&pressEvent, e);
00997     pressEvent.charCode = (PRInt32)e->text()[0].unicode();
00998 
00999     if (!e->isAutoRepeat()) {
01000 
01001         // send the key down event
01002         nsKeyEvent downEvent(PR_TRUE, NS_KEY_DOWN, this);
01003         InitKeyEvent(&downEvent, e);
01004         DispatchEvent(&downEvent, status);
01005         if (ignoreEvent(status)) { // If prevent default on keydown, do same for keypress
01006           pressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
01007         }
01008     }
01009 
01010     // before we dispatch a key, check if it's the context menu key.
01011     // If so, send a context menu key event instead.
01012     if (isContextMenuKey(pressEvent)) {
01013         nsMouseEvent contextMenuEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);
01014         keyEventToContextMenuEvent(&pressEvent, &contextMenuEvent);
01015         DispatchEvent(&contextMenuEvent, status);
01016     }
01017     else {
01018         // send the key press event
01019         DispatchEvent(&pressEvent, status);
01020     }
01021 
01022     return ignoreEvent(status);
01023 }
01024 
01025 bool
01026 nsCommonWidget::keyReleaseEvent(QKeyEvent *e)
01027 {
01028     nsKeyEvent event(PR_TRUE, NS_KEY_UP, this);
01029 
01030     InitKeyEvent(&event, e);
01031 
01032     nsEventStatus status;
01033     DispatchEvent(&event, status);
01034     return ignoreEvent(status);
01035 }
01036 
01037 bool
01038 nsCommonWidget::focusInEvent(QFocusEvent *)
01039 {
01040     if (!mWidget)
01041         return FALSE;
01042 
01043 #ifdef DEBUG_WIDGETS
01044     qDebug("focusInEvent mWidget=%p, mContainer=%p", (void*)mWidget, (void*)mContainer);
01045 #endif
01046 
01047     DispatchGotFocusEvent();
01048 
01049     DispatchActivateEvent();
01050 
01051     return FALSE;
01052 }
01053 
01054 bool
01055 nsCommonWidget::focusOutEvent(QFocusEvent *)
01056 {
01057 #ifdef DEBUG_WIDGETS
01058     qDebug("focusOutEvent mWidget=%p,mContainer = %p", (void*)mWidget, (void*)mContainer);
01059 #endif
01060 
01061     DispatchLostFocusEvent();
01062     if (mContainer)
01063         DispatchDeactivateEvent();
01064 
01065     return FALSE;
01066 }
01067 
01068 bool
01069 nsCommonWidget::enterEvent(QEvent *)
01070 {
01071     nsMouseEvent event(PR_TRUE, NS_MOUSE_ENTER, this, nsMouseEvent::eReal);
01072 
01073     QPoint pt = QCursor::pos();
01074 
01075     event.point.x = nscoord(pt.x());
01076     event.point.y = nscoord(pt.y());
01077 
01078     nsEventStatus status;
01079     DispatchEvent(&event, status);
01080     return FALSE;
01081 }
01082 
01083 bool
01084 nsCommonWidget::leaveEvent(QEvent *aEvent)
01085 {
01086     nsMouseEvent event(PR_TRUE, NS_MOUSE_EXIT, this, nsMouseEvent::eReal);
01087 
01088     QPoint pt = QCursor::pos();
01089 
01090     event.point.x = nscoord(pt.x());
01091     event.point.y = nscoord(pt.y());
01092 
01093     nsEventStatus status;
01094     DispatchEvent(&event, status);
01095     return FALSE;
01096 }
01097 
01098 bool
01099 nsCommonWidget::paintEvent(QPaintEvent *e)
01100 {
01101     //qDebug("paintEvent: mWidget=%p x = %d, y = %d, width =  %d, height = %d", (void*)mWidget,
01102     //e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
01103 //     qDebug("paintEvent: Widgetrect %d %d %d %d", mWidget->x(), mWidget->y(),
01104 //            mWidget->width(), mWidget->height());
01105 
01106     QRect r = e->rect();
01107     if (!r.isValid())
01108         r = mWidget->rect();
01109     nsRect rect(r.x(), r.y(), r.width(), r.height());
01110 
01111     nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
01112 
01113     // Generate XPFE paint event
01114     nsPaintEvent event(PR_TRUE, NS_PAINT, this);
01115     event.point.x = 0;
01116     event.point.y = 0;
01117     event.rect = &rect;
01118     // XXX fix this!
01119     event.region = nsnull;
01120     // XXX fix this!
01121     event.renderingContext = rc;
01122 
01123     nsEventStatus status;
01124     DispatchEvent(&event, status);
01125     return ignoreEvent(status);
01126 }
01127 
01128 bool
01129 nsCommonWidget::moveEvent(QMoveEvent *e)
01130 {
01131     // can we shortcut?
01132     if (!mWidget || (mBounds.x == e->pos().x() &&
01133                      mBounds.y == e->pos().y()))
01134         return FALSE;
01135 
01136 #ifdef DEBUG_WIDGETS
01137     bool shown = mWidget ? mWidget->isShown() : false;
01138     bool popup = mWidget ? mWidget->isPopup() : false;
01139 
01140     qDebug("moveEvent mWidget=%p %d %d (%s, %s)", (void*)mWidget, e->pos().x(), e->pos().y(),
01141            shown? "shown": "hidden", popup ? "popup": "widget");
01142 #endif
01143 
01144     // Toplevel windows need to have their bounds set so that we can
01145     // keep track of our location.  It's not often that the x,y is set
01146     // by the layout engine.  Width and height are set elsewhere.
01147     QPoint pos = e->pos();
01148 
01149     if (mContainer) {
01150         // Need to translate this into the right coordinates
01151         nsRect oldrect, newrect;
01152         WidgetToScreen(oldrect, newrect);
01153         mBounds.x = newrect.x;
01154         mBounds.y = newrect.y;
01155 #ifdef DEBUG_WIDGETS
01156         qDebug("BOUNDS are [%d, %d]", mBounds.x, mBounds.y);
01157 #endif
01158     }
01159 
01160     nsGUIEvent event(PR_TRUE, NS_MOVE, this);
01161     event.point.x = pos.x();
01162     event.point.y = pos.y();
01163 
01164     // XXX mozilla will invalidate the entire window after this move
01165     // complete.  wtf?
01166     nsEventStatus status;
01167     DispatchEvent(&event, status);
01168     return ignoreEvent(status);
01169 }
01170 
01171 bool
01172 nsCommonWidget::resizeEvent(QResizeEvent *e)
01173 {
01174     nsRect rect;
01175 
01176     // Generate XPFE resize event
01177     GetBounds(rect);
01178     rect.width = e->size().width();
01179     rect.height = e->size().height();
01180 
01181     mBounds.width = rect.width;
01182     mBounds.height = rect.height;
01183 
01184 #ifdef DEBUG_WIDGETS
01185     qDebug("resizeEvent: mWidget=%p, aWidth=%d, aHeight=%d, aX = %d, aY = %d", (void*)mWidget,
01186            rect.width, rect.height, rect.x, rect.y);
01187 #endif
01188 
01189     nsEventStatus status;
01190     DispatchResizeEvent(rect, status);
01191     return ignoreEvent(status);
01192 }
01193 
01194 bool
01195 nsCommonWidget::closeEvent(QCloseEvent *)
01196 {
01197     nsGUIEvent event(PR_TRUE, NS_XUL_CLOSE, this);
01198 
01199     event.point.x = 0;
01200     event.point.y = 0;
01201 
01202     nsEventStatus status;
01203     DispatchEvent(&event, status);
01204 
01205     return ignoreEvent(status);
01206 }
01207 
01208 bool
01209 nsCommonWidget::contextMenuEvent(QContextMenuEvent *)
01210 {
01211     //qDebug("context menu");
01212     return false;
01213 }
01214 
01215 bool
01216 nsCommonWidget::imStartEvent(QIMEvent *)
01217 {
01218     qWarning("XXX imStartEvent");
01219     return false;
01220 }
01221 
01222 bool
01223 nsCommonWidget::imComposeEvent(QIMEvent *)
01224 {
01225     qWarning("XXX imComposeEvent");
01226     return false;
01227 }
01228 
01229 bool
01230 nsCommonWidget::imEndEvent(QIMEvent * )
01231 {
01232     qWarning("XXX imComposeEvent");
01233     return false;
01234 }
01235 
01236 bool
01237 nsCommonWidget::dragEnterEvent(QDragEnterEvent *)
01238 {
01239     qDebug("XXX dragEnterEvent");
01240     return false;
01241 }
01242 
01243 bool
01244 nsCommonWidget::dragMoveEvent(QDragMoveEvent *)
01245 {
01246     qDebug("XXX dragMoveEvent");
01247     return false;
01248 }
01249 
01250 bool
01251 nsCommonWidget::dragLeaveEvent(QDragLeaveEvent *)
01252 {
01253     qDebug("XXX dragLeaveEvent");
01254     return false;
01255 }
01256 
01257 bool
01258 nsCommonWidget::dropEvent(QDropEvent *)
01259 {
01260     qDebug("XXX dropEvent");
01261     return false;
01262 }
01263 
01264 bool
01265 nsCommonWidget::showEvent(QShowEvent *)
01266 {
01267 #ifdef DEBUG_WIDGETS
01268     qDebug("showEvent mWidget=%p", (void*)mWidget);
01269 #endif
01270 
01271     QRect r = mWidget->rect();
01272     nsRect rect(r.x(), r.y(), r.width(), r.height());
01273 
01274     nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
01275        // Generate XPFE paint event
01276     nsPaintEvent event(PR_TRUE, NS_PAINT, this);
01277     event.point.x = 0;
01278     event.point.y = 0;
01279     event.rect = &rect;
01280     // XXX fix this!
01281     event.region = nsnull;
01282     // XXX fix this!
01283     event.renderingContext = rc;
01284 
01285     nsEventStatus status;
01286     DispatchEvent(&event, status);
01287 
01288     return false;
01289 }
01290 
01291 bool
01292 nsCommonWidget::hideEvent(QHideEvent *)
01293 {
01294 #ifdef DEBUG_WIDGETS
01295     qDebug("hideEvent mWidget=%p", (void*)mWidget);
01296 #endif
01297     return false;
01298 }
01299 
01300 void
01301 nsCommonWidget::InitKeyEvent(nsKeyEvent *nsEvent, QKeyEvent *qEvent)
01302 {
01303     nsEvent->isShift   = qEvent->state() & Qt::ShiftButton;
01304     nsEvent->isControl = qEvent->state() & Qt::ControlButton;
01305     nsEvent->isAlt     = qEvent->state() & Qt::AltButton;
01306     nsEvent->isMeta    = qEvent->state() & Qt::MetaButton;
01307     nsEvent->time      = 0;
01308 
01309     if (qEvent->text().length() && qEvent->text()[0].isPrint()) {
01310         nsEvent->charCode = (PRInt32)qEvent->text()[0].unicode();
01311     }
01312     else {
01313         nsEvent->charCode = 0;
01314     }
01315 
01316     if (nsEvent->charCode) {
01317         nsEvent->keyCode = 0;
01318     }
01319     else {
01320         nsEvent->keyCode = NS_GetKey(qEvent->key());
01321     }
01322 }
01323 
01324 void
01325 nsCommonWidget::InitMouseEvent(nsMouseEvent *nsEvent, QMouseEvent *qEvent, int aClickCount)
01326 {
01327     nsEvent->point.x = nscoord(qEvent->x());
01328     nsEvent->point.y = nscoord(qEvent->y());
01329 
01330     nsEvent->isShift         = qEvent->state() & Qt::ShiftButton;
01331     nsEvent->isControl       = qEvent->state() & Qt::ControlButton;
01332     nsEvent->isAlt           = qEvent->state() & Qt::AltButton;
01333     nsEvent->isMeta          = qEvent->state() & Qt::MetaButton;
01334     nsEvent->clickCount      = aClickCount;
01335 }
01336 
01337 void
01338 nsCommonWidget::InitMouseWheelEvent(nsMouseScrollEvent *aEvent,
01339                                     QWheelEvent *qEvent)
01340 {
01341     switch (qEvent->orientation()) {
01342     case Qt::Vertical:
01343         aEvent->scrollFlags = nsMouseScrollEvent::kIsVertical;
01344         break;
01345     case Qt::Horizontal:
01346         aEvent->scrollFlags = nsMouseScrollEvent::kIsHorizontal;
01347         break;
01348     default:
01349         Q_ASSERT(0);
01350         break;
01351     }
01352     aEvent->delta = (int)((qEvent->delta() / WHEEL_DELTA) * -3);
01353 
01354     aEvent->point.x = nscoord(qEvent->x());
01355     aEvent->point.y = nscoord(qEvent->y());
01356 
01357     aEvent->isShift         = qEvent->state() & Qt::ShiftButton;
01358     aEvent->isControl       = qEvent->state() & Qt::ControlButton;
01359     aEvent->isAlt           = qEvent->state() & Qt::AltButton;
01360     aEvent->isMeta          = qEvent->state() & Qt::MetaButton;
01361     aEvent->time            = 0;
01362 }
01363 
01364 void
01365 nsCommonWidget::CommonCreate(nsIWidget *aParent, PRBool aListenForResizes)
01366 {
01367     mParent = aParent;
01368     mListenForResizes = aListenForResizes;
01369 }
01370 
01371 PRBool
01372 nsCommonWidget::AreBoundsSane() const
01373 {
01374     if (mBounds.width > 0 && mBounds.height > 0)
01375         return PR_TRUE;
01376 
01377     return PR_FALSE;
01378 }
01379 
01380 NS_IMETHODIMP
01381 nsCommonWidget::Create(nsIWidget *aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction,
01382                        nsIDeviceContext *aContext, nsIAppShell *aAppShell, nsIToolkit *aToolkit,
01383                        nsWidgetInitData *aInitData)
01384 {
01385     return NativeCreate(aParent, nsnull, aRect, aHandleEventFunction, aContext, aAppShell,
01386                         aToolkit, aInitData);
01387 }
01388 
01389 NS_IMETHODIMP
01390 nsCommonWidget::Create(nsNativeWidget aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction,
01391                        nsIDeviceContext *aContext, nsIAppShell *aAppShell, nsIToolkit *aToolkit,
01392                        nsWidgetInitData *aInitData)
01393 {
01394     return NativeCreate(nsnull, (QWidget*)aParent, aRect, aHandleEventFunction, aContext, aAppShell,
01395                         aToolkit, aInitData);
01396 }
01397 
01398 nsresult
01399 nsCommonWidget::NativeCreate(nsIWidget        *aParent,
01400                              QWidget          *aNativeParent,
01401                              const nsRect     &aRect,
01402                              EVENT_CALLBACK    aHandleEventFunction,
01403                              nsIDeviceContext *aContext,
01404                              nsIAppShell      *aAppShell,
01405                              nsIToolkit       *aToolkit,
01406                              nsWidgetInitData *aInitData)
01407 {
01408     // only set the base parent if we're going to be a dialog or a
01409     // toplevel
01410     nsIWidget *baseParent = aInitData &&
01411                             (aInitData->mWindowType == eWindowType_dialog ||
01412                              aInitData->mWindowType == eWindowType_toplevel ||
01413                              aInitData->mWindowType == eWindowType_invisible) ?
01414                             nsnull : aParent;
01415 
01416     // initialize all the common bits of this class
01417     BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
01418                aAppShell, aToolkit, aInitData);
01419 
01420     // Do we need to listen for resizes?
01421     PRBool listenForResizes = PR_FALSE;;
01422     if (aNativeParent || (aInitData && aInitData->mListenForResizes))
01423         listenForResizes = PR_TRUE;
01424 
01425     // and do our common creation
01426     CommonCreate(aParent, listenForResizes);
01427 
01428     // save our bounds
01429     mBounds = aRect;
01430 
01431     QWidget *parent = 0;
01432     if (aParent != nsnull)
01433         parent = (QWidget*)aParent->GetNativeData(NS_NATIVE_WIDGET);
01434     else
01435         parent = aNativeParent;
01436 
01437     mWidget = createQWidget(parent, aInitData);
01438 
01439     Initialize(mWidget);
01440 
01441     Resize(mBounds.width, mBounds.height, PR_FALSE);
01442 
01443     return NS_OK;
01444 }
01445 
01446 nsCursor nsCommonWidget::GetCursor()
01447 {
01448     return mCursor;
01449 }
01450 
01451 NS_METHOD nsCommonWidget::SetCursor(nsCursor aCursor)
01452 {
01453     mCursor = aCursor;
01454     Qt::CursorShape cursor = Qt::ArrowCursor;
01455     switch(mCursor) {
01456     case eCursor_standard:
01457        cursor = Qt::ArrowCursor;
01458         break;
01459     case eCursor_wait:
01460         cursor = Qt::WaitCursor;
01461         break;
01462     case eCursor_select:
01463         cursor = Qt::IbeamCursor;
01464         break;
01465     case eCursor_hyperlink:
01466         cursor = Qt::PointingHandCursor;
01467         break;
01468     case eCursor_ew_resize:
01469         cursor = Qt::SplitHCursor;
01470         break;
01471     case eCursor_ns_resize:
01472         cursor = Qt::SplitVCursor;
01473         break;
01474     case eCursor_nw_resize:
01475     case eCursor_se_resize:
01476        cursor = Qt::SizeBDiagCursor;
01477         break;
01478     case eCursor_ne_resize:
01479     case eCursor_sw_resize:
01480        cursor = Qt::SizeFDiagCursor;
01481         break;
01482     case eCursor_crosshair:
01483     case eCursor_move:
01484        cursor = Qt::SizeAllCursor;
01485         break;
01486     case eCursor_help:
01487        cursor = Qt::WhatsThisCursor;
01488         break;
01489     case eCursor_copy:
01490     case eCursor_alias:
01491         break;
01492     case eCursor_context_menu:
01493     case eCursor_cell:
01494     case eCursor_grab:
01495     case eCursor_grabbing:
01496     case eCursor_spinning:
01497     case eCursor_zoom_in:
01498     case eCursor_zoom_out:
01499 
01500     default:
01501         break;
01502     }
01503     mWidget->setCursor(cursor);
01504     return NS_OK;
01505 }
01506 
01507 bool nsCommonWidget::ignoreEvent(nsEventStatus aStatus) const
01508 {
01509       switch(aStatus) {
01510     case nsEventStatus_eIgnore:
01511         return(PR_FALSE);
01512 
01513     case nsEventStatus_eConsumeNoDefault:
01514         return(PR_TRUE);
01515 
01516     case nsEventStatus_eConsumeDoDefault:
01517         return(PR_FALSE);
01518 
01519     default:
01520         NS_ASSERTION(0,"Illegal nsEventStatus enumeration value");
01521         break;
01522     }
01523     return(PR_FALSE);
01524 }
01525 
01526 NS_METHOD nsCommonWidget::SetModal(PRBool aModal)
01527 {
01528 #ifdef DEBUG_WIDGETS
01529     qDebug("------------> SetModal mWidget=%p",(void*) mWidget);
01530 #endif
01531 
01532     MozQWidget *mozWidget = qt_cast<MozQWidget*>(mWidget);
01533     if (mozWidget)
01534         mozWidget->setModal(aModal);
01535 
01536     return NS_OK;
01537 }
01538 
01539 NS_IMETHODIMP nsCommonWidget::GetScreenBounds(nsRect &aRect)
01540 {
01541        nsRect origin(0,0,mBounds.width,mBounds.height);
01542        WidgetToScreen(origin, aRect);
01543        return NS_OK;
01544 }
01545 
01546 void
01547 nsCommonWidget::NativeShow(PRBool aState)
01548 {
01549     mNeedsShow = PR_FALSE;
01550 
01551     if (!mWidget) {
01552          //XXX: apperently can be null during the printing, check whether
01553          //     that's true
01554          qDebug("nsCommon::Show : widget empty");
01555          return;
01556     }
01557     mWidget->setShown(aState);
01558 }
01559 
01560 void
01561 nsCommonWidget::NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
01562 {
01563     mNeedsResize = PR_FALSE;
01564 
01565     mWidget->resize( aWidth, aHeight);
01566 
01567     if (aRepaint) {
01568         if (mWidget->isVisible())
01569             mWidget->repaint(false);
01570     }
01571 }
01572 
01573 void
01574 nsCommonWidget::NativeResize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight,
01575                              PRBool aRepaint)
01576 {
01577     mNeedsResize = PR_FALSE;
01578 
01579     QPoint pos(aX, aY);
01580     if (mContainer)
01581     {
01582         if (mParent && mWidget->isPopup()) {
01583             nsRect oldrect, newrect;
01584             oldrect.x = aX;
01585             oldrect.y = aY;
01586 
01587             mParent->WidgetToScreen(oldrect, newrect);
01588 
01589             pos = QPoint(newrect.x, newrect.y);
01590 #ifdef DEBUG_WIDGETS
01591             qDebug("pos is [%d,%d]", pos.x(), pos.y());
01592 #endif
01593         } else {
01594 #ifdef DEBUG_WIDGETS
01595             qDebug("Widget with original position? (%p)", mWidget);
01596 #endif
01597         }
01598     }
01599 
01600     mWidget->setGeometry(pos.x(), pos.y(), aWidth, aHeight);
01601 
01602     if (aRepaint) {
01603         if (mWidget->isVisible())
01604             mWidget->repaint(false);
01605     }
01606 }