diff options
Diffstat (limited to 'src/frontend/keychooser/ckeychooserwidget.cpp')
-rw-r--r-- | src/frontend/keychooser/ckeychooserwidget.cpp | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/src/frontend/keychooser/ckeychooserwidget.cpp b/src/frontend/keychooser/ckeychooserwidget.cpp new file mode 100644 index 0000000..dd8f7a5 --- /dev/null +++ b/src/frontend/keychooser/ckeychooserwidget.cpp @@ -0,0 +1,304 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2008 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + + +//BibleTime includes +#include "ckeychooserwidget.h" + +#include "cscrollerwidgetset.h" + +//Qt includes +#include <QString> +#include <QWheelEvent> +#include <QFocusEvent> +#include <QHBoxLayout> +#include <QComboBox> +#include <QLineEdit> +#include <QDebug> + +CKCComboBox::CKCComboBox() +: QComboBox() { + setFocusPolicy(Qt::WheelFocus); + if (lineEdit()) { + installEventFilter( lineEdit() ); + } +} + +/** Reimplementation. */ +bool CKCComboBox::eventFilter( QObject *o, QEvent *e ) { + if (e->type() == QEvent::FocusOut) { + QFocusEvent* f = static_cast<QFocusEvent*>(e); + + if (o == lineEdit() && f->reason() == Qt::TabFocusReason) { + int index = findText(currentText()); + if (index == -1) { + index = 0;// return 0 if not found + } + setCurrentIndex( index ); + emit focusOut( index ); + + return false; + } + else if (f->reason() == Qt::PopupFocusReason) { + return false; + } + else if (f->reason() == Qt::ActiveWindowFocusReason) { + emit activated(currentText()); + return false; + } + else if (f->reason() == Qt::MouseFocusReason) { + emit activated(currentText()); + return false; + } + else if (o == this) { + emit activated(currentText()); + return false; + } + } + + return QComboBox::eventFilter(o,e); +} + +/** Scrolls in the list if the wheel of the mouse was used. */ +void CKCComboBox::wheelEvent( QWheelEvent* e ) { + return QComboBox::wheelEvent(e); + + const signed int change = (int)((float)e->delta()/(float)120); + int current = currentIndex(); + + if ((current+change >= 0) && (current+change<count()) ) { + setCurrentIndex(current+change); + e->accept(); + emit activated( currentIndex() ); + } + else { + e->ignore(); + } +} + +//**********************************************************************************/ + +CKeyChooserWidget::CKeyChooserWidget(int count, const bool useNextPrevSignals, QWidget *parent ) : QWidget(parent) { + m_useNextPrevSignals = useNextPrevSignals; + + for (int index=1; index <= count; index++) { + m_list.append( QString::number(index) ); + } + init(); + reset(m_list,0,false); +} + +CKeyChooserWidget::CKeyChooserWidget(QStringList *list, const bool useNextPrevSignals, QWidget *parent ) : QWidget(parent) { + m_useNextPrevSignals = useNextPrevSignals; + + if (list) { + m_list = *list; //deep copy the items of list + } + else { + m_list.clear(); + } + + init(); + reset(m_list,0,false); +} + +void CKeyChooserWidget::reset(const int count, int index, bool do_emit) { + //This prevents the widget from resetting during application load, which + //produces undesirable behavior. + //if (!updatesEnabled()) + // return; + + m_list.clear(); + for (int i=1; i <= count; i++) { //TODO: CHECK + m_list.append( QString::number(i) ); + } + + reset(&m_list,index,do_emit); +} + +void CKeyChooserWidget::reset(QStringList& list, int index, bool do_emit) { + //This prevents the widget from resetting during application load, which + //produces undesirable behavior. + //if (!updatesEnabled()) + // return; + + m_list = list; + reset(&m_list,index,do_emit); +} + + +void CKeyChooserWidget::reset(QStringList *list, int index, bool do_emit) { + //if (isResetting || !updatesEnabled()) + if (isResetting) + return; + + // qWarning("starting insert"); + isResetting = true; + + oldKey = QString::null; + + // m_comboBox->setUpdatesEnabled(false); + //DON'T REMOVE THE HIDE: Otherwise QComboBox's sizeHint() function won't work properly + m_comboBox->hide(); + m_comboBox->clear(); + if (list) { + m_comboBox->insertItems(-1, *list); + } + + if (!list || (list && !list->count())) { //nothing in the combobox + setEnabled(false); + } + else if (!isEnabled()) { //was disabled + setEnabled(true); + } + + if (list->count()) { + m_comboBox->setCurrentIndex(index); + } + if (do_emit) { + emit changed(m_comboBox->currentIndex()); + } + + const QSize dummySize = m_comboBox->sizeHint(); //without this function call the combo box won't be properly sized! + //DON'T REMOVE OR MOVE THE show()! Otherwise QComboBox's sizeHint() function won't work properly! + m_comboBox->show(); + + // m_comboBox->setFont( m_comboBox->font() ); + // m_comboBox->setUpdatesEnabled(true); + + isResetting = false; + // qWarning("inserted"); +} + +/** Initializes this widget. We need this function because we have more than one constructor. */ +void CKeyChooserWidget::init() { + qDebug("CKeyChooserWidget::init"); + oldKey = QString::null; + + setFocusPolicy(Qt::WheelFocus); + + m_comboBox = new CKCComboBox(); + m_comboBox->setAutoCompletion( true ); + m_comboBox->setEditable(true); + m_comboBox->setInsertPolicy(QComboBox::NoInsert); + m_comboBox->setFocusPolicy(Qt::WheelFocus); + + m_mainLayout = new QHBoxLayout( this ); + m_mainLayout->setSpacing(0); + m_mainLayout->setContentsMargins(0,0,0,0); + m_mainLayout->addWidget(m_comboBox); + + m_scroller = new CScrollerWidgetSet(this); + + m_mainLayout->addWidget( m_scroller ); + m_mainLayout->addSpacing(0); + + setTabOrder(m_comboBox, 0); + + connect(m_scroller, SIGNAL(scroller_pressed()), SLOT(lock())); + connect(m_scroller, SIGNAL(scroller_released()), SLOT(unlock())); + connect(m_scroller, SIGNAL(change(int)), SLOT(changeCombo(int)) ); + + connect(m_comboBox, SIGNAL(activated(int)), SLOT(slotComboChanged(int))); + // connect(m_comboBox, SIGNAL(activated(const QString&)), SLOT(slotReturnPressed(const QString&))); + connect(m_comboBox->lineEdit(), SIGNAL(returnPressed()), SLOT(slotReturnPressed())); + connect(m_comboBox, SIGNAL(focusOut(int)), SIGNAL(focusOut(int))); + + updatelock = false; + isResetting = false; +} + +/** Is called when the return key was presed in the combobox. */ +void CKeyChooserWidget::slotReturnPressed( /*const QString& text*/) { + Q_ASSERT(comboBox()->lineEdit()); + qDebug("return pressed"); + + QString text = comboBox()->lineEdit()->text(); + for (int index = 0; index < comboBox()->count(); ++index) { + if (comboBox()->itemText(index) == text) { +// emit changed(index); + emit focusOut(index); // a workaround because focusOut is not checked, the slot connected to changed to check + break; + } + } +} + +/** Is called when the current item of the combo box was changed. */ +void CKeyChooserWidget::slotComboChanged(int index) { + qDebug("CKeyChooserWidget::slotComboChanged(int index)"); + if (!updatesEnabled()) { + return; + } + + setUpdatesEnabled(false); + + const QString key = comboBox()->itemText( index ); + if (oldKey.isNull() || (oldKey != key)) { + emit changed(index); + } + + oldKey = key; + + setUpdatesEnabled(true); +} + +/** Sets the tooltips for the given entries using the parameters as text. */ +void CKeyChooserWidget::setToolTips( const QString comboTip, const QString nextEntryTip, const QString scrollButtonTip, const QString previousEntryTip) { + comboBox()->setToolTip(comboTip); + m_scroller->setToolTips(nextEntryTip, scrollButtonTip, previousEntryTip); +} + +/** Sets the current item to the one with the given text */ +bool CKeyChooserWidget::setItem( const QString item ) { + bool ret = false; + const int count = comboBox()->count(); + for (int i = 0; i < count; ++i) { + if (comboBox()->itemText(i) == item) { + comboBox()->setCurrentIndex(i); + ret = true; + break; + } + } + if (!ret) + comboBox()->setCurrentIndex(-1); + return ret; +} + +/* Handlers for the various scroller widgetset. */ +void CKeyChooserWidget::lock() { + updatelock = true; + comboBox()->setEditable(false); + oldKey = comboBox()->currentText(); +} + +void CKeyChooserWidget::unlock() { + updatelock = false; + comboBox()->setEditable(true); + comboBox()->setEditText(comboBox()->itemText(comboBox()->currentIndex())); + if (comboBox()->currentText() != oldKey) { + emit changed(comboBox()->currentIndex()); + } +} + +void CKeyChooserWidget::changeCombo(int n) { + const int old_index = comboBox()->currentIndex(); + int new_index = old_index + n; + + //index of highest Item + const int max = comboBox()->count()-1; + if(new_index > max) new_index = max; + if(new_index < 0) new_index = 0; + + if(new_index != old_index) { + comboBox()->setCurrentIndex(new_index); + if(!updatelock) + emit changed(new_index); + } +} + |