20#include "kexidbcombobox.h"
21#include "kexidblineedit.h"
22#include "../kexiformscrollview.h"
26#include <tdeapplication.h>
28#include <tqmetaobject.h>
31#include <tqdrawutil.h>
35#include <kexidb/queryschema.h>
36#include <widget/tableview/kexicomboboxpopup.h>
37#include <widget/tableview/kexicelleditorfactory.h>
38#include <kexiutils/utils.h>
41class KexiDBComboBox::Private
46 , visibleColumnInfo(0)
47 , subWidgetsWithDisabledEvents(0)
49 , buttonPressed(false)
51 , dataEnteredByHand(true)
56 delete subWidgetsWithDisabledEvents;
57 subWidgetsWithDisabledEvents = 0;
60 KexiComboBoxPopup *popup;
61 KComboBox *paintedCombo;
64 KexiDB::QueryColumnInfo* visibleColumnInfo;
65 TQPtrDict<char> *subWidgetsWithDisabledEvents;
67 bool buttonPressed : 1;
69 bool dataEnteredByHand : 1;
75KexiDBComboBox::KexiDBComboBox(TQWidget *parent,
const char *name,
bool designMode)
80 setMouseTracking(
true);
81 setFocusPolicy(TQWidget::WheelFocus);
82 installEventFilter(
this);
83 d->designMode = designMode;
84 d->paintedCombo =
new KComboBox(
this);
85 d->paintedCombo->hide();
86 d->paintedCombo->move(0,0);
89KexiDBComboBox::~KexiDBComboBox()
104void KexiDBComboBox::setEditable(
bool set)
106 if (d->isEditable == set)
109 d->paintedCombo->setEditable(set);
119bool KexiDBComboBox::isEditable()
const
121 return d->isEditable;
127 TQColorGroup cg( palette().active() );
134 TQStyle::SFlags flags = TQStyle::Style_Default;
136 flags |= TQStyle::Style_Enabled;
138 flags |= TQStyle::Style_HasFocus;
140 flags |= TQStyle::Style_MouseOver;
142 if ( width() < 5 || height() < 5 ) {
143 qDrawShadePanel( &p, rect(), cg,
false, 2, &cg.brush( TQColorGroup::Button ) );
149 style().drawComplexControl( TQStyle::CC_ComboBox, &p, d->paintedCombo , rect(), cg,
150 flags, (uint)TQStyle::SC_All,
151 (d->buttonPressed ? TQStyle::SC_ComboBoxArrow : TQStyle::SC_None )
160 if (0==qstrcmp(style().name(),
"windows"))
161 p.fillRect(
editorGeometry, cg.brush( TQColorGroup::Highlight ) );
162 TQRect r( TQStyle::visualRect( style().subRect( TQStyle::SR_ComboBoxFocusRect, d->paintedCombo ),
this ) );
163 r = TQRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2);
164 style().drawPrimitive( TQStyle::PE_FocusRect, &p,
165 r, cg, flags | TQStyle::Style_FocusAtBorder, TQStyleOption(cg.highlight()));
173 TQRect r( TQStyle::visualRect(
174 style().querySubControlMetrics(TQStyle::CC_ComboBox, d->paintedCombo,
175 TQStyle::SC_ComboBoxEditField), d->paintedCombo ) );
187 if (!d->isEditable) {
188 m_subwidget->setCursor(TQCursor(TQt::ArrowCursor));
189 TQPalette subwidgetPalette( m_subwidget->palette() );
190 subwidgetPalette.setColor(TQPalette::Active, TQColorGroup::Base,
191 subwidgetPalette.color(TQPalette::Active, TQColorGroup::Button));
192 m_subwidget->setPalette( subwidgetPalette );
193 if (d->subWidgetsWithDisabledEvents)
194 d->subWidgetsWithDisabledEvents->clear();
196 d->subWidgetsWithDisabledEvents =
new TQPtrDict<char>();
197 d->subWidgetsWithDisabledEvents->insert(m_subwidget, (
char*)1);
198 m_subwidget->installEventFilter(
this);
199 TQObjectList *l = m_subwidget->queryList(
"TQWidget" );
200 for ( TQObjectListIt it( *l ); it.current(); ++it ) {
201 d->subWidgetsWithDisabledEvents->insert(it.current(), (
char*)1);
202 it.current()->installEventFilter(
this);
210void KexiDBComboBox::setLabelPosition(LabelPosition position)
213 if (-1 != m_subwidget->metaObject()->findProperty(
"frameShape",
true))
214 m_subwidget->setProperty(
"frameShape", TQVariant((
int)TQFrame::NoFrame));
220 TQSizePolicy sizePolicy( this->sizePolicy() );
222 sizePolicy.setHorData( TQSizePolicy::Minimum );
224 sizePolicy.setVerData( TQSizePolicy::Minimum );
226 setSizePolicy(sizePolicy);
231TQRect KexiDBComboBox::buttonGeometry()
const
234 style().querySubControlMetrics( TQStyle::CC_ComboBox, d->paintedCombo, TQStyle::SC_ComboBoxArrow) );
235 arrowRect = TQStyle::visualRect(arrowRect, d->paintedCombo);
236 arrowRect.setHeight( TQMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) );
240bool KexiDBComboBox::handleMousePressEvent(TQMouseEvent *e)
242 if ( e->button() != TQt::LeftButton || d->designMode )
249 if ( ( !isEditable() || buttonGeometry().contains( e->pos() ) ) ) {
250 d->buttonPressed =
false;
270bool KexiDBComboBox::handleKeyPressEvent(TQKeyEvent *ke)
272 const int k = ke->key();
273 const bool dropDown = (ke->state() == TQt::NoButton && ((k==TQt::Key_F2 && !d->isEditable) || k==TQt::Key_F4))
274 || (ke->state() == TQt::AltButton && k==TQt::Key_Down);
275 const bool escPressed = ke->state() == TQt::NoButton && k==TQt::Key_Escape;
276 const bool popupVisible = popup() && popup()->isVisible();
277 if ((dropDown || escPressed) && popupVisible) {
281 else if (dropDown && !popupVisible) {
282 d->buttonPressed =
false;
286 else if (popupVisible) {
287 const bool enterPressed = k==TQt::Key_Enter || k==TQt::Key_Return;
289 acceptPopupSelection();
292 return handleKeyPressForPopup( ke );
303 const int k = ke->key();
304 const bool popupVisible = popup() && popup()->isVisible();
305 const bool escPressed = ke->state() == TQt::NoButton && k==TQt::Key_Escape;
306 if (escPressed && popupVisible) {
310 if (ke->state() == TQt::NoButton && (k==TQt::Key_PageDown || k==TQt::Key_PageUp) && popupVisible)
315void KexiDBComboBox::mousePressEvent( TQMouseEvent *e )
317 if (handleMousePressEvent(e))
323 KexiDBAutoField::mousePressEvent( e );
326void KexiDBComboBox::mouseDoubleClickEvent( TQMouseEvent *e )
328 mousePressEvent( e );
331bool KexiDBComboBox::eventFilter( TQObject *o, TQEvent *e )
334 if (e->type()==TQEvent::Resize) {
335 d->paintedCombo->resize(size());
339 else if (e->type()==TQEvent::Enter) {
341 || buttonGeometry().contains(
static_cast<TQMouseEvent*
>(e)->pos() ))
347 else if (e->type()==TQEvent::MouseMove) {
349 const bool overButton = buttonGeometry().contains(
static_cast<TQMouseEvent*
>(e)->pos() );
350 if (overButton != d->mouseOver) {
351 d->mouseOver = overButton;
356 else if (e->type()==TQEvent::Leave) {
357 d->mouseOver =
false;
360 else if (e->type()==TQEvent::KeyPress) {
362 if (handleKeyPressEvent(
static_cast<TQKeyEvent*
>(e)))
365 else if (e->type()==TQEvent::FocusOut) {
366 if (popup() && popup()->isVisible()) {
372 else if (!d->isEditable && d->subWidgetsWithDisabledEvents && d->subWidgetsWithDisabledEvents->find(o)) {
373 if (e->type()==TQEvent::MouseButtonPress) {
375 if (handleMousePressEvent(
static_cast<TQMouseEvent*
>(e)))
378 else if (e->type()==TQEvent::KeyPress) {
379 if (handleKeyPressEvent(
static_cast<TQKeyEvent*
>(e)))
382 return e->type()!=TQEvent::Paint;
384 return KexiDBAutoField::eventFilter( o, e );
387bool KexiDBComboBox::subwidgetStretchRequired(
KexiDBAutoField* autoField)
const
396 TQPalette pal(palette());
397 TQColorGroup cg(pal.active());
398 pal.setColor(TQColorGroup::Base, red);
399 pal.setColor(TQColorGroup::Background, red);
401 TQWidget::setPalette(pal);
407 kdDebug() <<
"KexiDataItemInterface::valueChanged(): " << m_origValue.toString() <<
" ? " <<
value().toString() << endl;
408 return m_origValue !=
value();
419 d->visibleColumnInfo = cinfo;
426 return d->visibleColumnInfo;
431 if (d->isEditable && m_moveCursorToEndInInternalEditor_enabled)
437 if (d->isEditable && m_selectAllInInternalEditor_enabled)
452 KexiFormDataItemInterface *iface =
dynamic_cast<KexiFormDataItemInterface*
>((TQWidget*)m_subwidget);
459 return KexiComboBoxBase::visibleValue();
464 if (!m_setValueInInternalEditor_enabled)
466 KexiFormDataItemInterface *iface =
dynamic_cast<KexiFormDataItemInterface*
>((TQWidget*)m_subwidget);
480 return TQPoint(-1,-1);
481 return parentWidget()->mapToGlobal(pos);
492 d->sizeHint = TQSize();
493 KexiDBAutoField::fontChange(oldFont);
498 KexiDBAutoField::styleChange( oldStyle );
499 d->sizeHint = TQSize();
504TQSize KexiDBComboBox::sizeHint()
const
506 if ( isVisible() && d->sizeHint.isValid() )
509 const int maxWidth = 7 * fontMetrics().width(TQChar(
'x')) + 18;
510 const int maxHeight = TQMAX( fontMetrics().lineSpacing(), 14 ) + 2;
511 d->sizeHint = (style().sizeFromContents(TQStyle::CT_ComboBox, d->paintedCombo,
512 TQSize(maxWidth, maxHeight)).expandedTo(TQApplication::globalStrut()));
526void KexiDBComboBox::slotRowAccepted(KexiTableItem *item,
int row)
528 d->dataEnteredByHand =
false;
530 d->dataEnteredByHand =
true;
535 if (d->dataEnteredByHand) {
536 KexiFormDataItemInterface *iface =
dynamic_cast<KexiFormDataItemInterface*
>((TQWidget*)m_subwidget);
538 slotInternalEditorValueChanged( iface->
value() );
549#include "kexidbcombobox.moc"
A base class for handling data-aware combo boxes. This class is used by KexiComboBoxTableEdit and Kex...
virtual void slotRowAccepted(KexiTableItem *item, int row)
Call this from slot.
virtual void setValueInternal(const TQVariant &add, bool removeOld)
void undoChanges()
Used by KexiDBComboBox.
Universal "Auto Field" widget for Kexi forms.
virtual void moveCursorToEnd()
Implemented for KexiDataItemInterface.
virtual TQVariant value()
const TQColor & paletteBackgroundColor() const
Reimplemented to return internal editor's color.
virtual bool keyPressed(TQKeyEvent *ke)
virtual void setPaletteBackgroundColor(const TQColor &color)
Reimplemented to set internal editor's color.
virtual void createEditor()
virtual void selectAll()
Implemented for KexiDataItemInterface.
void setColumnInfoInternal(KexiDB::QueryColumnInfo *cinfo, KexiDB::QueryColumnInfo *visibleColumnInfo)
Used by KexiDBAutoField::setColumnInfo() and KexiDBComboBox::setColumnInfo().
virtual TQVariant value()
virtual bool keyPressed(TQKeyEvent *ke)
virtual void setValueInternal(const TQVariant &add, bool removeOld)
virtual void setVisibleColumnInfo(KexiDB::QueryColumnInfo *cinfo)
virtual void setVisibleValueInternal(const TQVariant &value)
Implemented to handle visible value instead of index.
virtual void setColumnInfo(KexiDB::QueryColumnInfo *cinfo)
virtual void beforeSignalValueChanged()
Implemented for KexiDataItemInterface.
virtual void fontChange(const TQFont &oldFont)
virtual void setValueInInternalEditor(const TQVariant &value)
Implemented for KexiComboBoxBase.
virtual TQPoint mapFromParentToGlobal(const TQPoint &pos) const
virtual void editRequested()
Implemented for KexiComboBoxBase.
virtual void createEditor()
virtual void moveCursorToEndInInternalEditor()
Implemented for KexiComboBoxBase. Does nothing if the widget is not editable.
virtual bool valueChanged()
Reimpemented because to avoid taking value from the internal editor (index is taken from the popup in...
virtual TQVariant visibleValue()
virtual void undoChanges()
virtual KexiDB::QueryColumnInfo * visibleColumnInfo() const
virtual int popupWidthHint() const
Implement this to return a hint for popup width.
virtual void setPaletteBackgroundColor(const TQColor &color)
Reimplemented to also set 'this' widget's background color, not only subwidget's.
virtual void styleChange(TQStyle &oldStyle)
virtual TQVariant valueFromInternalEditor()
Implemented for KexiComboBoxBase.
virtual void selectAllInInternalEditor()
Implemented for KexiComboBoxBase. Does nothing if the widget is not editable.
virtual void acceptRequested()
Implemented for KexiComboBoxBase.
virtual void paintEvent(TQPaintEvent *)
TQRect editorGeometry() const
Helper class that assigns additional information for the column in a query.
virtual TQVariant value()=0
void setValue(const TQVariant &value, const TQVariant &add=TQVariant(), bool removeOld=false, const TQVariant *visibleValue=0)
virtual void signalValueChanged()