summaryrefslogtreecommitdiff
path: root/libopie2/opieui/opopupmenu.cpp
Side-by-side diff
Diffstat (limited to 'libopie2/opieui/opopupmenu.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opieui/opopupmenu.cpp7
1 files changed, 0 insertions, 7 deletions
diff --git a/libopie2/opieui/opopupmenu.cpp b/libopie2/opieui/opopupmenu.cpp
index ac73188..d5cc575 100644
--- a/libopie2/opieui/opopupmenu.cpp
+++ b/libopie2/opieui/opopupmenu.cpp
@@ -1,414 +1,407 @@
/* This file is part of the KDE libraries
Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org>
Copyright (C) 2002 Hamish Rodda <meddie@yoyo.its.monash.edu.au>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/* QT */
-#include <qapplication.h>
-#include <qcursor.h>
-#include <qpainter.h>
#include <qdrawutil.h>
#include <qtimer.h>
-#include <qfont.h>
-#include <qfontmetrics.h>
-#include <qregexp.h>
-#include <qstyle.h>
/* OPIE */
#include <opie2/opopupmenu.h>
#include <opie2/oconfig.h>
OPopupTitle::OPopupTitle(QWidget *parent, const char *name)
: QWidget(parent, name)
{
setMinimumSize(16, fontMetrics().height()+8);
}
OPopupTitle::OPopupTitle(OPixmapEffect::GradientType /* gradient */,
const QColor &/* color */, const QColor &/* textColor */,
QWidget *parent, const char *name)
: QWidget(parent, name)
{
setMinimumSize(16, fontMetrics().height()+8);
}
OPopupTitle::OPopupTitle(const OPixmap & /* background */, const QColor &/* color */,
const QColor &/* textColor */, QWidget *parent,
const char *name)
: QWidget(parent, name)
{
setMinimumSize(16, fontMetrics().height()+8);
}
void OPopupTitle::setTitle(const QString &text, const QPixmap *icon)
{
titleStr = text;
if (icon)
miniicon = *icon;
else
miniicon.resize(0, 0);
int w = miniicon.width()+fontMetrics().width(titleStr);
int h = QMAX( fontMetrics().height(), miniicon.height() );
setMinimumSize( w+16, h+8 );
}
void OPopupTitle::setText( const QString &text )
{
titleStr = text;
int w = miniicon.width()+fontMetrics().width(titleStr);
int h = QMAX( fontMetrics().height(), miniicon.height() );
setMinimumSize( w+16, h+8 );
}
void OPopupTitle::setIcon( const QPixmap &pix )
{
miniicon = pix;
int w = miniicon.width()+fontMetrics().width(titleStr);
int h = QMAX( fontMetrics().height(), miniicon.height() );
setMinimumSize( w+16, h+8 );
}
void OPopupTitle::paintEvent(QPaintEvent *)
{
QRect r(rect());
QPainter p(this);
#if QT_VERSION > 290
qApp->style().drawPrimitive(QStyle::PE_HeaderSection, &p, r, palette().active());
#else
#warning OPopupMenu is not fully functional on Qt2
#endif
if (!miniicon.isNull())
p.drawPixmap(4, (r.height()-miniicon.height())/2, miniicon);
if (!titleStr.isNull())
{
p.setPen(palette().active().text());
QFont f = p.font();
f.setBold(true);
p.setFont(f);
if(!miniicon.isNull())
{
p.drawText(miniicon.width()+8, 0, width()-(miniicon.width()+8),
height(), AlignLeft | AlignVCenter | SingleLine,
titleStr);
}
else
{
p.drawText(0, 0, width(), height(),
AlignCenter | SingleLine, titleStr);
}
}
p.setPen(palette().active().highlight());
p.drawLine(0, 0, r.right(), 0);
}
QSize OPopupTitle::sizeHint() const
{
return(minimumSize());
}
class OPopupMenu::OPopupMenuPrivate
{
public:
OPopupMenuPrivate ()
: noMatches(false)
, shortcuts(false)
, autoExec(false)
, lastHitIndex(-1)
, m_ctxMenu(0)
{}
~OPopupMenuPrivate ()
{
delete m_ctxMenu;
}
QString m_lastTitle;
// variables for keyboard navigation
QTimer clearTimer;
bool noMatches : 1;
bool shortcuts : 1;
bool autoExec : 1;
QString keySeq;
QString originalText;
int lastHitIndex;
// support for RMB menus on menus
QPopupMenu* m_ctxMenu;
static bool s_continueCtxMenuShow;
static int s_highlightedItem;
static OPopupMenu* s_contextedMenu;
};
int OPopupMenu::OPopupMenuPrivate::s_highlightedItem(-1);
OPopupMenu* OPopupMenu::OPopupMenuPrivate::s_contextedMenu(0);
bool OPopupMenu::OPopupMenuPrivate::s_continueCtxMenuShow(true);
OPopupMenu::OPopupMenu(QWidget *parent, const char *name)
: QPopupMenu(parent, name)
{
d = new OPopupMenuPrivate;
resetKeyboardVars();
connect(&(d->clearTimer), SIGNAL(timeout()), SLOT(resetKeyboardVars()));
}
OPopupMenu::~OPopupMenu()
{
if (OPopupMenuPrivate::s_contextedMenu == this)
{
OPopupMenuPrivate::s_contextedMenu = 0;
OPopupMenuPrivate::s_highlightedItem = -1;
}
delete d;
}
int OPopupMenu::insertTitle(const QString &text, int id, int index)
{
OPopupTitle *titleItem = new OPopupTitle();
titleItem->setTitle(text);
int ret = insertItem(titleItem, id, index);
setItemEnabled(id, false);
return ret;
}
int OPopupMenu::insertTitle(const QPixmap &icon, const QString &text, int id,
int index)
{
OPopupTitle *titleItem = new OPopupTitle();
titleItem->setTitle(text, &icon);
int ret = insertItem(titleItem, id, index);
setItemEnabled(id, false);
return ret;
}
void OPopupMenu::changeTitle(int id, const QString &text)
{
QMenuItem *item = findItem(id);
if(item){
if(item->widget())
((OPopupTitle *)item->widget())->setTitle(text);
#ifndef NDEBUG
else
qWarning( "KPopupMenu: changeTitle() called with non-title id %d", id );
#endif
}
#ifndef NDEBUG
else
qWarning( "KPopupMenu: changeTitle() called with invalid id %d", id );
#endif
}
void OPopupMenu::changeTitle(int id, const QPixmap &icon, const QString &text)
{
QMenuItem *item = findItem(id);
if(item){
if(item->widget())
((OPopupTitle *)item->widget())->setTitle(text, &icon);
#ifndef NDEBUG
else
qWarning( "KPopupMenu: changeTitle() called with non-title id %d", id );
#endif
}
#ifndef NDEBUG
else
qWarning( "KPopupMenu: changeTitle() called with invalid id %d", id );
#endif
}
QString OPopupMenu::title(int id) const
{
if(id == -1) // obsolete
return(d->m_lastTitle);
QMenuItem *item = findItem(id);
if(item){
if(item->widget())
return(((OPopupTitle *)item->widget())->title());
else
qWarning("OPopupMenu: title() called with non-title id %d.", id);
}
else
qWarning("OPopupMenu: title() called with invalid id %d.", id);
return(QString::null);
}
QPixmap OPopupMenu::titlePixmap(int id) const
{
QMenuItem *item = findItem(id);
if(item){
if(item->widget())
return(((OPopupTitle *)item->widget())->icon());
else
qWarning("KPopupMenu: titlePixmap() called with non-title id %d.", id);
}
else
qWarning("KPopupMenu: titlePixmap() called with invalid id %d.", id);
QPixmap tmp;
return(tmp);
}
/**
* This is re-implemented for keyboard navigation.
*/
void OPopupMenu::closeEvent(QCloseEvent*e)
{
if (d->shortcuts)
resetKeyboardVars();
QPopupMenu::closeEvent(e);
}
void OPopupMenu::keyPressEvent(QKeyEvent* e)
{
if (!d->shortcuts) {
// continue event processing by Qpopup
//e->ignore();
QPopupMenu::keyPressEvent(e);
return;
}
int i = 0;
bool firstpass = true;
QString keyString = e->text();
// check for common commands dealt with by QPopup
int key = e->key();
if (key == Key_Escape || key == Key_Return || key == Key_Enter
|| key == Key_Up || key == Key_Down || key == Key_Left
|| key == Key_Right || key == Key_F1) {
resetKeyboardVars();
// continue event processing by Qpopup
//e->ignore();
QPopupMenu::keyPressEvent(e);
return;
}
// check to see if the user wants to remove a key from the sequence (backspace)
// or clear the sequence (delete)
if (!d->keySeq.isNull()) {
if (key == Key_Backspace) {
if (d->keySeq.length() == 1) {
resetKeyboardVars();
return;
}
// keep the last sequence in keyString
keyString = d->keySeq.left(d->keySeq.length() - 1);
// allow sequence matching to be tried again
resetKeyboardVars();
} else if (key == Key_Delete) {
resetKeyboardVars();
// clear active item
setActiveItem(0);
return;
} else if (d->noMatches) {
// clear if there are no matches
resetKeyboardVars();
// clear active item
setActiveItem(0);
} else {
// the key sequence is not a null string
// therefore the lastHitIndex is valid
i = d->lastHitIndex;
}
} else if (key == Key_Backspace && parentMenu) {
// backspace with no chars in the buffer... go back a menu.
hide();
resetKeyboardVars();
return;
}
d->keySeq += keyString;
int seqLen = d->keySeq.length();
for (; i < (int)count(); i++) {
// compare typed text with text of this entry
int j = idAt(i);
// don't search disabled entries
if (!isItemEnabled(j))
continue;
QString thisText;
// retrieve the right text
// (the last selected item one may have additional ampersands)
if (i == d->lastHitIndex)
thisText = d->originalText;
else
thisText = text(j);
// if there is an accelerator present, remove it
if ((int)accel(j) != 0)
thisText = thisText.replace(QRegExp("&"), "");
// chop text to the search length
thisText = thisText.left(seqLen);
// do the search
if (thisText.find(d->keySeq, 0, false) == 0) {
if (firstpass) {
// match
setActiveItem(i);
// check to see if we're underlining a different item
if (d->lastHitIndex != i)
// yes; revert the underlining
changeItem(idAt(d->lastHitIndex), d->originalText);
// set the original text if it's a different item
if (d->lastHitIndex != i || d->lastHitIndex == -1)
d->originalText = text(j);
// underline the currently selected item
changeItem(j, underlineText(d->originalText, d->keySeq.length()));
// remeber what's going on
d->lastHitIndex = i;
// start/restart the clear timer
d->clearTimer.start(5000, true);
// go around for another try, to see if we can execute
firstpass = false;
} else {
// don't allow execution
return;
}
}
// fall through to allow execution
}