diff options
Diffstat (limited to 'kdeui/kpopupmenu.cpp')
-rw-r--r-- | kdeui/kpopupmenu.cpp | 694 |
1 files changed, 0 insertions, 694 deletions
diff --git a/kdeui/kpopupmenu.cpp b/kdeui/kpopupmenu.cpp deleted file mode 100644 index 2e174422b..000000000 --- a/kdeui/kpopupmenu.cpp +++ /dev/null @@ -1,694 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org> - Copyright (C) 2002 Hamish Rodda <rodda@kde.org> - - 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#include <tqcursor.h> -#include <tqpainter.h> -#include <tqtimer.h> -#include <tqfontmetrics.h> - -#ifdef USE_QT4 -#undef None -#endif // USE_QT4 - -#include <tqstyle.h> - -#include "kpopupmenu.h" - -#include <kdebug.h> -#include <kapplication.h> - -KPopupTitle::KPopupTitle(TQWidget *parent, const char *name) - : TQWidget(parent, name) -{ - setMinimumSize(16, fontMetrics().height()+8); -} - -KPopupTitle::KPopupTitle(KPixmapEffect::GradientType /* gradient */, - const TQColor &/* color */, const TQColor &/* textColor */, - TQWidget *parent, const char *name) - : TQWidget(parent, name) -{ - calcSize(); -} - -KPopupTitle::KPopupTitle(const KPixmap & /* background */, const TQColor &/* color */, - const TQColor &/* textColor */, TQWidget *parent, - const char *name) - : TQWidget(parent, name) -{ - calcSize(); -} - -void KPopupTitle::setTitle(const TQString &text, const TQPixmap *icon) -{ - titleStr = text; - if (icon) - miniicon = *icon; - else - miniicon.resize(0, 0); - - calcSize(); -} - -void KPopupTitle::setText( const TQString &text ) -{ - titleStr = text; - calcSize(); -} - -void KPopupTitle::setIcon( const TQPixmap &pix ) -{ - miniicon = pix; - calcSize(); -} - -void KPopupTitle::calcSize() -{ - TQFont f = font(); - f.setBold(true); - int w = miniicon.width()+TQFontMetrics(f).width(titleStr); - int h = QMAX( fontMetrics().height(), miniicon.height() ); - setMinimumSize( w+16, h+8 ); -} - -void KPopupTitle::paintEvent(TQPaintEvent *) -{ - TQRect r(rect()); - TQPainter p(this); - kapp->tqstyle().tqdrawPrimitive(TQStyle::PE_HeaderSectionMenu, &p, r, tqpalette().active()); - - if (!miniicon.isNull()) - p.drawPixmap(4, (r.height()-miniicon.height())/2, miniicon); - - if (!titleStr.isNull()) - { - p.setPen(tqpalette().active().text()); - TQFont 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); - } - } -} - -TQSize KPopupTitle::tqsizeHint() const -{ - return tqminimumSize(); -} - -class KPopupMenu::KPopupMenuPrivate -{ -public: - KPopupMenuPrivate () - : noMatches(false) - , shortcuts(false) - , autoExec(false) - , lastHitIndex(-1) - , state(Qt::NoButton) - , m_ctxMenu(0) - {} - - ~KPopupMenuPrivate () - { - delete m_ctxMenu; - } - - TQString m_lastTitle; - - // variables for keyboard navigation - TQTimer clearTimer; - - bool noMatches : 1; - bool shortcuts : 1; - bool autoExec : 1; - - TQString keySeq; - TQString originalText; - - int lastHitIndex; - TQt::ButtonState state; - - // support for RMB menus on menus - TQPopupMenu* m_ctxMenu; - static bool s_continueCtxMenuShow; - static int s_highlightedItem; - static KPopupMenu* s_contextedMenu; -}; - -int KPopupMenu::KPopupMenuPrivate::s_highlightedItem(-1); -KPopupMenu* KPopupMenu::KPopupMenuPrivate::s_contextedMenu(0); -bool KPopupMenu::KPopupMenuPrivate::s_continueCtxMenuShow(true); - -KPopupMenu::KPopupMenu(TQWidget *parent, const char *name) - : TQPopupMenu(parent, name) -{ - d = new KPopupMenuPrivate; - resetKeyboardVars(); - connect(&(d->clearTimer), TQT_SIGNAL(timeout()), TQT_SLOT(resetKeyboardVars())); -} - -KPopupMenu::~KPopupMenu() -{ - if (KPopupMenuPrivate::s_contextedMenu == this) - { - KPopupMenuPrivate::s_contextedMenu = 0; - KPopupMenuPrivate::s_highlightedItem = -1; - } - - delete d; -} - -int KPopupMenu::insertTitle(const TQString &text, int id, int index) -{ - KPopupTitle *titleItem = new KPopupTitle(); - titleItem->setTitle(text); - int ret = insertItem(titleItem, id, index); - setItemEnabled(ret, false); - return ret; -} - -int KPopupMenu::insertTitle(const TQPixmap &icon, const TQString &text, int id, - int index) -{ - KPopupTitle *titleItem = new KPopupTitle(); - titleItem->setTitle(text, &icon); - int ret = insertItem(titleItem, id, index); - setItemEnabled(ret, false); - return ret; -} - -void KPopupMenu::changeTitle(int id, const TQString &text) -{ - TQMenuItem *item = findItem(id); - if(item){ - if(item->widget()) - ((KPopupTitle *)item->widget())->setTitle(text); -#ifndef NDEBUG - else - kdWarning() << "KPopupMenu: changeTitle() called with non-title id "<< id << endl; -#endif - } -#ifndef NDEBUG - else - kdWarning() << "KPopupMenu: changeTitle() called with invalid id " << id << endl; -#endif -} - -void KPopupMenu::changeTitle(int id, const TQPixmap &icon, const TQString &text) -{ - TQMenuItem *item = findItem(id); - if(item){ - if(item->widget()) - ((KPopupTitle *)item->widget())->setTitle(text, &icon); -#ifndef NDEBUG - else - kdWarning() << "KPopupMenu: changeTitle() called with non-title id "<< id << endl; -#endif - } -#ifndef NDEBUG - else - kdWarning() << "KPopupMenu: changeTitle() called with invalid id " << id << endl; -#endif -} - -TQString KPopupMenu::title(int id) const -{ - if(id == -1) // obsolete - return d->m_lastTitle; - TQMenuItem *item = findItem(id); - if(item){ - if(item->widget()) - return ((KPopupTitle *)item->widget())->title(); - else - qWarning("KPopupMenu: title() called with non-title id %d.", id); - } - else - qWarning("KPopupMenu: title() called with invalid id %d.", id); - return TQString::null; -} - -TQPixmap KPopupMenu::titlePixmap(int id) const -{ - TQMenuItem *item = findItem(id); - if(item){ - if(item->widget()) - return ((KPopupTitle *)item->widget())->icon(); - else - qWarning("KPopupMenu: titlePixmap() called with non-title id %d.", id); - } - else - qWarning("KPopupMenu: titlePixmap() called with invalid id %d.", id); - TQPixmap tmp; - return tmp; -} - -/** - * This is re-implemented for keyboard navigation. - */ -void KPopupMenu::closeEvent(TQCloseEvent*e) -{ - if (d->shortcuts) - resetKeyboardVars(); - TQPopupMenu::closeEvent(e); -} - -void KPopupMenu::activateItemAt(int index) -{ - d->state = Qt::NoButton; - TQPopupMenu::activateItemAt(index); -} - -TQt::ButtonState KPopupMenu::state() const -{ - return d->state; -} - -void KPopupMenu::keyPressEvent(TQKeyEvent* e) -{ - d->state = Qt::NoButton; - if (!d->shortcuts) { - // continue event processing by Qpopup - //e->ignore(); - d->state = e->state(); - TQPopupMenu::keyPressEvent(e); - return; - } - - int i = 0; - bool firstpass = true; - TQString 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(); - d->state = e->state(); - TQPopupMenu::keyPressEvent(e); - return; - } else if ( key == Key_Shift || key == Key_Control || key == Key_Alt || key == Key_Meta ) - return TQPopupMenu::keyPressEvent(e); - - // 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; - - TQString 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("&", TQString()); - - // chop text to the search length - thisText = thisText.left(seqLen); - - // do the search - if (!thisText.find(d->keySeq, 0, false)) { - - 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())); - - // remember 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 - } - - if (!firstpass) { - if (d->autoExec) { - // activate anything - activateItemAt(d->lastHitIndex); - resetKeyboardVars(); - - } else if (findItem(idAt(d->lastHitIndex)) && - findItem(idAt(d->lastHitIndex))->popup()) { - // only activate sub-menus - activateItemAt(d->lastHitIndex); - resetKeyboardVars(); - } - - return; - } - - // no matches whatsoever, clean up - resetKeyboardVars(true); - //e->ignore(); - TQPopupMenu::keyPressEvent(e); -} - -bool KPopupMenu::focusNextPrevChild( bool next ) -{ - resetKeyboardVars(); - return TQPopupMenu::focusNextPrevChild( next ); -} - -TQString KPopupMenu::underlineText(const TQString& text, uint length) -{ - TQString ret = text; - for (uint i = 0; i < length; i++) { - if (ret[2*i] != '&') - ret.insert(2*i, "&"); - } - return ret; -} - -void KPopupMenu::resetKeyboardVars(bool noMatches /* = false */) -{ - // Clean up keyboard variables - if (d->lastHitIndex != -1) { - changeItem(idAt(d->lastHitIndex), d->originalText); - d->lastHitIndex = -1; - } - - if (!noMatches) { - d->keySeq = TQString::null; - } - - d->noMatches = noMatches; -} - -void KPopupMenu::setKeyboardShortcutsEnabled(bool enable) -{ - d->shortcuts = enable; -} - -void KPopupMenu::setKeyboardShortcutsExecute(bool enable) -{ - d->autoExec = enable; -} -/** - * End keyboard navigation. - */ - -/** - * RMB menus on menus - */ - -void KPopupMenu::mousePressEvent(TQMouseEvent* e) -{ - if (d->m_ctxMenu && d->m_ctxMenu->isVisible()) - { - // hide on a second context menu event - d->m_ctxMenu->hide(); - } - - TQPopupMenu::mousePressEvent(e); -} - -void KPopupMenu::mouseReleaseEvent(TQMouseEvent* e) -{ - // Save the button, and the modifiers from state() - d->state = TQt::ButtonState(e->button() | (e->state() & KeyButtonMask)); - - if ( !d->m_ctxMenu || !d->m_ctxMenu->isVisible() ) - TQPopupMenu::mouseReleaseEvent(e); -} - -TQPopupMenu* KPopupMenu::contextMenu() -{ - if (!d->m_ctxMenu) - { - d->m_ctxMenu = new TQPopupMenu(this); - connect(d->m_ctxMenu, TQT_SIGNAL(aboutToHide()), this, TQT_SLOT(ctxMenuHiding())); - } - - return d->m_ctxMenu; -} - -const TQPopupMenu* KPopupMenu::contextMenu() const -{ - return const_cast< KPopupMenu* >( this )->contextMenu(); -} - -void KPopupMenu::hideContextMenu() -{ - KPopupMenuPrivate::s_continueCtxMenuShow = false; -} - -int KPopupMenu::contextMenuFocusItem() -{ - return KPopupMenuPrivate::s_highlightedItem; -} - -KPopupMenu* KPopupMenu::contextMenuFocus() -{ - return KPopupMenuPrivate::s_contextedMenu; -} - -void KPopupMenu::itemHighlighted(int /* whichItem */) -{ - if (!d->m_ctxMenu || !d->m_ctxMenu->isVisible()) - { - return; - } - - d->m_ctxMenu->hide(); - showCtxMenu(mapFromGlobal(TQCursor::pos())); -} - -void KPopupMenu::showCtxMenu(TQPoint pos) -{ - TQMenuItem* item = findItem(KPopupMenuPrivate::s_highlightedItem); - if (item) - { - TQPopupMenu* subMenu = item->popup(); - if (subMenu) - { - disconnect(subMenu, TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(ctxMenuHideShowingMenu())); - } - } - - KPopupMenuPrivate::s_highlightedItem = idAt(pos); - - if (KPopupMenuPrivate::s_highlightedItem == -1) - { - KPopupMenuPrivate::s_contextedMenu = 0; - return; - } - - emit aboutToShowContextMenu(this, KPopupMenuPrivate::s_highlightedItem, d->m_ctxMenu); - - TQPopupMenu* subMenu = findItem(KPopupMenuPrivate::s_highlightedItem)->popup(); - if (subMenu) - { - connect(subMenu, TQT_SIGNAL(aboutToShow()), TQT_SLOT(ctxMenuHideShowingMenu())); - TQTimer::singleShot(100, subMenu, TQT_SLOT(hide())); - } - - if (!KPopupMenuPrivate::s_continueCtxMenuShow) - { - KPopupMenuPrivate::s_continueCtxMenuShow = true; - return; - } - - KPopupMenuPrivate::s_contextedMenu = this; - d->m_ctxMenu->popup(this->mapToGlobal(pos)); - connect(this, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(itemHighlighted(int))); -} - -/* - * this method helps prevent submenus popping up while we have a context menu - * showing - */ -void KPopupMenu::ctxMenuHideShowingMenu() -{ - TQMenuItem* item = findItem(KPopupMenuPrivate::s_highlightedItem); - if (item) - { - TQPopupMenu* subMenu = item->popup(); - if (subMenu) - { - TQTimer::singleShot(0, subMenu, TQT_SLOT(hide())); - } - } -} - -void KPopupMenu::ctxMenuHiding() -{ - if (KPopupMenuPrivate::s_highlightedItem) - { - TQPopupMenu* subMenu = findItem(KPopupMenuPrivate::s_highlightedItem)->popup(); - if (subMenu) - { - disconnect(subMenu, TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(ctxMenuHideShowingMenu())); - } - } - - disconnect(this, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(itemHighlighted(int))); - KPopupMenuPrivate::s_continueCtxMenuShow = true; -} - -void KPopupMenu::contextMenuEvent(TQContextMenuEvent* e) -{ - if (d->m_ctxMenu) - { - if (e->reason() == TQContextMenuEvent::Mouse) - { - showCtxMenu(e->pos()); - } - else if (actItem != -1) - { - showCtxMenu(itemGeometry(actItem).center()); - } - - e->accept(); - return; - } - - TQPopupMenu::contextMenuEvent(e); -} - -void KPopupMenu::hideEvent(TQHideEvent*) -{ - if (d->m_ctxMenu && d->m_ctxMenu->isVisible()) - { - // we need to block signals here when the ctxMenu is showing - // to prevent the TQPopupMenu::activated(int) signal from emitting - // when hiding with a context menu, the user doesn't expect the - // menu to actually do anything. - // since hideEvent gets called very late in the process of hiding - // (deep within TQWidget::hide) the activated(int) signal is the - // last signal to be emitted, even after things like aboutToHide() - // AJS - blockSignals(true); - d->m_ctxMenu->hide(); - blockSignals(false); - } -} -/** - * end of RMB menus on menus support - */ - -// Obsolete -KPopupMenu::KPopupMenu(const TQString& title, TQWidget *parent, const char *name) - : TQPopupMenu(parent, name) -{ - d = new KPopupMenuPrivate; - insertTitle(title); -} - -// Obsolete -void KPopupMenu::setTitle(const TQString &title) -{ - KPopupTitle *titleItem = new KPopupTitle(); - titleItem->setTitle(title); - insertItem(titleItem); - d->m_lastTitle = title; -} - -void KPopupTitle::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -void KPopupMenu::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "kpopupmenu.moc" |