Index: /trunk/src/VBox/Frontends/VirtualBox4/include/VBoxConsoleView.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox4/include/VBoxConsoleView.h	(revision 7589)
+++ /trunk/src/VBox/Frontends/VirtualBox4/include/VBoxConsoleView.h	(revision 7590)
@@ -26,5 +26,6 @@
 
 /* Qt includes */
-#include <q3scrollview.h>
+#include <QAbstractScrollArea>
+#include <QScrollBar>
 
 #if defined (Q_WS_PM)
@@ -46,5 +47,5 @@
 class QMenuData;
 
-class VBoxConsoleView : public Q3ScrollView
+class VBoxConsoleView : public QAbstractScrollArea
 {
     Q_OBJECT
@@ -64,5 +65,5 @@
                      const CConsole &console,
                      VBoxDefs::RenderMode rm,
-                     QWidget *parent = 0, const char *name = 0, Qt::WFlags f = 0);
+                     QWidget *parent = 0);
     ~VBoxConsoleView();
 
@@ -95,4 +96,24 @@
 
     QRect getDesktopGeometry();
+
+    /* todo: This are some support functions for the qt4 port. Maybe we get rid
+     * of them some day. */
+    int contentsX() const { return horizontalScrollBar()->value(); }
+    int contentsY() const { return verticalScrollBar()->value(); }
+    int contentsWidth() const;
+    int contentsHeight() const;
+    int visibleWidth() const { return horizontalScrollBar()->pageStep(); }
+    int visibleHeight() const { return verticalScrollBar()->pageStep(); }
+    void scrollBy (int dx, int dy) 
+    { 
+        horizontalScrollBar()->setValue (horizontalScrollBar()->value() + dx);
+        verticalScrollBar()->setValue (verticalScrollBar()->value() + dy);
+    }
+    QPoint viewportToContents ( const QPoint & vp ) const
+    {
+        return QPoint (vp.x() + contentsX(), 
+                       vp.y() + contentsY());
+    }
+    void updateSliders();
 
 signals:
@@ -141,5 +162,5 @@
     bool mouseEvent (int aType, const QPoint &aPos, const QPoint &aGlobalPos,
                      Qt::ButtonState aButton,
-                     Qt::ButtonState aState, Qt::ButtonState aStateAfter,
+                     Qt::MouseButtons aButtons, Qt::KeyboardModifiers aModifiers,
                      int aWheelDelta, Qt::Orientation aWheelDir);
 
@@ -162,5 +183,6 @@
     void doRefresh();
 
-    void viewportPaintEvent( QPaintEvent * );
+    void resizeEvent (QResizeEvent *);
+    void paintEvent (QPaintEvent *);
 #ifdef VBOX_GUI_USE_REFRESH_TIMER
     void timerEvent( QTimerEvent * );
@@ -170,5 +192,5 @@
     void captureMouse (bool aCapture, bool aEmitSignal = true);
 
-    bool processHotKey (const QKeySequence &key, QMenuData *data);
+    bool processHotKey (const QKeySequence &key, const QList<QAction*>& data);
     void updateModifiers (bool fNumLock, bool fCapsLock, bool fScrollLock);
 
@@ -235,5 +257,4 @@
     long muCapsLockAdaptionCnt;
 
-    QTimer *resize_hint_timer;
     QTimer *mToggleFSModeTimer;
 
Index: /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxConsoleView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxConsoleView.cpp	(revision 7589)
+++ /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxConsoleView.cpp	(revision 7590)
@@ -259,12 +259,10 @@
 {
 public:
-    ActivateMenuEvent (QMenuData *menuData, uint index) :
+    ActivateMenuEvent (QAction *aData) :
         QEvent ((QEvent::Type) VBoxDefs::ActivateMenuEventType),
-        md (menuData), i (index) {}
-    QMenuData *menuData() const { return md; }
-    uint index() const { return i; }
+        mAction (aData) {}
+    QAction *action() const { return mAction; }
 private:
-    QMenuData *md;
-    uint i;
+    QAction *mAction;
 };
 
@@ -574,4 +572,22 @@
 #endif
 
+class VBoxViewport: public QWidget
+{
+public:
+    VBoxViewport (QWidget *aParent)
+        : QWidget (aParent)
+    {
+        /* No need for background drawing */
+        setAttribute (Qt::WA_OpaquePaintEvent);
+    }
+    virtual QPaintEngine * paintEngine() const 
+    { 
+        if (testAttribute (Qt::WA_PaintOnScreen))
+            return NULL; 
+        else 
+            return QWidget::paintEngine();
+    } 
+};
+
 //
 // VBoxConsoleView class
