summaryrefslogtreecommitdiffstats
path: root/src/gui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets')
-rw-r--r--src/gui/widgets/qabstractslider.cpp3
-rw-r--r--src/gui/widgets/qcombobox.cpp5
-rw-r--r--src/gui/widgets/qlineedit.cpp23
-rw-r--r--src/gui/widgets/qlineedit_p.h4
-rw-r--r--src/gui/widgets/qmenu.cpp27
-rw-r--r--src/gui/widgets/qmenu.h12
-rw-r--r--src/gui/widgets/qmenu_p.h43
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp392
-rw-r--r--src/gui/widgets/qmenubar.cpp38
-rw-r--r--src/gui/widgets/qmenubar.h4
-rw-r--r--src/gui/widgets/qmenubar_p.h44
-rw-r--r--src/gui/widgets/widgets.pri4
12 files changed, 591 insertions, 8 deletions
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index 8028fdc..abe592d 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -687,8 +687,9 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
Q_D(QAbstractSlider);
e->ignore();
if (e->orientation() != d->orientation && !rect().contains(e->pos()))
+ {
return;
-
+ }
static qreal offset = 0;
static QAbstractSlider *offset_owner = 0;
if (offset_owner != this){
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index a5a98d4..16e2f39 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -640,6 +640,7 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
case Qt::Key_Escape:
#ifdef QT_KEYPAD_NAVIGATION
case Qt::Key_Back:
+ case Qt::Key_Context2: // TODO: aportale, KEYPAD_NAVIGATION_HACK when softkey support is there
#endif
combo->hidePopup();
return true;
@@ -2431,6 +2432,10 @@ void QComboBox::showPopup()
container->setUpdatesEnabled(updatesEnabled);
container->update();
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled())
+ view()->setEditFocus(true);
+#endif
}
/*!
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index b76d019..0d8e16f 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -97,8 +97,7 @@ extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp
static inline bool shouldEnableInputMethod(QLineEdit *lineedit)
{
- const QLineEdit::EchoMode mode = lineedit->echoMode();
- return !lineedit->isReadOnly() && (mode == QLineEdit::Normal || mode == QLineEdit::PasswordEchoOnEdit);
+ return !lineedit->isReadOnly();
}
/*!
@@ -544,7 +543,13 @@ void QLineEdit::setEchoMode(EchoMode mode)
Q_D(QLineEdit);
if (mode == (EchoMode)d->echoMode)
return;
- setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
+ Qt::InputMethodHints imHints = inputMethodHints();
+ if (mode == Password) {
+ imHints |= Qt::ImhHiddenText;
+ } else {
+ imHints &= ~Qt::ImhHiddenText;
+ }
+ setInputMethodHints(imHints);
d->echoMode = mode;
d->passwordEchoEditing = false;
d->updateTextLayout();
@@ -1768,6 +1773,13 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
}
}
#endif
+
+ if (e->button() == Qt::LeftButton && qApp->autoSipEnabled()
+ && (!d->clickCausedFocus || qApp->autoSipOnMouseFocus())) {
+ QEvent event(QEvent::RequestSoftwareInputPanel);
+ QApplication::sendEvent(this, &event);
+ }
+ d->clickCausedFocus = 0;
}
/*! \reimp
@@ -2330,6 +2342,8 @@ QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
return QVariant(d->text);
case Qt::ImCurrentSelection:
return QVariant(selectedText());
+ case Qt::ImMaximumTextLength:
+ return QVariant(maxLength());
default:
return QVariant();
}
@@ -2348,6 +2362,8 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
d->moveCursor(d->nextMaskBlank(0));
else if (!d->hasSelectedText())
selectAll();
+ } else if (e->reason() == Qt::MouseFocusReason) {
+ d->clickCausedFocus = 1;
}
#ifdef QT_KEYPAD_NAVIGATION
if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason))
@@ -2926,6 +2942,7 @@ void QLineEditPrivate::moveCursor(int pos, bool mark)
selDirty = false;
emit q->selectionChanged();
}
+ q->updateMicroFocus();
emitCursorPositionChanged();
}
diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h
index 532528b..3db903f 100644
--- a/src/gui/widgets/qlineedit_p.h
+++ b/src/gui/widgets/qlineedit_p.h
@@ -76,7 +76,8 @@ public:
: cursor(0), preeditCursor(0), cursorTimer(0), frame(1),
cursorVisible(0), hideCursor(false), separator(0), readOnly(0),
dragEnabled(0), contextMenuEnabled(1), echoMode(0), textDirty(0),
- selDirty(0), validInput(1), alignment(Qt::AlignLeading | Qt::AlignVCenter), ascent(0),
+ selDirty(0), validInput(1), clickCausedFocus(0),
+ alignment(Qt::AlignLeading | Qt::AlignVCenter), ascent(0),
maxLength(32767), hscroll(0), vscroll(0), lastCursorPos(-1), maskData(0),
modifiedState(0), undoState(0), selstart(0), selend(0), userInput(false),
emitingEditingFinished(false), passwordEchoEditing(false)
@@ -110,6 +111,7 @@ public:
uint textDirty : 1;
uint selDirty : 1;
uint validInput : 1;
+ uint clickCausedFocus : 1;
uint alignment;
int ascent;
int maxLength;
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 7396a9d..6be0f19 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -1794,6 +1794,22 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this);
bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!atAction && QApplication::keypadNavigationEnabled()) {
+ // Try to have one item activated
+ if (d->defaultAction && d->defaultAction->isEnabled()) {
+ atAction = d->defaultAction;
+ // TODO: This works for first level menus, not yet sub menus
+ } else {
+ foreach (QAction *action, d->actionList)
+ if (action->isEnabled()) {
+ atAction = action;
+ break;
+ }
+ }
+ d->currentAction = atAction;
+ }
+#endif
if (d->ncols > 1) {
pos.setY(screen.top()+desktopFrame);
} else if (atAction) {
@@ -2571,6 +2587,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
case Qt::Key_Escape:
#ifdef QT_KEYPAD_NAVIGATION
case Qt::Key_Back:
+ case Qt::Key_Context2: // TODO: aportale, remove KEYPAD_NAVIGATION_HACK when softkey support is there
#endif
key_consumed = true;
if (d->tornoff) {
@@ -2848,6 +2865,16 @@ void QMenu::actionEvent(QActionEvent *e)
d->wce_menu->syncAction(e->action());
#endif
+#ifdef Q_OS_SYMBIAN
+ if (!d->symbian_menu)
+ d->symbian_menu = new QMenuPrivate::QSymbianMenuPrivate;
+ if (e->type() == QEvent::ActionAdded)
+ d->symbian_menu->addAction(e->action(), d->symbian_menu->findAction(e->before()));
+ else if (e->type() == QEvent::ActionRemoved)
+ d->symbian_menu->removeAction(e->action());
+ else if (e->type() == QEvent::ActionChanged)
+ d->symbian_menu->syncAction(e->action());
+#endif
if (isVisible()) {
d->updateActions();
resize(sizeHint());
diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h
index 867baee..1676eb8 100644
--- a/src/gui/widgets/qmenu.h
+++ b/src/gui/widgets/qmenu.h
@@ -52,11 +52,19 @@
#endif
QT_BEGIN_HEADER
+#ifdef Q_OS_SYMBIAN
+ class CEikMenuPane;
+#endif
QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
+#ifdef Q_OS_SYMBIAN
+ IMPORT_C void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
+ IMPORT_C void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
+#endif
+
#ifndef QT_NO_MENU
class QMenuPrivate;
@@ -145,7 +153,6 @@ public:
HMENU wceMenu(bool create = false);
#endif
-
bool separatorsCollapsible() const;
void setSeparatorsCollapsible(bool collapse);
@@ -177,6 +184,9 @@ protected:
#ifdef Q_OS_WINCE
QAction* wceCommands(uint command);
#endif
+#ifdef Q_OS_SYMBIAN
+ void symbianCommands(int command);
+#endif
private Q_SLOTS:
void internalSetSloppyAction();
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index 74367c4..a45f12f 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -61,6 +61,9 @@
#include "QtCore/qbasictimer.h"
#include "private/qwidget_p.h"
+#ifdef Q_OS_SYMBIAN
+class CEikMenuPane;
+#endif
QT_BEGIN_NAMESPACE
#ifndef QT_NO_MENU
@@ -120,6 +123,15 @@ struct QWceMenuAction {
QWceMenuAction() : menuHandle(0), command(0) {}
};
#endif
+#ifdef Q_OS_SYMBIAN
+struct QSymbianMenuAction {
+ uint command;
+ int parent;
+ CEikMenuPane* menuPane;
+ QPointer<QAction> action;
+ QSymbianMenuAction() : command(0) {}
+};
+#endif
class QMenuPrivate : public QWidgetPrivate
{
@@ -135,6 +147,9 @@ public:
#if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR)
,wce_menu(0)
#endif
+#ifdef Q_OS_SYMBIAN
+ ,symbian_menu(0)
+#endif
#ifdef QT3_SUPPORT
,emitHighlighted(false)
#endif
@@ -148,6 +163,10 @@ public:
#if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR)
delete wce_menu;
#endif
+#ifdef Q_OS_SYMBIAN
+ delete symbian_menu;
+#endif
+
}
void init();
@@ -318,7 +337,29 @@ public:
HMENU wceMenu(bool create = false);
QAction* wceCommands(uint command);
#endif
-
+#if defined(Q_OS_SYMBIAN)
+ struct QSymbianMenuPrivate {
+ QList<QSymbianMenuAction*> actionItems;
+ QSymbianMenuPrivate();
+ ~QSymbianMenuPrivate();
+ void addAction(QAction *, QSymbianMenuAction* =0);
+ void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
+ void syncAction(QSymbianMenuAction *);
+ inline void syncAction(QAction *a) { syncAction(findAction(a)); }
+ void removeAction(QSymbianMenuAction *);
+ void rebuild(bool reCreate = false);
+ inline void removeAction(QAction *a) { removeAction(findAction(a)); }
+ inline QSymbianMenuAction *findAction(QAction *a) {
+ for(int i = 0; i < actionItems.size(); i++) {
+ QSymbianMenuAction *act = actionItems[i];
+ if(a == act->action)
+ return act;
+ }
+ return 0;
+ }
+ } *symbian_menu;
+ bool symbianCommands(int command);
+#endif
QPointer<QWidget> noReplayFor;
};
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
new file mode 100644
index 0000000..86affe3
--- /dev/null
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+**
+** $TROLLTECH_DUAL_EMBEDDED_LICENSE$
+**
+****************************************************************************/
+
+#include "qmenu.h"
+#include "qapplication.h"
+#include "qmainwindow.h"
+#include "qtoolbar.h"
+#include "qevent.h"
+#include "qstyle.h"
+#include "qdebug.h"
+#include "qwidgetaction.h"
+#include <eikmenub.h>
+#include <eikmenup.h>
+#include <private/qapplication_p.h>
+#include <private/qmenu_p.h>
+#include <private/qmenubar_p.h>
+#include <qt_s60_p.h>
+#include <eikaufty.h>
+#include <eikbtgpc.h>
+#include <QtCore/qlibrary.h>
+#include <avkon.rsg>
+
+#ifndef QT_NO_MENUBAR
+
+QT_BEGIN_NAMESPACE
+
+// ### FIX/Document this, we need some safe range of menu id's for Qt that don't clash with AIW ones
+typedef QMultiHash<QWidget *, QMenuBarPrivate *> MenuBarHash;
+Q_GLOBAL_STATIC(MenuBarHash, menubars)
+
+#define QT_FIRST_MENU_ITEM 32000
+
+struct SymbianMenuItem
+{
+ int id;
+ CEikMenuPaneItem::SData menuItemData;
+ QList<SymbianMenuItem*> children;
+ QAction* action;
+};
+
+static QList<SymbianMenuItem*> symbianMenus;
+static QList<QMenuBar*> nativeMenuBars;
+static uint qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
+
+bool menuExists()
+{
+ QWidget *w = qApp->activeWindow();
+ QMenuBarPrivate *mb = menubars()->value(w);
+ if ((!mb) && !menubars()->count())
+ return false;
+ return true;
+}
+
+// ### FIX THIS, copy/paste of original (faulty) stripped text implementation.
+// Implementation should be removed from QAction implementation to some generic place
+static QString qt_strippedText_copy_from_qaction(QString s)
+{
+ s.remove(QString::fromLatin1("..."));
+ int i = 0;
+ while (i < s.size()) {
+ ++i;
+ if (s.at(i-1) != QLatin1Char('&'))
+ continue;
+ if (i < s.size() && s.at(i) == QLatin1Char('&'))
+ ++i;
+ s.remove(i-1,1);
+ }
+ return s.trimmed();
+};
+
+static SymbianMenuItem* qt_symbian_find_menu(int id, const QList<SymbianMenuItem*> &parent)
+{
+ int index=0;
+ while (index < parent.count()) {
+ SymbianMenuItem* temp = parent[index];
+ if (temp->menuItemData.iCascadeId == id)
+ return temp;
+ else if (temp->menuItemData.iCascadeId != 0) {
+ SymbianMenuItem* result = qt_symbian_find_menu( id, temp->children);
+ if (result)
+ return result;
+ }
+ index++;
+ }
+ return 0;
+}
+
+static SymbianMenuItem* qt_symbian_find_menu_item(int id, const QList<SymbianMenuItem*> &parent)
+{
+ int index=0;
+ while (index < parent.count()) {
+ SymbianMenuItem* temp = parent[index];
+ if (temp->menuItemData.iCascadeId != 0) {
+ SymbianMenuItem* result = qt_symbian_find_menu_item( id, temp->children);
+ if (result)
+ return result;
+ }
+ else if (temp->menuItemData.iCommandId == id)
+ return temp;
+ index++;
+
+ }
+ return 0;
+}
+
+static void qt_symbian_insert_action(QSymbianMenuAction* action, QList<SymbianMenuItem*>* parent)
+{
+ if (action->action->isVisible()) {
+ if (action->action->isSeparator())
+ return;
+
+// ### FIX THIS, the qt_strippedText2 doesn't work perfectly for stripping & marks. Same bug is in QAction
+// New really working method is needed in a place where the implementation isn't copy/pasted
+ QString text = qt_strippedText_copy_from_qaction(action->action->text());
+ HBufC* menuItemText = qt_QString2HBufCNewL(text);
+
+ if (action->action->menu()) {
+ SymbianMenuItem* menuItem = new SymbianMenuItem();
+ menuItem->menuItemData.iCascadeId = action->command;
+ menuItem->menuItemData.iCommandId = action->command;
+ menuItem->menuItemData.iFlags = 0;
+ menuItem->menuItemData.iText = *menuItemText;
+ menuItem->action = action->action;
+ if (action->action->menu()->actions().size() == 0 || !action->action->isEnabled() )
+ menuItem->menuItemData.iFlags |= EEikMenuItemDimmed;
+ parent->append(menuItem);
+
+ if (action->action->menu()->actions().size() > 0) {
+ for (int c2= 0; c2 < action->action->menu()->actions().size(); ++c2) {
+ QSymbianMenuAction *symbianAction2 = new QSymbianMenuAction;
+ symbianAction2->action = action->action->menu()->actions().at(c2);
+ QMenu * menu = symbianAction2->action->menu();
+ symbianAction2->command = qt_symbian_menu_static_cmd_id++;
+ qt_symbian_insert_action(symbianAction2, &(menuItem->children));
+ }
+ }
+
+ } else {
+ SymbianMenuItem* menuItem = new SymbianMenuItem();
+ menuItem->menuItemData.iCascadeId = 0;
+ menuItem->menuItemData.iCommandId = action->command;
+ menuItem->menuItemData.iFlags = 0;
+ menuItem->menuItemData.iText = *menuItemText;
+ menuItem->action = action->action;
+ if (!action->action->isEnabled()){
+ menuItem->menuItemData.iFlags += EEikMenuItemDimmed;
+ }
+
+ if (action->action->isCheckable()) {
+ if (action->action->isChecked())
+ menuItem->menuItemData.iFlags += EEikMenuItemCheckBox | EEikMenuItemSymbolOn;
+ else
+ menuItem->menuItemData.iFlags += EEikMenuItemCheckBox;
+ }
+ parent->append(menuItem);
+ }
+ delete menuItemText;
+ }
+}
+
+void deleteAll(QList<SymbianMenuItem*> *items)
+{
+ while (!items->isEmpty()) {
+ SymbianMenuItem* temp = items->takeFirst();
+ deleteAll(&temp->children);
+ delete temp;
+ }
+}
+
+static void setSoftkeys()
+{
+ CEikButtonGroupContainer* cba = CEikonEnv::Static()->AppUiFactory()->Cba();
+ if (cba){
+ if (menuExists())
+ cba->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_EXIT);
+ else
+ cba->SetCommandSetL(R_AVKON_SOFTKEYS_EXIT);
+ }
+}
+
+static void rebuildMenu()
+{
+ QMenuBarPrivate *mb = 0;
+ setSoftkeys();
+ QWidget *w = qApp->activeWindow();
+ if (w)
+ {
+ mb = menubars()->value(w);
+ qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
+ deleteAll( &symbianMenus );
+ if (!mb)
+ return;
+ mb->symbian_menubar->rebuild();
+ }
+ }
+
+Q_GUI_EXPORT void qt_symbian_show_toplevel( CEikMenuPane* menuPane)
+{
+ if (!menuExists())
+ return;
+ rebuildMenu();
+ for (int i = 0; i < symbianMenus.count(); ++i)
+ menuPane->AddMenuItemL(symbianMenus.at(i)->menuItemData);
+}
+
+Q_GUI_EXPORT void qt_symbian_show_submenu( CEikMenuPane* menuPane, int id)
+{
+ SymbianMenuItem* menu = qt_symbian_find_menu(id, symbianMenus);
+ if (menu) {
+ for (int i = 0; i < menu->children.count(); ++i)
+ menuPane->AddMenuItemL(menu->children.at(i)->menuItemData);
+ }
+}
+
+void QMenu::symbianCommands(int command)
+{
+ Q_D(QMenu);
+ d->symbianCommands(command);
+}
+
+void QMenuBar::symbianCommands(int command)
+{
+ int size = nativeMenuBars.size();
+ for (int i = 0; i < nativeMenuBars.size(); ++i) {
+ bool result = nativeMenuBars.at(i)->d_func()->symbianCommands(command);
+ if (result)
+ return;
+ }
+}
+
+bool QMenuBarPrivate::symbianCommands(int command)
+{
+ SymbianMenuItem* menu = qt_symbian_find_menu_item(command, symbianMenus);
+ if (!menu)
+ return false;
+
+ emit q_func()->triggered(menu->action);
+ menu->action->activate(QAction::Trigger);
+ return true;
+}
+
+bool QMenuPrivate::symbianCommands(int command)
+{
+ SymbianMenuItem* menu = qt_symbian_find_menu_item(command, symbianMenus);
+ if (!menu)
+ return false;
+
+ emit q_func()->triggered(menu->action);
+ menu->action->activate(QAction::Trigger);
+ return true;
+}
+
+void QMenuBarPrivate::symbianCreateMenuBar(QWidget *parent)
+{
+ Q_Q(QMenuBar);
+ if (parent && parent->isWindow()){
+ menubars()->insert(q->window(), this);
+ symbian_menubar = new QSymbianMenuBarPrivate(this);
+ nativeMenuBars.append(q);
+ }
+}
+
+void QMenuBarPrivate::symbianDestroyMenuBar()
+{
+ Q_Q(QMenuBar);
+ int index = nativeMenuBars.indexOf(q);
+ nativeMenuBars.removeAt(index);
+ menubars()->remove(q->window(), this);
+ rebuildMenu();
+ if (symbian_menubar)
+ delete symbian_menubar;
+ symbian_menubar = 0;
+}
+
+QMenuBarPrivate::QSymbianMenuBarPrivate::QSymbianMenuBarPrivate(QMenuBarPrivate *menubar)
+{
+ d = menubar;
+}
+
+QMenuBarPrivate::QSymbianMenuBarPrivate::~QSymbianMenuBarPrivate()
+{
+ deleteAll( &symbianMenus );
+ symbianMenus.clear();
+ d = 0;
+ rebuild();
+}
+
+QMenuPrivate::QSymbianMenuPrivate::QSymbianMenuPrivate()
+{
+}
+
+QMenuPrivate::QSymbianMenuPrivate::~QSymbianMenuPrivate()
+{
+
+}
+
+void QMenuPrivate::QSymbianMenuPrivate::addAction(QAction *a, QSymbianMenuAction *before)
+{
+ QSymbianMenuAction *action = new QSymbianMenuAction;
+ action->action = a;
+ action->command = qt_symbian_menu_static_cmd_id++;
+ addAction(action, before);
+}
+
+void QMenuPrivate::QSymbianMenuPrivate::addAction(QSymbianMenuAction *action, QSymbianMenuAction *before)
+{
+ if (!action)
+ return;
+ int before_index = actionItems.indexOf(before);
+ if (before_index < 0) {
+ before = 0;
+ before_index = actionItems.size();
+ }
+ actionItems.insert(before_index, action);
+}
+
+
+void QMenuPrivate::QSymbianMenuPrivate::syncAction(QSymbianMenuAction *)
+{
+ rebuild();
+}
+
+void QMenuPrivate::QSymbianMenuPrivate::removeAction(QSymbianMenuAction *action)
+{
+ actionItems.removeAll(action);
+ delete action;
+ action = 0;
+ rebuild();
+}
+
+void QMenuPrivate::QSymbianMenuPrivate::rebuild(bool)
+{
+}
+
+void QMenuBarPrivate::QSymbianMenuBarPrivate::addAction(QAction *a, QSymbianMenuAction *before)
+{
+ QSymbianMenuAction *action = new QSymbianMenuAction;
+ action->action = a;
+ action->command = qt_symbian_menu_static_cmd_id++;
+ addAction(action, before);
+}
+
+void QMenuBarPrivate::QSymbianMenuBarPrivate::addAction(QSymbianMenuAction *action, QSymbianMenuAction *before)
+{
+ if (!action)
+ return;
+ int before_index = actionItems.indexOf(before);
+ if (before_index < 0) {
+ before = 0;
+ before_index = actionItems.size();
+ }
+ actionItems.insert(before_index, action);
+}
+
+void QMenuBarPrivate::QSymbianMenuBarPrivate::syncAction(QSymbianMenuAction*)
+{
+ rebuild();
+}
+
+void QMenuBarPrivate::QSymbianMenuBarPrivate::removeAction(QSymbianMenuAction *action)
+{
+ actionItems.removeAll(action);
+ delete action;
+ rebuild();
+}
+
+void QMenuBarPrivate::QSymbianMenuBarPrivate::rebuild()
+{
+ setSoftkeys();
+ qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
+ deleteAll( &symbianMenus );
+ if (!d)
+ return;
+ for (int i = 0; i < d->actions.size(); ++i) {
+ QSymbianMenuAction *symbianActionTopLevel = new QSymbianMenuAction;
+ symbianActionTopLevel->action = d->actions.at(i);
+ symbianActionTopLevel->parent = 0;
+ symbianActionTopLevel->command = qt_symbian_menu_static_cmd_id++;
+ qt_symbian_insert_action(symbianActionTopLevel, &symbianMenus);
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_MENUBAR
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index c63da64..fb8a69b 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -732,6 +732,12 @@ void QMenuBarPrivate::init()
q->hide();
}
#endif
+#ifdef Q_OS_SYMBIAN
+ symbianCreateMenuBar(q->parentWidget());
+ if(symbian_menubar)
+ q->hide();
+#endif
+
q->setBackgroundRole(QPalette::Button);
oldWindow = oldParent = 0;
#ifdef QT3_SUPPORT
@@ -781,6 +787,10 @@ QMenuBar::~QMenuBar()
if (qt_wince_is_mobile())
d->wceDestroyMenuBar();
#endif
+#ifdef Q_OS_SYMBIAN
+ Q_D(QMenuBar);
+ d->symbianDestroyMenuBar();
+#endif
}
/*!
@@ -1035,6 +1045,12 @@ void QMenuBar::setVisible(bool visible)
if(d->wce_menubar)
return;
#endif
+#ifdef Q_OS_SYMBIAN
+ Q_D(QMenuBar);
+ if(d->symbian_menubar)
+ return;
+#endif
+
QWidget::setVisible(visible);
}
@@ -1292,6 +1308,17 @@ void QMenuBar::actionEvent(QActionEvent *e)
d->wce_menubar->syncAction(e->action());
}
#endif
+#ifdef Q_OS_SYMBIAN
+ if(d->symbian_menubar) {
+ if(e->type() == QEvent::ActionAdded)
+ d->symbian_menubar->addAction(e->action(), d->symbian_menubar->findAction(e->before()));
+ else if(e->type() == QEvent::ActionRemoved)
+ d->symbian_menubar->removeAction(e->action());
+ else if(e->type() == QEvent::ActionChanged)
+ d->symbian_menubar->syncAction(e->action());
+ }
+#endif
+
if(e->type() == QEvent::ActionAdded) {
connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
@@ -1378,6 +1405,11 @@ void QMenuBarPrivate::handleReparent()
if (qt_wince_is_mobile() && wce_menubar)
wce_menubar->rebuild();
#endif
+#ifdef Q_OS_SYMBIAN
+ if (symbian_menubar)
+ symbian_menubar->rebuild();
+#endif
+
}
#ifdef QT3_SUPPORT
@@ -1616,6 +1648,8 @@ QSize QMenuBar::minimumSizeHint() const
const bool as_gui_menubar = !d->mac_menubar;
#elif defined (Q_OS_WINCE)
const bool as_gui_menubar = !d->wce_menubar;
+#elif defined (Q_OS_SYMBIAN)
+ const bool as_gui_menubar = !d->symbian_menubar;
#else
const bool as_gui_menubar = true;
#endif
@@ -1676,6 +1710,8 @@ QSize QMenuBar::sizeHint() const
const bool as_gui_menubar = !d->mac_menubar;
#elif defined (Q_OS_WINCE)
const bool as_gui_menubar = !d->wce_menubar;
+#elif defined (Q_OS_SYMBIAN)
+ const bool as_gui_menubar = !d->symbian_menubar;
#else
const bool as_gui_menubar = true;
#endif
@@ -1739,6 +1775,8 @@ int QMenuBar::heightForWidth(int) const
const bool as_gui_menubar = !d->mac_menubar;
#elif defined (Q_OS_WINCE)
const bool as_gui_menubar = !d->wce_menubar;
+#elif defined (Q_OS_SYMBIAN)
+ const bool as_gui_menubar = !d->symbian_menubar;
#else
const bool as_gui_menubar = true;
#endif
diff --git a/src/gui/widgets/qmenubar.h b/src/gui/widgets/qmenubar.h
index 42f0c0c..36c983b 100644
--- a/src/gui/widgets/qmenubar.h
+++ b/src/gui/widgets/qmenubar.h
@@ -118,6 +118,10 @@ public:
static void wceRefresh();
#endif
+#ifdef Q_OS_SYMBIAN
+ static void symbianCommands(int command);
+#endif
+
public Q_SLOTS:
virtual void setVisible(bool visible);
diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h
index 223346b..d562cd9 100644
--- a/src/gui/widgets/qmenubar_p.h
+++ b/src/gui/widgets/qmenubar_p.h
@@ -61,6 +61,13 @@
#include "qguifunctions_wince.h"
#endif
+#ifndef QT_NO_MENUBAR
+#ifdef Q_OS_SYMBIAN
+class CCoeControl;
+class CEikMenuBar;
+#endif
+#endif
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_MENUBAR
@@ -78,7 +85,11 @@ public:
#ifdef Q_OS_WINCE
, wce_menubar(0), wceClassicMenu(false)
#endif
- { }
+#ifdef Q_OS_SYMBIAN
+ , symbian_menubar(0)
+#endif
+
+ { }
~QMenuBarPrivate()
{
#ifdef Q_WS_MAC
@@ -87,6 +98,9 @@ public:
#ifdef Q_OS_WINCE
delete wce_menubar;
#endif
+#ifdef Q_OS_SYMBIAN
+ delete symbian_menubar;
+#endif
}
void init();
@@ -220,6 +234,34 @@ public:
void wceRefresh();
bool wceEmitSignals(QList<QWceMenuAction*> actions, uint command);
#endif
+#ifdef Q_OS_SYMBIAN
+ void symbianCreateMenuBar(QWidget *);
+ void symbianDestroyMenuBar();
+ struct QSymbianMenuBarPrivate {
+ QList<QSymbianMenuAction*> actionItems;
+ QMenuBarPrivate *d;
+ QSymbianMenuBarPrivate(QMenuBarPrivate *menubar);
+ ~QSymbianMenuBarPrivate();
+ void addAction(QAction *, QSymbianMenuAction* =0);
+ void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
+ void syncAction(QSymbianMenuAction *);
+ inline void syncAction(QAction *a) { syncAction(findAction(a)); }
+ void removeAction(QSymbianMenuAction *);
+ void rebuild();
+ inline void removeAction(QAction *a) { removeAction(findAction(a)); }
+ inline QSymbianMenuAction *findAction(QAction *a) {
+ for(int i = 0; i < actionItems.size(); i++) {
+ QSymbianMenuAction *act = actionItems[i];
+ if(a == act->action)
+ return act;
+ }
+ return 0;
+ }
+
+ } *symbian_menubar;
+ bool symbianCommands(int command);
+
+#endif
};
#endif
diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri
index 86dc453..fc57944 100644
--- a/src/gui/widgets/widgets.pri
+++ b/src/gui/widgets/widgets.pri
@@ -160,3 +160,7 @@ wince*: {
RC_FILE = widgets/qmenu_wince.rc
!static: QMAKE_WRITE_DEFAULT_RC = 1
}
+
+symbian*: {
+ SOURCES += widgets/qmenu_symbian.cpp
+}