You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kexi/plugins/forms/widgets/kexidbform.cpp

715 lines
23 KiB

/* This file is part of the KDE project
Copyright (C) 2004 Lucijan Busch <lucijan@kde.org>
Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
Copyright (C) 2005-2007 Jaroslaw Staniek <js@iidea.pl>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 <tqobjectlist.h>
#include <tqpainter.h>
#include <tqcursor.h>
#include <tqapplication.h>
#include <tqfocusdata.h>
#include <kdebug.h>
#include "kexidbform.h"
#include "kexiformpart.h"
#include "kexiformscrollview.h"
#include <formeditor/objecttree.h>
#include <formeditor/formmanager.h>
#include <formeditor/widgetlibrary.h>
#include <widget/tableview/kexidataawareobjectiface.h>
#include <widget/kexiscrollview.h>
#include <kexiutils/utils.h>
//! @internal
class KexiDBForm::Private
{
public:
Private()
: dataAwareObject(0)
, orderedFocusWidgetsIterator(orderedFocusWidgets)
, autoTabStops(false)
, popupFocused(false)
{
}
~Private()
{
}
//! \return index of data-aware widget \a widget
int indexOfDataAwareWidget(TQWidget *widget) const
{
if (!dynamic_cast<KexiDataItemInterface*>(widget))
return -1;
return indexOfDataItem( dynamic_cast<KexiDataItemInterface*>(widget) );
}
//! \return index of data item \a item, or -1 if not found
int indexOfDataItem( KexiDataItemInterface* item ) const
{
TQMapConstIterator<KexiDataItemInterface*, uint> indicesForDataAwareWidgetsIt(
indicesForDataAwareWidgets.tqfind(item));
if (indicesForDataAwareWidgetsIt == indicesForDataAwareWidgets.constEnd())
return -1;
kexipluginsdbg << "KexiDBForm: column # for item: "
<< indicesForDataAwareWidgetsIt.data() << endl;
return indicesForDataAwareWidgetsIt.data();
}
//! Sets orderedFocusWidgetsIterator member to a position pointing to \a widget
void setOrderedFocusWidgetsIteratorTo( TQWidget *widget )
{
if (orderedFocusWidgetsIterator.current() == widget)
return;
orderedFocusWidgetsIterator.toFirst();
while (orderedFocusWidgetsIterator.current() && orderedFocusWidgetsIterator.current()!=widget)
++orderedFocusWidgetsIterator;
}
KexiDataAwareObjectInterface* dataAwareObject;
//! ordered list of focusable widgets (can be both data-widgets or buttons, etc.)
TQPtrList<TQWidget> orderedFocusWidgets;
//! ordered list of data-aware widgets
TQPtrList<TQWidget> orderedDataAwareWidgets;
TQMap<KexiDataItemInterface*, uint> indicesForDataAwareWidgets; //!< a subset of orderedFocusWidgets mapped to indices
TQPtrListIterator<TQWidget> orderedFocusWidgetsIterator;
TQPixmap buffer; //!< stores grabbed entire form's area for redraw
TQRect prev_rect; //!< previously selected rectangle
// TQGuardedPtr<TQWidget> widgetFocusedBeforePopup;
bool autoTabStops : 1;
bool popupFocused : 1; //!< used in KexiDBForm::eventFilter()
};
//========================
KexiDBForm::KexiDBForm(TQWidget *tqparent, KexiDataAwareObjectInterface* dataAwareObject,
const char *name/*, KexiDB::Connection *conn*/)
: KexiDBFormBase(tqparent, name)
, KexiFormDataItemInterface()
, d(new Private())
{
installEventFilter(this);
//test setDisplayMode( KexiGradientWidget::SimpleGradient );
editedItem = 0;
d->dataAwareObject = dataAwareObject;
m_hasFocusableWidget = false;
kexipluginsdbg << "KexiDBForm::KexiDBForm(): " << endl;
setCursor(TQCursor(TQt::ArrowCursor)); //to avoid keeping Size cursor when moving from form's boundaries
setAcceptDrops( true );
}
KexiDBForm::~KexiDBForm()
{
kexipluginsdbg << "KexiDBForm::~KexiDBForm(): close" << endl;
delete d;
}
KexiDataAwareObjectInterface* KexiDBForm::dataAwareObject() const { return d->dataAwareObject; }
//tqrepaint all tqchildren widgets
static void repaintAll(TQWidget *w)
{
TQObjectList *list = w->queryList(TQWIDGET_OBJECT_NAME_STRING);
TQObjectListIt it(*list);
for (TQObject *obj; (obj=it.current()); ++it ) {
TQT_TQWIDGET(obj)->tqrepaint();
}
delete list;
}
void
KexiDBForm::drawRect(const TQRect& r, int type)
{
TQValueList<TQRect> l;
l.append(r);
drawRects(l, type);
}
void
KexiDBForm::drawRects(const TQValueList<TQRect> &list, int type)
{
TQPainter p;
p.tqbegin(TQT_TQPAINTDEVICE(this), true);
bool unclipped = testWFlags( WPaintUnclipped );
setWFlags( WPaintUnclipped );
if (d->prev_rect.isValid()) {
//redraw prev. selection's rectangle
p.drawPixmap( TQPoint(d->prev_rect.x()-2, d->prev_rect.y()-2), d->buffer,
TQRect(d->prev_rect.x()-2, d->prev_rect.y()-2, d->prev_rect.width()+4, d->prev_rect.height()+4));
}
p.setBrush(TQBrush::NoBrush);
if(type == 1) // selection rect
p.setPen(TQPen(white, 1, TQt::DotLine));
else if(type == 2) // insert rect
p.setPen(TQPen(white, 2));
p.setRasterOp(XorROP);
d->prev_rect = TQRect();
TQValueList<TQRect>::ConstIterator endIt = list.constEnd();
for(TQValueList<TQRect>::ConstIterator it = list.constBegin(); it != endIt; ++it) {
p.drawRect(*it);
if (d->prev_rect.isValid())
d->prev_rect = d->prev_rect.unite(*it);
else
d->prev_rect = *it;
}
if (!unclipped)
clearWFlags( WPaintUnclipped );
p.end();
}
void
KexiDBForm::initBuffer()
{
repaintAll(this);
d->buffer.resize( width(), height() );
d->buffer = TQPixmap::grabWindow( winId() );
d->prev_rect = TQRect();
}
void
KexiDBForm::clearForm()
{
TQPainter p;
p.tqbegin(TQT_TQPAINTDEVICE(this), true);
bool unclipped = testWFlags( WPaintUnclipped );
setWFlags( WPaintUnclipped );
//redraw entire form surface
p.drawPixmap( TQPoint(0,0), d->buffer, TQRect(0,0,d->buffer.width(), d->buffer.height()) );
if (!unclipped)
clearWFlags( WPaintUnclipped );
p.end();
repaintAll(this);
}
void
KexiDBForm::highlightWidgets(TQWidget *from, TQWidget *to)//, const TQPoint &point)
{
TQPoint fromPoint, toPoint;
if(from && from->parentWidget() && (from != this))
fromPoint = from->parentWidget()->mapTo(this, from->pos());
if(to && to->parentWidget() && (to != this))
toPoint = to->parentWidget()->mapTo(this, to->pos());
TQPainter p;
p.tqbegin(TQT_TQPAINTDEVICE(this), true);
bool unclipped = testWFlags( WPaintUnclipped );
setWFlags( WPaintUnclipped );
if (d->prev_rect.isValid()) {
//redraw prev. selection's rectangle
p.drawPixmap( TQPoint(d->prev_rect.x(), d->prev_rect.y()), d->buffer,
TQRect(d->prev_rect.x(), d->prev_rect.y(), d->prev_rect.width(), d->prev_rect.height()));
}
p.setPen( TQPen(TQt::red, 2) );
if(to)
{
TQPixmap pix1 = TQPixmap::grabWidget(from);
TQPixmap pix2 = TQPixmap::grabWidget(to);
if((from != this) && (to != this))
p.drawLine( from->parentWidget()->mapTo(this, from->tqgeometry().center()), to->parentWidget()->mapTo(this, to->tqgeometry().center()) );
p.drawPixmap(fromPoint.x(), fromPoint.y(), pix1);
p.drawPixmap(toPoint.x(), toPoint.y(), pix2);
if(to == this)
p.drawRoundRect(2, 2, width()-4, height()-4, 4, 4);
else
p.drawRoundRect(toPoint.x(), toPoint.y(), to->width(), to->height(), 5, 5);
}
if(from == this)
p.drawRoundRect(2, 2, width()-4, height()-4, 4, 4);
else
p.drawRoundRect(fromPoint.x(), fromPoint.y(), from->width(), from->height(), 5, 5);
if((to == this) || (from == this))
d->prev_rect = TQRect(0, 0, d->buffer.width(), d->buffer.height());
else if(to)
{
d->prev_rect.setX( (fromPoint.x() < toPoint.x()) ? (fromPoint.x() - 5) : (toPoint.x() - 5) );
d->prev_rect.setY( (fromPoint.y() < toPoint.y()) ? (fromPoint.y() - 5) : (toPoint.y() - 5) );
d->prev_rect.setRight( (fromPoint.x() < toPoint.x()) ? (toPoint.x() + to->width() + 10) : (fromPoint.x() + from->width() + 10) );
d->prev_rect.setBottom( (fromPoint.y() < toPoint.y()) ? (toPoint.y() + to->height() + 10) : (fromPoint.y() + from->height() + 10) ) ;
}
else
d->prev_rect = TQRect(fromPoint.x()- 5, fromPoint.y() -5, from->width() + 10, from->height() + 10);
if (!unclipped)
clearWFlags( WPaintUnclipped );
p.end();
}
TQSize
KexiDBForm::tqsizeHint() const
{
//todo: find better size (user configured?)
return TQSize(400,300);
}
void KexiDBForm::setInvalidState( const TQString& displayText )
{
Q_UNUSED( displayText );
//! @todo draw "invalid data source" text on the surface?
}
bool KexiDBForm::autoTabStops() const
{
return d->autoTabStops;
}
void KexiDBForm::setAutoTabStops(bool set)
{
d->autoTabStops = set;
}
TQPtrList<TQWidget>* KexiDBForm::orderedFocusWidgets() const
{
return &d->orderedFocusWidgets;
}
TQPtrList<TQWidget>* KexiDBForm::orderedDataAwareWidgets() const
{
return &d->orderedDataAwareWidgets;
}
void KexiDBForm::updateTabStopsOrder(KFormDesigner::Form* form)
{
TQWidget *fromWidget = 0;
//TQWidget *tqtopLevelWidget = form->widget()->tqtopLevelWidget();
//js form->updateTabStopsOrder(); //certain widgets can have now updated focusPolicy properties, fix this
uint numberOfDataAwareWidgets = 0;
// if (d->orderedFocusWidgets.isEmpty()) {
//generate a new list
for (KFormDesigner::ObjectTreeListIterator it(form->tabStopsIterator()); it.current(); ++it) {
if (it.current()->widget()->focusPolicy() & TQ_TabFocus) {
//this widget has tab focus:
it.current()->widget()->installEventFilter(this);
//also filter events for data-aware tqchildren of this widget (i.e. KexiDBAutoField's editors)
TQObjectList *tqchildren = it.current()->widget()->queryList(TQWIDGET_OBJECT_NAME_STRING);
for (TQObjectListIt tqchildrenIt(*tqchildren); tqchildrenIt.current(); ++tqchildrenIt) {
// if (dynamic_cast<KexiFormDataItemInterface*>(tqchildrenIt.current())) {
kexipluginsdbg << "KexiDBForm::updateTabStopsOrder(): also adding '"
<< tqchildrenIt.current()->className() << " " << tqchildrenIt.current()->name()
<< "' child to filtered widgets" << endl;
//it.current()->widget()->installEventFilter(TQT_TQWIDGET(tqchildrenIt.current()));
tqchildrenIt.current()->installEventFilter(this);
// }
}
delete tqchildren;
if (fromWidget) {
kexipluginsdbg << "KexiDBForm::updateTabStopsOrder() tab order: " << fromWidget->name()
<< " -> " << it.current()->widget()->name() << endl;
// setTabOrder( fromWidget, it.current()->widget() );
}
fromWidget = it.current()->widget();
d->orderedFocusWidgets.append( it.current()->widget() );
}
KexiFormDataItemInterface* dataItem = dynamic_cast<KexiFormDataItemInterface*>( it.current()->widget() );
if (dataItem && !dataItem->dataSource().isEmpty()) {
kexipluginsdbg << "#" << numberOfDataAwareWidgets << ": "
<< dataItem->dataSource() << " (" << it.current()->widget()->name() << ")" << endl;
// /*! @todo d->indicesForDataAwareWidgets SHOULDNT BE UPDATED HERE BECAUSE
// THERE CAN BE ALSO NON-TABSTOP DATA WIDGETS!
// */
d->indicesForDataAwareWidgets.tqreplace(
dataItem,
numberOfDataAwareWidgets );
numberOfDataAwareWidgets++;
d->orderedDataAwareWidgets.append( it.current()->widget() );
}
}//for
// }
/* else {
//restore ordering
for (TQPtrListIterator<TQWidget> it(d->orderedFocusWidgets); it.current(); ++it) {
if (fromWidget) {
kdDebug() << "KexiDBForm::updateTabStopsOrder() tab order: " << fromWidget->name()
<< " -> " << it.current()->name() << endl;
setTabOrder( fromWidget, it.current() );
}
fromWidget = it.current();
}
// SET_FOCUS_USING_REASON(tqfocusWidget(), TQFocusEvent::Tab);
}*/
}
void KexiDBForm::updateTabStopsOrder()
{
for (TQPtrListIterator<TQWidget> it( d->orderedFocusWidgets ); it.current();) {
if (! (it.current()->focusPolicy() & TQ_TabFocus))
d->orderedFocusWidgets.remove( it.current() );
else
++it;
}
}
void KexiDBForm::updateReadOnlyFlags()
{
for (TQPtrListIterator<TQWidget> it(d->orderedDataAwareWidgets); it.current(); ++it) {
KexiFormDataItemInterface* dataItem = dynamic_cast<KexiFormDataItemInterface*>( it.current() );
if (dataItem && !dataItem->dataSource().isEmpty()) {
if (dataAwareObject()->isReadOnly()) {
dataItem->setReadOnly( true );
}
}
}
}
bool KexiDBForm::eventFilter( TQObject * watched, TQEvent * e )
{
//kexipluginsdbg << e->type() << endl;
if (e->type()==TQEvent::Resize && TQT_BASE_OBJECT(watched) == TQT_BASE_OBJECT(this))
kexipluginsdbg << "RESIZE" << endl;
if (e->type()==TQEvent::KeyPress) {
if (preview()) {
TQKeyEvent *ke = TQT_TQKEYEVENT(e);
const int key = ke->key();
bool tab = ke->state() == Qt::NoButton && key == TQt::Key_Tab;
bool backtab = ((ke->state() == Qt::NoButton || ke->state() == TQt::ShiftButton) && key == TQt::Key_Backtab)
|| (ke->state() == TQt::ShiftButton && key == TQt::Key_Tab);
TQObject *o = watched; //tqfocusWidget();
TQWidget* realWidget = dynamic_cast<TQWidget*>(o); //will beused below (for tab/backtab handling)
if (!tab && !backtab) {
//for buttons, left/up and right/down keys act like tab/backtab (see qbutton.cpp)
if (realWidget->inherits(TQBUTTON_OBJECT_NAME_STRING)) {
if (ke->state() == Qt::NoButton && (key == TQt::Key_Right || key == TQt::Key_Down))
tab = true;
else if (ke->state() == Qt::NoButton && (key == TQt::Key_Left || key == TQt::Key_Up))
backtab = true;
}
}
if (!tab && !backtab) {
// allow the editor widget to grab the key press event
while (true) {
if (!o || o == dynamic_cast<TQObject*>(d->dataAwareObject))
break;
if (dynamic_cast<KexiFormDataItemInterface*>(o)) {
realWidget = dynamic_cast<TQWidget*>(o); //will be used below
if (realWidget == this) //we have encountered 'this' form surface, give up
return false;
KexiFormDataItemInterface* dataItemIface = dynamic_cast<KexiFormDataItemInterface*>(o);
while (dataItemIface) {
if (dataItemIface->keyPressed(ke))
return false;
dataItemIface = dynamic_cast<KexiFormDataItemInterface*>(dataItemIface->parentInterface()); //try in tqparent, e.g. in combobox
}
break;
}
o = o->tqparent();
}
// try to handle global shortcuts at the KexiDataAwareObjectInterface
// level (e.g. for "next record" action)
int curRow = d->dataAwareObject->currentRow();
int curCol = d->dataAwareObject->currentColumn();
bool moveToFirstField; //if true, we'll move focus to the first field (in tab order)
bool moveToLastField; //if true, we'll move focus to the first field (in tab order)
if (! (ke->state() == Qt::NoButton && (key == TQt::Key_Home
|| key == TQt::Key_End || key == TQt::Key_Down || key == TQt::Key_Up))
/* ^^ home/end/down/up are already handled by widgets */
&& d->dataAwareObject->handleKeyPress(
ke, curRow, curCol, false/*!fullRowSelection*/, &moveToFirstField, &moveToLastField))
{
if (ke->isAccepted())
return true;
TQWidget* widgetToFocus;
if (moveToFirstField) {
widgetToFocus = d->orderedFocusWidgets.first(); //?
curCol = d->indexOfDataAwareWidget( widgetToFocus );
}
else if (moveToLastField) {
widgetToFocus = d->orderedFocusWidgets.last(); //?
curCol = d->indexOfDataAwareWidget( widgetToFocus );
}
else
widgetToFocus = d->orderedDataAwareWidgets.at( curCol ); //?
d->dataAwareObject->setCursorPosition( curRow, curCol );
if (widgetToFocus)
widgetToFocus->setFocus();
else
kexipluginswarn << "KexiDBForm::eventFilter(): widgetToFocus not found!" << endl;
ke->accept();
return true;
}
if (key == TQt::Key_Delete && ke->state()==TQt::ControlButton) {
//! @todo remove hardcoded shortcuts: can be reconfigured...
d->dataAwareObject->deleteCurrentRow();
return true;
}
}
// handle Esc key
if (ke->state() == Qt::NoButton && key == TQt::Key_Escape) {
//cancel field editing/row editing if possible
if (d->dataAwareObject->cancelEditor())
return true;
else if (d->dataAwareObject->cancelRowEdit())
return true;
return false; // canceling not needed - pass the event to the active widget
}
// jstaniek: Fix for TQt bug (handling e.g. Alt+2, Ctrl+2 keys on every platform)
// It's important because we're using alt+2 short cut by default
// Damn! I've reported this to Trolltech in November 2004 - still not fixed.
if (ke->isAccepted() && (ke->state() & TQt::AltButton) && ke->text()>="0" && ke->text()<="9")
return true;
if (tab || backtab) {
//the watched widget can be a subwidget of a real widget, e.g. a drop down button of image box: find it
while (!KexiFormPart::library()->widgetInfoForClassName(realWidget->className()))
realWidget = realWidget->parentWidget();
if (!realWidget)
return true; //ignore
//the watched widget can be a subwidget of a real widget, e.g. autofield: find it
//TQWidget* realWidget = TQT_TQWIDGET(watched);
while (dynamic_cast<KexiDataItemInterface*>(realWidget) && dynamic_cast<KexiDataItemInterface*>(realWidget)->parentInterface())
realWidget = dynamic_cast<TQWidget*>( dynamic_cast<KexiDataItemInterface*>(realWidget)->parentInterface() );
d->setOrderedFocusWidgetsIteratorTo( realWidget );
kexipluginsdbg << realWidget->name() << endl;
// find next/prev widget to focus
TQWidget *widgetToUnfocus = realWidget;
TQWidget *widgetToFocus = 0;
bool wasAtFirstWidget = false; //used to protect against infinite loop
while (true) {
if (tab) {
if (d->orderedFocusWidgets.first() && realWidget == d->orderedFocusWidgets.last()) {
if (wasAtFirstWidget)
break;
d->orderedFocusWidgetsIterator.toFirst();
wasAtFirstWidget = true;
}
else if (realWidget == d->orderedFocusWidgetsIterator.current()) {
++d->orderedFocusWidgetsIterator; //next
}
else
return true; //ignore
}
else {//backtab
if (d->orderedFocusWidgets.last() && realWidget == d->orderedFocusWidgets.first()) {
d->orderedFocusWidgetsIterator.toLast();
}
else if (realWidget == d->orderedFocusWidgetsIterator.current()) {
--d->orderedFocusWidgetsIterator; //prev
}
else
return true; //ignore
}
widgetToFocus = d->orderedFocusWidgetsIterator.current();
TQObject *pageFor_widgetToFocus = 0;
KFormDesigner::TabWidget *tabWidgetFor_widgetToFocus
= KFormDesigner::findParent<KFormDesigner::TabWidget>(
widgetToFocus, "KFormDesigner::TabWidget", pageFor_widgetToFocus);
if (tabWidgetFor_widgetToFocus && TQT_BASE_OBJECT(tabWidgetFor_widgetToFocus->currentPage())!=TQT_BASE_OBJECT(pageFor_widgetToFocus)) {
realWidget = widgetToFocus;
continue; //the new widget to focus is placed on invisible tab page: move to next widget
}
break;
}//while
//set focus, but don't use just setFocus() because certain widgets
//behaves differently (e.g. TQLineEdit calls selectAll()) when
//focus event's reason is TQFocusEvent::Tab
if (widgetToFocus->focusProxy())
widgetToFocus = TQT_TQWIDGET(widgetToFocus->focusProxy());
if (widgetToFocus && d->dataAwareObject->acceptEditor()) {
if (tab) {
//try to accept this will validate the current input (if any)
KexiUtils::unsetFocusWithReason(widgetToUnfocus, TQFocusEvent::Tab);
KexiUtils::setFocusWithReason(widgetToFocus, TQFocusEvent::Tab);
kexipluginsdbg << "focusing " << widgetToFocus->name() << endl;
}
else {//backtab
KexiUtils::unsetFocusWithReason(widgetToUnfocus, TQFocusEvent::Backtab);
//set focus, see above note
KexiUtils::setFocusWithReason(d->orderedFocusWidgetsIterator.current(), TQFocusEvent::Backtab);
kexipluginsdbg << "focusing " << d->orderedFocusWidgetsIterator.current()->name() << endl;
}
}
return true;
}
}
}
else if (e->type()==TQEvent::FocusIn) {
bool focusDataWidget = preview();
if (TQT_TQFOCUSEVENT(e)->reason()==TQFocusEvent::Popup) {
kdDebug() << "->>> focus IN, popup" <<endl;
focusDataWidget = !d->popupFocused;
d->popupFocused = false;
// if (d->widgetFocusedBeforePopup) {
// watched = d->widgetFocusedBeforePopup;
// d->widgetFocusedBeforePopup = 0;
// }
}
if (focusDataWidget) {
kexipluginsdbg << "KexiDBForm: FocusIn: " << watched->className() << " " << watched->name() << endl;
if (d->dataAwareObject) {
TQWidget *dataItem = dynamic_cast<TQWidget*>(watched);
while (dataItem) {
while (dataItem && !dynamic_cast<KexiDataItemInterface*>(dataItem))
dataItem = dataItem->parentWidget();
if (!dataItem)
break;
kexipluginsdbg << "KexiDBForm: FocusIn: FOUND " << dataItem->className() << " " << dataItem->name() << endl;
const int index = d->indexOfDataAwareWidget(dataItem);
if (index>=0) {
kexipluginsdbg << "KexiDBForm: moving cursor to column #" << index << endl;
editedItem = 0;
if ((int)index!=d->dataAwareObject->currentColumn()) {
d->dataAwareObject->setCursorPosition( d->dataAwareObject->currentRow(), index /*column*/ );
}
break;
}
else
dataItem = dataItem->parentWidget();
dataItem->update();
}
}
}
}
else if (e->type()==TQEvent::FocusOut) {
if (TQT_TQFOCUSEVENT(e)->reason()==TQFocusEvent::Popup) {
//d->widgetFocusedBeforePopup = (TQWidget*)watched;
d->popupFocused = true;
}
else
d->popupFocused = false;
// d->widgetFocusedBeforePopup = 0;
// kdDebug() << "e->type()==TQEvent::FocusOut " << watched->className() << " " <<watched->name() << endl;
// UNSET_FOCUS_USING_REASON(watched, TQT_TQFOCUSEVENT(e)->reason());
}
return KexiDBFormBase::eventFilter(watched, e);
}
bool KexiDBForm::valueIsNull()
{
return true;
}
bool KexiDBForm::valueIsEmpty()
{
return true;
}
bool KexiDBForm::isReadOnly() const
{
if (d->dataAwareObject)
return d->dataAwareObject->isReadOnly();
//! @todo ?
return false;
}
void KexiDBForm::setReadOnly( bool readOnly )
{
if (d->dataAwareObject)
d->dataAwareObject->setReadOnly( readOnly ); //???
}
TQWidget* KexiDBForm::widget()
{
return this;
}
bool KexiDBForm::cursorAtStart()
{
return false;
}
bool KexiDBForm::cursorAtEnd()
{
return false;
}
void KexiDBForm::clear()
{
//! @todo clear all fields?
}
bool KexiDBForm::preview() const {
return dynamic_cast<KexiScrollView*>(d->dataAwareObject)
? dynamic_cast<KexiScrollView*>(d->dataAwareObject)->preview() : false;
}
void KexiDBForm::dragMoveEvent( TQDragMoveEvent *e )
{
KexiDBFormBase::dragMoveEvent( e );
emit handleDragMoveEvent(e);
}
void KexiDBForm::dropEvent( TQDropEvent *e )
{
KexiDBFormBase::dropEvent( e );
emit handleDropEvent(e);
}
void KexiDBForm::setCursor( const TQCursor & cursor )
{
//js: empty, to avoid fscking problems with random cursors!
//! @todo?
if (KFormDesigner::FormManager::self()->isInserting()) //exception
KexiDBFormBase::setCursor(cursor);
}
//! @todo: TQt4? XORed resize rectangles instead of black widgets
/*
void KexiDBForm::paintEvent( TQPaintEvent *e )
{
TQPainter p;
p.begin(this, true);
bool unclipped = testWFlags( WPaintUnclipped );
setWFlags( WPaintUnclipped );
p.setPen(white);
p.setRasterOp(XorROP);
p.drawLine(e->rect().topLeft(), e->rect().bottomRight());
if (!unclipped)
clearWFlags( WPaintUnclipped );
p.end();
KexiDBFormBase::paintEvent(e);
}
*/
#include "kexidbform.moc"