@@ -587,6 +603,6 @@
                                   const CConsole &console,
                                   VBoxDefs::RenderMode rm,
-                                  QWidget *parent, const char *name, Qt::WFlags f)
-    : Q3ScrollView (parent, name, f | Qt::WStaticContents | Qt::WNoAutoErase)
+                                  QWidget *parent)
+    : QAbstractScrollArea (parent)
     , mMainWnd (mainWnd)
     , mConsole (console)
@@ -630,4 +646,7 @@
 #endif
 
+    VBoxViewport *pViewport = new VBoxViewport (this);
+    setViewport (pViewport);
+
     /* enable MouseMove events */
     viewport()->setMouseTracking (true);
@@ -652,8 +671,4 @@
     ::memset (mPressedKeys, 0, SIZEOF_ARRAY (mPressedKeys));
 
-    resize_hint_timer = new QTimer (this);
-    connect (resize_hint_timer, SIGNAL (timeout()),
-             this, SLOT (doResizeHint()));
-
     mToggleFSModeTimer = new QTimer (this);
     mToggleFSModeTimer->setSingleShot (true);
@@ -688,4 +703,7 @@
 #if defined (VBOX_GUI_USE_SDL)
         case VBoxDefs::SDLMode:
+            /* Indicate that we are doing all 
+             * drawing stuff ourself */
+            pViewport->setAttribute (Qt::WA_PaintOnScreen);
 # ifdef Q_WS_X11
             /* This is somehow necessary to prevent strange X11 warnings on
@@ -1058,5 +1076,5 @@
 
                 if (mToggleFSModeTimer->isActive())
-                    mToggleFSModeTimer->stop();
+                    mToggleFSModeTimer->stop(); 
 
                 /* do frame buffer dependent resize */
@@ -1080,5 +1098,6 @@
 
                 /* resize the guest canvas */
-                resizeContents (re->width(), re->height());
+                resize (re->width(), re->height());
+                updateSliders();
                 /* let our toplevel widget calculate its sizeHint properly */
                 QApplication::sendPostedEvents (0, QEvent::LayoutRequest);
@@ -1221,6 +1240,5 @@
             {
                 ActivateMenuEvent *ame = (ActivateMenuEvent *) e;
-#warning port me
-//                ame->menuData()->activateItemAt (ame->index());
+                ame->action()->trigger();
 
                 /*
@@ -1414,7 +1432,6 @@
                         /* process hot keys not processed in keyEvent()
                          * (as in case of non-alphanumeric keys) */
-#warning port me
-//                        processHotKey (QKeySequence (ke->key()),
-//                                       mMainWnd->menuBar());
+                        processHotKey (QKeySequence (ke->key()),
+                                       mMainWnd->menuBar()->actions());
                     }
                 }
@@ -1461,5 +1478,5 @@
     }
 
-    return Q3ScrollView::event (e);
+    return QAbstractScrollArea::event (e);
 }
 
@@ -1477,5 +1494,5 @@
                 QMouseEvent *me = (QMouseEvent *) e;
                 if (mouseEvent (me->type(), me->pos(), me->globalPos(),
-                                me->button(), me->state(), me->stateAfter(),
+                                me->button(), me->buttons(), me->modifiers(),
                                 0, Qt::Horizontal))
                     return true; /* stop further event handling */
@@ -1486,5 +1503,5 @@
                 QWheelEvent *we = (QWheelEvent *) e;
                 if (mouseEvent (we->type(), we->pos(), we->globalPos(),
-                                Qt::NoButton, we->state(), we->state(),
+                                Qt::NoButton, we->buttons(), we->modifiers(),
                                 we->delta(), we->orientation()))
                     return true; /* stop further event handling */
@@ -1555,5 +1572,5 @@
                 if (!mIgnoreMainwndResize &&
                     mIsAdditionsActive && mAutoresizeGuest)
-                    resize_hint_timer->start (300, TRUE);
+                    QTimer::singleShot (300, this, SLOT (doResizeHint()));
                 break;
             }
@@ -1582,5 +1599,5 @@
             {
                 QKeyEvent *ke = (QKeyEvent *) e;
-                if (ke->key() == Qt::Key_Escape && !(ke->state() & Qt::KeyboardModifierMask))
+                if (ke->key() == Qt::Key_Escape && (ke->modifiers() == Qt::NoModifier))
                     if (mMainWnd->menuBar()->hasFocus())
                         setFocus();
@@ -1592,5 +1609,5 @@
     }
 
