summaryrefslogtreecommitdiffstats
path: root/klipper/klipperpopup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'klipper/klipperpopup.cpp')
-rw-r--r--klipper/klipperpopup.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/klipper/klipperpopup.cpp b/klipper/klipperpopup.cpp
new file mode 100644
index 000000000..41eabdbdf
--- /dev/null
+++ b/klipper/klipperpopup.cpp
@@ -0,0 +1,304 @@
+// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*-
+/* This file is part of the KDE project
+ Copyright (C) 2004 Esben Mose Hansen <[email protected]>
+ Copyright (C) by Andrew Stanley-Jones
+ Copyright (C) 2000 by Carsten Pfeiffer <[email protected]>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#include <tdemessagebox.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <klineedit.h>
+
+#include <tdelocale.h>
+#include <tdeaction.h>
+#include <tdeglobalsettings.h>
+#include <twin.h>
+#include <tdeapplication.h>
+#include <tdeglobalsettings.h>
+#include <kdebug.h>
+
+#include "klipperpopup.h"
+#include "history.h"
+#include "toplevel.h"
+#include "popupproxy.h"
+
+namespace {
+ static const int TOP_HISTORY_ITEM_INDEX = 2;
+}
+
+// #define DEBUG_EVENTS__
+
+#ifdef DEBUG_EVENTS__
+kdbgstream& operator<<( kdbgstream& stream, const TQKeyEvent& e ) {
+ stream << "(TQKeyEvent(text=" << e.text() << ",key=" << e.key() << ( e.isAccepted()?",accepted":",ignored)" ) << ",count=" << e.count();
+ if ( e.state() & Qt::AltButton ) {
+ stream << ",ALT";
+ }
+ if ( e.state() & Qt::ControlButton ) {
+ stream << ",CTRL";
+ }
+ if ( e.state() & Qt::MetaButton ) {
+ stream << ",META";
+ }
+ if ( e.state() & Qt::ShiftButton ) {
+ stream << ",SHIFT";
+ }
+ if ( e.isAutoRepeat() ) {
+ stream << ",AUTOREPEAT";
+ }
+ stream << ")";
+
+ return stream;
+}
+#endif
+
+/**
+ * Exactly the same as KLineEdit, except that ALL key events are swallowed.
+ *
+ * We need this to avoid infinite loop when sending events to the search widget
+ */
+class KLineEditBlackKey : public KLineEdit {
+public:
+ KLineEditBlackKey(const TQString& string, TQWidget* parent, const char* name )
+ : KLineEdit( string, parent, name )
+ {}
+
+ KLineEditBlackKey( TQWidget* parent, const char* name )
+ : KLineEdit( parent, name )
+ {}
+
+ ~KLineEditBlackKey() {
+ }
+protected:
+ virtual void keyPressEvent( TQKeyEvent* e ) {
+ KLineEdit::keyPressEvent( e );
+ e->accept();
+
+ }
+
+};
+
+KlipperPopup::KlipperPopup( History* history, TQWidget* parent, const char* name )
+ : TDEPopupMenu( parent, name ),
+ m_dirty( true ),
+ QSempty( i18n( "<empty clipboard>" ) ),
+ QSnomatch( i18n( "<no matches>" ) ),
+ m_history( history ),
+ helpmenu( new KHelpMenu( this, KlipperWidget::aboutData(), false ) ),
+ m_popupProxy( 0 ),
+ m_filterWidget( 0 ),
+ m_filterWidgetId( 10 ),
+ n_history_items( 0 )
+{
+ KWin::WindowInfo i = KWin::windowInfo( winId(), NET::WMGeometry );
+ TQRect g = i.geometry();
+ TQRect screen = TDEGlobalSettings::desktopGeometry(g.center());
+ int menu_height = ( screen.height() ) * 3/4;
+ int menu_width = ( screen.width() ) * 1/3;
+
+ m_popupProxy = new PopupProxy( this, "popup_proxy", menu_height, menu_width );
+
+ connect( this, TQT_SIGNAL( aboutToShow() ), TQT_SLOT( slotAboutToShow() ) );
+}
+
+KlipperPopup::~KlipperPopup() {
+
+}
+
+void KlipperPopup::slotAboutToShow() {
+ if ( m_filterWidget ) {
+ if ( !m_filterWidget->text().isEmpty() ) {
+ m_dirty = true;
+ m_filterWidget->clear();
+ setItemVisible( m_filterWidgetId, false );
+ m_filterWidget->hide();
+ }
+ }
+ ensureClean();
+
+}
+
+void KlipperPopup::ensureClean() {
+ // If the history is unchanged since last menu build, the is no reason
+ // to rebuild it,
+ if ( m_dirty ) {
+ rebuild();
+ }
+
+}
+
+void KlipperPopup::buildFromScratch() {
+ m_filterWidget = new KLineEditBlackKey( this, "Klipper filter widget" );
+ insertTitle( SmallIcon( "klipper" ), i18n("Klipper - Clipboard Tool"));
+ m_filterWidgetId = insertItem( m_filterWidget, m_filterWidgetId, 1 );
+ m_filterWidget->setFocusPolicy( TQ_NoFocus );
+ setItemVisible( m_filterWidgetId, false );
+ m_filterWidget->hide();
+ TQString lastGroup;
+
+ // Bit of a hack here. It would be better of KHelpMenu could be an action.
+ // Insert Help-menu at the butttom of the "default" group.
+ TQString group;
+ TQString defaultGroup( "default" );
+ for ( TDEAction* action = m_actions.first(); action; action = m_actions.next() ) {
+ group = action->group();
+ if ( group != lastGroup ) {
+ if ( lastGroup == defaultGroup ) {
+ insertItem( SmallIconSet("help"), KStdGuiItem::help().text(), helpmenu->menu() );
+ }
+ insertSeparator();
+ }
+ lastGroup = group;
+ action->plug( this, -1 );
+ }
+
+ if ( TDEGlobalSettings::insertTearOffHandle() ) {
+ insertTearOffHandle();
+ }
+
+}
+
+void KlipperPopup::rebuild( const TQString& filter ) {
+
+ bool from_scratch = ( count() == 0 );
+ if ( from_scratch ) {
+ buildFromScratch();
+ } else {
+ for ( int i=0; i<n_history_items; i++ ) {
+ removeItemAt( TOP_HISTORY_ITEM_INDEX );
+ }
+ }
+
+ TQRegExp filterexp( filter );
+ if ( filterexp.isValid() ) {
+ m_filterWidget->setPaletteForegroundColor( paletteForegroundColor() );
+ } else {
+ m_filterWidget->setPaletteForegroundColor( TQColor( "red" ) );
+ }
+ n_history_items = m_popupProxy->buildParent( TOP_HISTORY_ITEM_INDEX, filterexp );
+
+ if ( n_history_items == 0 ) {
+ if ( m_history->empty() ) {
+ insertItem( QSempty, -1, TOP_HISTORY_ITEM_INDEX );
+ } else {
+ insertItem( QSnomatch, -1, TOP_HISTORY_ITEM_INDEX );
+ }
+ n_history_items++;
+ } else {
+ if ( history()->topIsUserSelected() ) {
+ int id = idAt( TOP_HISTORY_ITEM_INDEX );
+ if ( id != -1 ) {
+ setItemChecked( id,true );
+ }
+ }
+ }
+
+
+ m_dirty = false;
+
+}
+
+void KlipperPopup::plugAction( TDEAction* action ) {
+ m_actions.append( action );
+}
+
+
+
+
+/* virtual */
+void KlipperPopup::keyPressEvent( TQKeyEvent* e ) {
+ // If alt-something is pressed, select a shortcut
+ // from the menu. Do this by sending a keyPress
+ // without the alt-modifier to the superobject.
+ if ( e->state() & AltButton ) {
+ TQKeyEvent ke( TQEvent::KeyPress,
+ e->key(),
+ e->ascii(),
+ e->state() ^ AltButton,
+ e->text(),
+ e->isAutoRepeat(),
+ e->count() );
+ TDEPopupMenu::keyPressEvent( &ke );
+#ifdef DEBUG_EVENTS__
+ kdDebug() << "Passing this event to ancestor (TDEPopupMenu): " << e "->" << ke << endl;
+#endif
+ if ( ke.isAccepted() ) {
+ e->accept();
+ return;
+ } else {
+ e->ignore();
+ }
+ }
+
+ // Otherwise, send most events to the search
+ // widget, except a few used for navigation:
+ // These go to the superobject.
+ switch( e->key() ) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Right:
+ case Qt::Key_Left:
+ case Qt::Key_Tab:
+ case Qt::Key_Backtab:
+ case Qt::Key_Escape:
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ {
+#ifdef DEBUG_EVENTS__
+ kdDebug() << "Passing this event to ancestor (TDEPopupMenu): " << e << endl;
+#endif
+ TDEPopupMenu::keyPressEvent( e );
+ if ( isItemActive( m_filterWidgetId ) ) {
+ setActiveItem( TOP_HISTORY_ITEM_INDEX );
+ }
+ break;
+ }
+ default:
+ {
+#ifdef DEBUG_EVENTS__
+ kdDebug() << "Passing this event down to child (KLineEdit): " << e << endl;
+#endif
+ TQString lastString = m_filterWidget->text();
+ TQApplication::sendEvent( m_filterWidget, e );
+ if ( m_filterWidget->text().isEmpty() ) {
+ if ( isItemVisible( m_filterWidgetId ) )
+ {
+ setItemVisible( m_filterWidgetId, false );
+ m_filterWidget->hide();
+ }
+ }
+ else if ( !isItemVisible( m_filterWidgetId ) )
+ {
+ setItemVisible( m_filterWidgetId, true );
+ m_filterWidget->show();
+
+ }
+ if ( m_filterWidget->text() != lastString) {
+ slotHistoryChanged();
+ rebuild( m_filterWidget->text() );
+ }
+ break;
+
+ } //default:
+ } //case
+
+}
+
+
+
+#include "klipperpopup.moc"