summaryrefslogtreecommitdiffstats
path: root/kmymoney2/widgets/kmymoneycompletion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmymoney2/widgets/kmymoneycompletion.cpp')
-rw-r--r--kmymoney2/widgets/kmymoneycompletion.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/kmymoney2/widgets/kmymoneycompletion.cpp b/kmymoney2/widgets/kmymoneycompletion.cpp
new file mode 100644
index 0000000..f9bc7a3
--- /dev/null
+++ b/kmymoney2/widgets/kmymoneycompletion.cpp
@@ -0,0 +1,304 @@
+/***************************************************************************
+ kmymoneycompletion.cpp - description
+ -------------------
+ begin : Mon Apr 26 2004
+ copyright : (C) 2000-2004 by Michael Edwardes
+ email : mte@users.sourceforge.net
+ Javier Campos Morales <javi_c@users.sourceforge.net>
+ Felix Rodriguez <frodriguez@users.sourceforge.net>
+ John C <thetacoturtle@users.sourceforge.net>
+ Thomas Baumgart <ipwizard@users.sourceforge.net>
+ Kevin Tambascio <ktambascio@users.sourceforge.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// ----------------------------------------------------------------------------
+// QT Includes
+
+#include <qapplication.h>
+
+// ----------------------------------------------------------------------------
+// KDE Includes
+
+#include <klistview.h>
+
+// ----------------------------------------------------------------------------
+// Project Includes
+
+#include "kmymoneycompletion.h"
+#include <kmymoney/kmymoneyselector.h>
+#include <kmymoney/kmymoneylistviewitem.h>
+#include "./kmymoneycombo.h"
+
+const int kMyMoneyCompletion::MAX_ITEMS = 16;
+
+kMyMoneyCompletion::kMyMoneyCompletion(QWidget *parent, const char *name ) :
+ QVBox(parent, name, WType_Popup)
+{
+ m_selector = new KMyMoneySelector(this);
+ m_selector->listView()->setFocusProxy(this);
+
+ m_parent = parent;
+ setFocusProxy((parent) ? parent : (QWidget*) NoFocus);
+ setFrameStyle(QFrame::PopupPanel | QFrame::Raised);
+ connectSignals(m_selector, m_selector->listView());
+}
+
+void kMyMoneyCompletion::connectSignals(QWidget* widget, KListView* lv)
+{
+ m_widget = widget;
+ m_lv = lv;
+ connect(lv, SIGNAL(executed(QListViewItem*,const QPoint&,int)), this, SLOT(slotItemSelected(QListViewItem*,const QPoint&,int)));
+}
+
+kMyMoneyCompletion::~kMyMoneyCompletion()
+{
+}
+
+void kMyMoneyCompletion::adjustSize(void)
+{
+ QListViewItemIterator it(m_lv, QListViewItemIterator::Visible);
+ int count = 0;
+ while(it.current()) {
+ ++count;
+ ++it;
+ }
+ adjustSize(count);
+}
+
+void kMyMoneyCompletion::adjustSize(const int count)
+{
+ int w = m_widget->sizeHint().width();
+ if(m_parent && w < m_parent->width())
+ w = m_parent->width();
+
+ QFontMetrics fm(font());
+ if(w < fm.maxWidth()*15)
+ w = fm.maxWidth()*15;
+
+ int h = 0;
+ QListViewItemIterator it(m_lv, QListViewItemIterator::Visible);
+ QListViewItem* item = it.current();
+ if(item)
+ h = item->height() * (count > MAX_ITEMS ? MAX_ITEMS : count);
+
+ // the offset of 4 in the next statement avoids the
+ // display of a scroll bar if count < MAX_ITEMS.
+ resize(w, h+4);
+
+ if(m_parent) {
+ // the code of this basic block is taken from KCompletionBox::show()
+ // and modified to our local needs
+
+ // this is probably better, once kde switches to requiring qt3.1
+ // QRect screenSize = QApplication::desktop()->availableGeometry(d->m_parent);
+ // for now use this since it's qt3.0.x-safe
+ QRect screenSize = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_parent));
+
+ QPoint orig = m_parent->mapToGlobal( QPoint(0, m_parent->height()) );
+ int x = orig.x();
+ int y = orig.y();
+
+ if ( x + width() > screenSize.right() )
+ x = screenSize.right() - width();
+
+ // check for the maximum height here to avoid flipping
+ // of the completion box from top to bottom of the
+ // edit widget. The offset (y) is certainly based
+ // on the actual height.
+ if(item) {
+ if ((y + item->height()*MAX_ITEMS) > screenSize.bottom() )
+ y = y - height() - m_parent->height();
+ }
+
+ move( x, y);
+ }
+}
+
+void kMyMoneyCompletion::show(bool presetSelected)
+{
+ if(!m_id.isEmpty() && presetSelected)
+ m_selector->setSelected(m_id);
+
+ adjustSize();
+
+ if(m_parent) {
+ m_parent->installEventFilter(this);
+ // make sure to install the filter for the combobox lineedit as well
+ // We have do this here because QObject::installEventFilter() is not
+ // declared virtual and we have no chance to override it in KMyMoneyCombo
+ KMyMoneyCombo* c = dynamic_cast<KMyMoneyCombo*>(m_parent);
+ if(c && c->lineEdit()) {
+ c->lineEdit()->installEventFilter(this);
+ }
+ }
+
+ QVBox::show();
+}
+
+void kMyMoneyCompletion::hide(void)
+{
+ if(m_parent) {
+ m_parent->removeEventFilter(this);
+ // make sure to uninstall the filter for the combobox lineedit as well
+ // We have do this here because QObject::installEventFilter() is not
+ // declared virtual and we have no chance to override it in KMyMoneyCombo
+ KMyMoneyCombo* c = dynamic_cast<KMyMoneyCombo*>(m_parent);
+ if(c && c->lineEdit()) {
+ c->lineEdit()->removeEventFilter(this);
+ }
+ }
+ QVBox::hide();
+}
+
+bool kMyMoneyCompletion::eventFilter(QObject* o, QEvent* e)
+{
+ int type = e->type();
+
+ KMyMoneyCombo *c = dynamic_cast<KMyMoneyCombo*>(m_parent);
+ QListViewItem* item;
+ if(o == m_parent || (c && o == c->lineEdit())) {
+ if(isVisible()) {
+ if(type == QEvent::KeyPress) {
+ QKeyEvent* ev = static_cast<QKeyEvent*> (e);
+ QKeyEvent evt(QEvent::KeyPress,
+ Key_Down, 0, ev->state(), QString::null,
+ ev->isAutoRepeat(), ev->count());
+ QKeyEvent evbt(QEvent::KeyPress,
+ Key_Up, 0, ev->state(), QString::null,
+ ev->isAutoRepeat(), ev->count());
+
+ switch(ev->key()) {
+ case Key_Tab:
+ case Key_BackTab:
+ slotItemSelected(m_lv->currentItem(), QPoint(0,0), 0);
+ break;
+
+ case Key_Down:
+ case Key_Next:
+ item = m_lv->currentItem();
+ while(item) {
+ item = item->itemBelow();
+ if(item && selector()->match(m_lastCompletion, item))
+ break;
+ }
+ if(item) {
+ m_lv->setCurrentItem(item);
+ selector()->ensureItemVisible(item);
+ }
+ ev->accept();
+ return true;
+
+ case Key_Up:
+ case Key_Prior:
+ item = m_lv->currentItem();
+ while(item) {
+ item = item->itemAbove();
+ if(item && selector()->match(m_lastCompletion, item))
+ break;
+ }
+ if(item) {
+ m_lv->setCurrentItem(item);
+ // make sure, we always see a possible (non-selectable) group item
+ if(item->itemAbove())
+ item = item->itemAbove();
+ selector()->ensureItemVisible(item);
+ }
+ ev->accept();
+ return true;
+
+ case Key_Escape:
+ hide();
+ ev->accept();
+ return true;
+
+ case Key_Enter:
+ case Key_Return:
+ slotItemSelected(m_lv->currentItem(), QPoint(0,0), 0);
+ ev->accept();
+ return true;
+
+ case Key_Home:
+ case Key_End:
+ if(ev->state() & ControlButton) {
+ item = m_lv->currentItem();
+ if(ev->key() == Key_Home) {
+ while(item && item->itemAbove()) {
+ item = item->itemAbove();
+ }
+ while(item && !selector()->match(m_lastCompletion, item)) {
+ item = item->itemBelow();
+ }
+ } else {
+ while(item && item->itemBelow()) {
+ item = item->itemBelow();
+ }
+ while(item && !selector()->match(m_lastCompletion, item)) {
+ item = item->itemAbove();
+ }
+ }
+ if(item) {
+ m_lv->setCurrentItem(item);
+ // make sure, we always see a possible (non-selectable) group item
+ if(item->itemAbove())
+ item = item->itemAbove();
+ selector()->ensureItemVisible(item);
+ }
+ ev->accept();
+ return true;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+ }
+ }
+ }
+ return QVBox::eventFilter(o, e);
+}
+
+void kMyMoneyCompletion::slotMakeCompletion(const QString& txt)
+{
+ int cnt = selector()->slotMakeCompletion(txt.stripWhiteSpace());
+
+ if(m_parent && m_parent->isVisible() && !isVisible() && cnt)
+ show(false);
+ else {
+ if(cnt != 0) {
+ adjustSize();
+ } else {
+ hide();
+ }
+ }
+}
+
+void kMyMoneyCompletion::slotItemSelected(QListViewItem *item, const QPoint&, int)
+{
+ KMyMoneyListViewItem* it_v = static_cast<KMyMoneyListViewItem*>(item);
+ if(it_v && it_v->isSelectable()) {
+ QString id = it_v->id();
+ // hide the widget, so we can debug the slots that are connect
+ // to the signal we emit very soon
+ hide();
+ m_id = id;
+ emit itemSelected(id);
+ }
+}
+
+void kMyMoneyCompletion::setSelected(const QString& id)
+{
+ m_id = id;
+ m_selector->setSelected(id, true);
+}
+
+#include "kmymoneycompletion.moc"