-    return Q3ScrollView::eventFilter (watched, e);
+    return QAbstractScrollArea::eventFilter (watched, e);
 }
 
@@ -2503,5 +2520,5 @@
                 processed = processHotKey (QKeySequence (Qt::UNICODE_ACCEL +
                                                 QChar (ch).upper().unicode()),
-                                           mMainWnd->menuBar());
+                                           mMainWnd->menuBar()->actions());
         }
         delete[] list;
@@ -2521,16 +2538,14 @@
             {
                 QChar c = QString::fromLocal8Bit (&ch, 1) [0];
-#warning port me
-//                processed = processHotKey (QKeySequence (Qt::UNICODE_ACCEL +
-//                                                c.upper().unicode()),
-//                                           mMainWnd->menuBar());
+                processed = processHotKey (QKeySequence (Qt::UNICODE_ACCEL +
+                                                         c.toUpper().unicode()),
+                                           mMainWnd->menuBar()->actions());
             }
         }
 #elif defined (Q_WS_MAC)
-#warning port me
-//        if (aUniKey && aUniKey [0] && !aUniKey [1])
-//            processed = processHotKey (QKeySequence (Qt::UNICODE_ACCEL +
-//                                                     QChar (aUniKey [0]).upper().unicode()),
-//                                       mMainWnd->menuBar());
+        if (aUniKey && aUniKey [0] && !aUniKey [1])
+            processed = processHotKey (QKeySequence (Qt::UNICODE_ACCEL +
+                                                     QChar (aUniKey [0]).upper().unicode()),
+                                       mMainWnd->menuBar()->actions());
 
         /* Don't consider the hot key as pressed since the guest never saw
@@ -2585,5 +2600,5 @@
 bool VBoxConsoleView::mouseEvent (int aType, const QPoint &aPos,
                                   const QPoint &aGlobalPos, Qt::ButtonState aButton,
-                                  Qt::ButtonState aState, Qt::ButtonState aStateAfter,
+                                  Qt::MouseButtons aButtons, Qt::KeyboardModifiers aModifiers,
                                   int aWheelDelta, Qt::Orientation aWheelDir)
 {
@@ -2591,20 +2606,20 @@
     char buf [256];
     sprintf (buf,
-             "MOUSE: type=%03d x=%03d y=%03d btn=%03d st=%08X stAfter=%08X "
+             "MOUSE: type=%03d x=%03d y=%03d btn=%03d btns=%08X mod=%08X "
              "wdelta=%03d wdir=%03d",
-             aType, aPos.x(), aPos.y(), aButton, aState, aStateAfter,
+             aType, aPos.x(), aPos.y(), aButton, aButtons, aModifiers,
              aWheelDelta, aWheelDir);
     mMainWnd->statusBar()->message (buf);
 #else
     Q_UNUSED (aButton);
-    Q_UNUSED (aState);
+    Q_UNUSED (aModifiers);
 #endif
 
     int state = 0;
-    if (aStateAfter & Qt::LeftButton)
+    if (aButtons & Qt::LeftButton)
         state |= KMouseButtonState_LeftButton;
-    if (aStateAfter & Qt::RightButton)
+    if (aButtons & Qt::RightButton)
         state |= KMouseButtonState_RightButton;
-    if (aStateAfter & Qt::MidButton)
+    if (aButtons & Qt::MidButton)
         state |= KMouseButtonState_MiddleButton;
 
@@ -2784,5 +2799,5 @@
             if (hasFocus() &&
                 (aType == QEvent::MouseButtonRelease &&
-                 !aStateAfter))
+                 aButtons == Qt::NoButton))
             {
                 if (isPaused())
@@ -2844,5 +2859,5 @@
                     mPausedShot = QPixmap::fromImage (shot);
                     /* fully repaint to pick up mPausedShot */
-                    viewport()->repaint();
+                    repaint();
                 }
             }
@@ -2913,5 +2928,5 @@
             {
                 int pw = pm.width(), ph = pm.height();
-                resizeContents (pw, ph);
+                viewport()->resize (pw, ph);
                 updateGeometry();
                 setMaximumSize (sizeHint());
@@ -2925,5 +2940,5 @@
                  * on the next event loop iteration. currently disabled.
                  * updateContents(); */
-                repaintContents (false);
+                viewport()->repaint();
             }
         }
@@ -2933,28 +2948,33 @@
     else
 #endif
-        repaintContents (false);
-}
-
-void VBoxConsoleView::viewportPaintEvent (QPaintEvent *pe)
+        viewport()->repaint();
+}
+
+void VBoxConsoleView::resizeEvent (QResizeEvent *)
+{
+    updateSliders();
+}
+
+void VBoxConsoleView::paintEvent (QPaintEvent *pe)
 {
 #if defined (VBOX_GUI_USE_REFRESH_TIMER)
-    if (mode == VBoxDefs::TimerMode)
-    {
-        if (!pm.isNull())
-        {
-            /* draw a part of vbuf */
-            const QRect &r = pe->rect();
-#warning port me
+#warning "port me: Is this needed anymore?"
+//    if (mode == VBoxDefs::TimerMode)
+//    {
+//        if (!pm.isNull())
+//        {
+//            /* draw a part of vbuf */
+//            const QRect &r = pe->rect();
 //            ::bitBlt (viewport(), r.x(), r.y(),
 //                      &pm, r.x() + contentsX(), r.y() + contentsY(),
 //                      r.width(), r.height(),
 //                      CopyROP, TRUE);
-        }
-        else
-        {
-            viewport()->erase (pe->rect());
-        }
-    }
-    else
+//        }
+//        else
+//        {
+//            viewport()->erase (pe->rect());
+//        }
+//    }
+//    else
 #endif
     {
@@ -3118,50 +3138,31 @@
  *  is found, activates it and returns true. Otherwise returns false.
  */
-bool VBoxConsoleView::processHotKey (const QKeySequence &key,  QMenuData *data)
-{
-    if (!data) return false;
-
-    /*
-     *  Note: below, we use the internal class QMenuItem, that is subject
-     *  to change w/o notice... (the alternative would be to explicitly assign
-     *  specific IDs to all popup submenus in VBoxConsoleWnd and then
-     *  look through its children in order to find a popup with a given ID,
-     *  which is unconvenient).
-     */
-
-#warning port me
-//    for (uint i = 0; i < data->count(); i++)
-//    {
-//        int id = data->idAt (i);
-//        QMenuItem *item = data->findItem (id);
-//        if (item->popup())
-//        {
-//            if (processHotKey (key, item->popup()))
-//                return true;
-//        }
-//        else
-//        {
-//            QStringList list = QStringList::split ("\tHost+", data->text (id));
-//            if (list.count() == 2)
-//            {
-//                if (key.matches (QKeySequence (list[1])) == Identical)
-//                {
-//                    /*
-//                     *  we asynchronously post a special event instead of calling
-//                     *  data->activateItemAt (i) directly, to let key presses
-//                     *  and releases be processed correctly by Qt first.
-//                     *  Note: we assume that nobody will delete the menu item
-//                     *  corresponding to the key sequence, so that the pointer to
-//                     *  menu data posted along with the event will remain valid in
-//                     *  the event handler, at least until the main window is closed.
-//                     */
-//
-//                    QApplication::postEvent (this,
-//                                             new ActivateMenuEvent (data, i));
-//                    return true;
-//                }
-//            }
-//        }
-//    }
+bool VBoxConsoleView::processHotKey (const QKeySequence &key, const QList<QAction*>& data)
+{
+    foreach (QAction *pAction, data)
+    {
+        if (QMenu *menu = pAction->menu())
+            return processHotKey (key, menu->actions());
+
+        QStringList list = pAction->text().split ("\tHost+");
+        if (list.count() == 2)
+        {
+            if (key.matches (QKeySequence (list[1])) == QKeySequence::ExactMatch)
+            {
+                /*
+                 *  we asynchronously post a special event instead of calling
+                 *  pAction->trigger() directly, to let key presses and
+                 *  releases be processed correctly by Qt first. Note: we
+                 *  assume that nobody will delete the menu item corresponding
+                 *  to the key sequence, so that the pointer to menu data
+                 *  posted along with the event will remain valid in the event
+                 *  handler, at least until the main window is closed.
+                 */
+                QApplication::postEvent (this,
+                                         new ActivateMenuEvent (pAction));
+                return true;
+            }
+        }
+    }
 
     return false;
@@ -3676,2 +3677,29 @@
     }
 }
+
+int VBoxConsoleView::contentsWidth() const 
+{ 
+    return mFrameBuf->width(); 
+}
+
+int VBoxConsoleView::contentsHeight() const 
+{ 
+    return mFrameBuf->height(); 
+}
+
+void VBoxConsoleView::updateSliders()
+{
+    QSize p = viewport()->size();
+    QSize m = maximumViewportSize();
+
+    QSize v = QSize (mFrameBuf->width(), mFrameBuf->height());
+    /* no scroll bars needed */
+    if (m.expandedTo(v) == m)
+        p = m;
+
+    horizontalScrollBar()->setRange(0, v.width() - p.width());
+    verticalScrollBar()->setRange(0, v.height() - p.height());
+    horizontalScrollBar()->setPageStep(p.width());
+    verticalScrollBar()->setPageStep(p.height());
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxConsoleWnd.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxConsoleWnd.cpp	(revision 7589)
+++ /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxConsoleWnd.cpp	(revision 7590)
@@ -680,5 +680,5 @@
 
     console = new VBoxConsoleView (this, cconsole, mode,
-                                   centralWidget(), "console");
+                                   centralWidget());
 
     activateUICustomizations();
@@ -837,4 +837,6 @@
     /* set the correct initial machine_state value */
     machine_state = cconsole.GetState();
+
+    console->normalizeGeometry (true /* adjustPosition */);
 
     updateAppearanceOf (AllStuff);
@@ -2091,5 +2093,9 @@
         foreach (QWidget *w, list)
         {
-            if (w != centralWidget())
+            /* todo: The list is now recursive. So think about a better way to
+             * prevent the childrens of the centralWidget to be hidden */
+            if (w != centralWidget() &&
+                w != console &&
+                w != console->viewport())
             {
                 if (!w->isHidden())
@@ -2115,9 +2121,8 @@
         centralWidget()->setEraseColor (Qt::black);
         console_style = console->frameStyle();
-        console->setFrameStyle (Q3Frame::NoFrame);
+        console->setFrameStyle (QFrame::NoFrame);
         console->setMaximumSize (scrGeo.size());
-#warning port me
-/*        console->setVScrollBarMode (Q3ScrollView::AlwaysOff);*/
-/*        console->setHScrollBarMode (Q3ScrollView::AlwaysOff);*/
+        console->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
+        console->setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
 
         /* Going fullscreen */
@@ -2204,7 +2209,6 @@
         console->setFrameStyle (console_style);
         console->setMaximumSize (console->sizeHint());
-#warning port me
-/*        console->setVScrollBarMode (Q3ScrollView::Auto);*/
-/*        console->setHScrollBarMode (Q3ScrollView::Auto);*/
+        console->setHorizontalScrollBarPolicy (Qt::ScrollBarAsNeeded);
+        console->setVerticalScrollBarPolicy (Qt::ScrollBarAsNeeded);
 
         /* Show everything hidden when going fullscreen. */
Index: /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxProblemReporter.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxProblemReporter.cpp	(revision 7589)
+++ /trunk/src/VBox/Frontends/VirtualBox4/src/VBoxProblemReporter.cpp	(revision 7590)
@@ -1507,5 +1507,5 @@
             "operation. The currently assigned host key is shown on the status bar "
             "at the bottom of the Virtual Machine window, next to the&nbsp;"
-            "<img src=hostkey_16px.png/>&nbsp;icon. This icon, together "
+            "<img src=:/hostkey_16px.png/>&nbsp;icon. This icon, together "
             "with the mouse icon placed nearby, indicate the current keyboard "
             "and mouse capture state."
@@ -1540,5 +1540,5 @@
             "operation. The currently assigned host key is shown on the status bar "
             "at the bottom of the Virtual Machine window, next to the&nbsp;"
-            "<img src=hostkey_16px.png/>&nbsp;icon. This icon, together "
+            "<img src=:/hostkey_16px.png/>&nbsp;icon. This icon, together "
             "with the mouse icon placed nearby, indicate the current keyboard "
             "and mouse capture state."
@@ -1581,5 +1581,5 @@
                 "</p>"
                 "<p>The mouse icon on the status bar will look like&nbsp;"
-                "<img src=mouse_seamless_16px.png/>&nbsp;to inform you that mouse "
+                "<img src=:/mouse_seamless_16px.png/>&nbsp;to inform you that mouse "
                 "pointer integration is supported by the guest OS and is "
                 "currently turned on."
@@ -1700,5 +1700,5 @@
             "You can go back to windowed mode at any time by pressing "
             "<b>%1</b>. Note that the <i>Host</i> key is currently "
-            "defined as <b>%1</b>.</p>"
+            "defined as <b>%2</b>.</p>"
             "<p>Note that the main menu bar is hidden in fullscreen mode. You "
             "can access it by pressing <b>Host+Home</b>.</p>")
@@ -1722,5 +1722,5 @@
             "You can go back to windowed mode at any time by pressing "
             "<b>%1</b>. Note that the <i>Host</i> key is currently "
-            "defined as <b>%1</b>.</p>"
+            "defined as <b>%2</b>.</p>"
             "<p>Note that the main menu bar is hidden in seamless mode. You "
             "can access it by pressing <b>Host+Home</b>.</p>")
