kexidbform.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004 Lucijan Busch <lucijan@kde.org>
3 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
4 Copyright (C) 2005-2007 Jaroslaw Staniek <js@iidea.pl>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20*/
21
22#include <tqobjectlist.h>
23#include <tqpainter.h>
24#include <tqcursor.h>
25#include <tqapplication.h>
26#include <tqfocusdata.h>
27
28#include <kdebug.h>
29
30#include "kexidbform.h"
31#include "kexiformpart.h"
32#include "kexiformscrollview.h"
33
34#include <formeditor/objecttree.h>
35#include <formeditor/formmanager.h>
36#include <formeditor/widgetlibrary.h>
37#include <widget/tableview/kexidataawareobjectiface.h>
38#include <widget/kexiscrollview.h>
39#include <kexiutils/utils.h>
40
42class KexiDBForm::Private
43{
44 public:
45 Private()
46 : dataAwareObject(0)
47 , orderedFocusWidgetsIterator(orderedFocusWidgets)
48 , autoTabStops(false)
49 , popupFocused(false)
50 {
51 }
52
53 ~Private()
54 {
55 }
56
58 int indexOfDataAwareWidget(TQWidget *widget) const
59 {
60 if (!dynamic_cast<KexiDataItemInterface*>(widget))
61 return -1;
62 return indexOfDataItem( dynamic_cast<KexiDataItemInterface*>(widget) );
63 }
64
66 int indexOfDataItem( KexiDataItemInterface* item ) const
67 {
68 TQMapConstIterator<KexiDataItemInterface*, uint> indicesForDataAwareWidgetsIt(
69 indicesForDataAwareWidgets.find(item));
70 if (indicesForDataAwareWidgetsIt == indicesForDataAwareWidgets.constEnd())
71 return -1;
72 kexipluginsdbg << "KexiDBForm: column # for item: "
73 << indicesForDataAwareWidgetsIt.data() << endl;
74 return indicesForDataAwareWidgetsIt.data();
75 }
76
78 void setOrderedFocusWidgetsIteratorTo( TQWidget *widget )
79 {
80 if (orderedFocusWidgetsIterator.current() == widget)
81 return;
82 orderedFocusWidgetsIterator.toFirst();
83 while (orderedFocusWidgetsIterator.current() && orderedFocusWidgetsIterator.current()!=widget)
84 ++orderedFocusWidgetsIterator;
85 }
86
87 KexiDataAwareObjectInterface* dataAwareObject;
89 TQPtrList<TQWidget> orderedFocusWidgets;
91 TQPtrList<TQWidget> orderedDataAwareWidgets;
92 TQMap<KexiDataItemInterface*, uint> indicesForDataAwareWidgets;
93 TQPtrListIterator<TQWidget> orderedFocusWidgetsIterator;
94 TQPixmap buffer;
95 TQRect prev_rect;
96// TQGuardedPtr<TQWidget> widgetFocusedBeforePopup;
97 bool autoTabStops : 1;
98 bool popupFocused : 1;
99};
100
101//========================
102
103KexiDBForm::KexiDBForm(TQWidget *parent, KexiDataAwareObjectInterface* dataAwareObject,
104 const char *name/*, KexiDB::Connection *conn*/)
105 : KexiDBFormBase(parent, name)
107 , d(new Private())
108{
109 installEventFilter(this);
110//test setDisplayMode( KexiGradientWidget::SimpleGradient );
111 editedItem = 0;
112 d->dataAwareObject = dataAwareObject;
113 m_hasFocusableWidget = false;
114
115 kexipluginsdbg << "KexiDBForm::KexiDBForm(): " << endl;
116 setCursor(TQCursor(TQt::ArrowCursor)); //to avoid keeping Size cursor when moving from form's boundaries
117 setAcceptDrops( true );
118}
119
120KexiDBForm::~KexiDBForm()
121{
122 kexipluginsdbg << "KexiDBForm::~KexiDBForm(): close" << endl;
123 delete d;
124}
125
126KexiDataAwareObjectInterface* KexiDBForm::dataAwareObject() const { return d->dataAwareObject; }
127
128//repaint all children widgets
129static void repaintAll(TQWidget *w)
130{
131 TQObjectList *list = w->queryList("TQWidget");
132 TQObjectListIt it(*list);
133 for (TQObject *obj; (obj=it.current()); ++it ) {
134 static_cast<TQWidget*>(obj)->repaint();
135 }
136 delete list;
137}
138
139void
140KexiDBForm::drawRect(const TQRect& r, int type)
141{
142 TQValueList<TQRect> l;
143 l.append(r);
144 drawRects(l, type);
145}
146
147void
148KexiDBForm::drawRects(const TQValueList<TQRect> &list, int type)
149{
150 TQPainter p;
151 p.begin(this, true);
152 bool unclipped = testWFlags( WPaintUnclipped );
153 setWFlags( WPaintUnclipped );
154
155 if (d->prev_rect.isValid()) {
156 //redraw prev. selection's rectangle
157 p.drawPixmap( TQPoint(d->prev_rect.x()-2, d->prev_rect.y()-2), d->buffer,
158 TQRect(d->prev_rect.x()-2, d->prev_rect.y()-2, d->prev_rect.width()+4, d->prev_rect.height()+4));
159 }
160 p.setBrush(TQBrush::NoBrush);
161 if(type == 1) // selection rect
162 p.setPen(TQPen(white, 1, TQt::DotLine));
163 else if(type == 2) // insert rect
164 p.setPen(TQPen(white, 2));
165 p.setRasterOp(XorROP);
166
167 d->prev_rect = TQRect();
168 TQValueList<TQRect>::ConstIterator endIt = list.constEnd();
169 for(TQValueList<TQRect>::ConstIterator it = list.constBegin(); it != endIt; ++it) {
170 p.drawRect(*it);
171 if (d->prev_rect.isValid())
172 d->prev_rect = d->prev_rect.unite(*it);
173 else
174 d->prev_rect = *it;
175 }
176
177 if (!unclipped)
178 clearWFlags( WPaintUnclipped );
179 p.end();
180}
181
182void
184{
185 repaintAll(this);
186 d->buffer.resize( width(), height() );
187 d->buffer = TQPixmap::grabWindow( winId() );
188 d->prev_rect = TQRect();
189}
190
191void
193{
194 TQPainter p;
195 p.begin(this, true);
196 bool unclipped = testWFlags( WPaintUnclipped );
197 setWFlags( WPaintUnclipped );
198
199 //redraw entire form surface
200 p.drawPixmap( TQPoint(0,0), d->buffer, TQRect(0,0,d->buffer.width(), d->buffer.height()) );
201
202 if (!unclipped)
203 clearWFlags( WPaintUnclipped );
204 p.end();
205
206 repaintAll(this);
207}
208
209void
210KexiDBForm::highlightWidgets(TQWidget *from, TQWidget *to)//, const TQPoint &point)
211{
212 TQPoint fromPoint, toPoint;
213 if(from && from->parentWidget() && (from != this))
214 fromPoint = from->parentWidget()->mapTo(this, from->pos());
215 if(to && to->parentWidget() && (to != this))
216 toPoint = to->parentWidget()->mapTo(this, to->pos());
217
218 TQPainter p;
219 p.begin(this, true);
220 bool unclipped = testWFlags( WPaintUnclipped );
221 setWFlags( WPaintUnclipped );
222
223 if (d->prev_rect.isValid()) {
224 //redraw prev. selection's rectangle
225 p.drawPixmap( TQPoint(d->prev_rect.x(), d->prev_rect.y()), d->buffer,
226 TQRect(d->prev_rect.x(), d->prev_rect.y(), d->prev_rect.width(), d->prev_rect.height()));
227 }
228
229 p.setPen( TQPen(TQt::red, 2) );
230
231 if(to)
232 {
233 TQPixmap pix1 = TQPixmap::grabWidget(from);
234 TQPixmap pix2 = TQPixmap::grabWidget(to);
235
236 if((from != this) && (to != this))
237 p.drawLine( from->parentWidget()->mapTo(this, from->geometry().center()), to->parentWidget()->mapTo(this, to->geometry().center()) );
238
239 p.drawPixmap(fromPoint.x(), fromPoint.y(), pix1);
240 p.drawPixmap(toPoint.x(), toPoint.y(), pix2);
241
242 if(to == this)
243 p.drawRoundRect(2, 2, width()-4, height()-4, 4, 4);
244 else
245 p.drawRoundRect(toPoint.x(), toPoint.y(), to->width(), to->height(), 5, 5);
246 }
247
248 if(from == this)
249 p.drawRoundRect(2, 2, width()-4, height()-4, 4, 4);
250 else
251 p.drawRoundRect(fromPoint.x(), fromPoint.y(), from->width(), from->height(), 5, 5);
252
253 if((to == this) || (from == this))
254 d->prev_rect = TQRect(0, 0, d->buffer.width(), d->buffer.height());
255 else if(to)
256 {
257 d->prev_rect.setX( (fromPoint.x() < toPoint.x()) ? (fromPoint.x() - 5) : (toPoint.x() - 5) );
258 d->prev_rect.setY( (fromPoint.y() < toPoint.y()) ? (fromPoint.y() - 5) : (toPoint.y() - 5) );
259 d->prev_rect.setRight( (fromPoint.x() < toPoint.x()) ? (toPoint.x() + to->width() + 10) : (fromPoint.x() + from->width() + 10) );
260 d->prev_rect.setBottom( (fromPoint.y() < toPoint.y()) ? (toPoint.y() + to->height() + 10) : (fromPoint.y() + from->height() + 10) ) ;
261 }
262 else
263 d->prev_rect = TQRect(fromPoint.x()- 5, fromPoint.y() -5, from->width() + 10, from->height() + 10);
264
265 if (!unclipped)
266 clearWFlags( WPaintUnclipped );
267 p.end();
268}
269
270TQSize
271KexiDBForm::sizeHint() const
272{
273 //todo: find better size (user configured?)
274 return TQSize(400,300);
275}
276
277void KexiDBForm::setInvalidState( const TQString& displayText )
278{
279 Q_UNUSED( displayText );
280
282}
283
284bool KexiDBForm::autoTabStops() const
285{
286 return d->autoTabStops;
287}
288
289void KexiDBForm::setAutoTabStops(bool set)
290{
291 d->autoTabStops = set;
292}
293
294TQPtrList<TQWidget>* KexiDBForm::orderedFocusWidgets() const
295{
296 return &d->orderedFocusWidgets;
297}
298
299TQPtrList<TQWidget>* KexiDBForm::orderedDataAwareWidgets() const
300{
301 return &d->orderedDataAwareWidgets;
302}
303
305{
306 TQWidget *fromWidget = 0;
307 //TQWidget *topLevelWidget = form->widget()->topLevelWidget();
308//js form->updateTabStopsOrder(); //certain widgets can have now updated focusPolicy properties, fix this
309 uint numberOfDataAwareWidgets = 0;
310// if (d->orderedFocusWidgets.isEmpty()) {
311 //generate a new list
312 for (KFormDesigner::ObjectTreeListIterator it(form->tabStopsIterator()); it.current(); ++it) {
313 if (it.current()->widget()->focusPolicy() & TQWidget::TabFocus) {
314 //this widget has tab focus:
315 it.current()->widget()->installEventFilter(this);
316 //also filter events for data-aware children of this widget (i.e. KexiDBAutoField's editors)
317 TQObjectList *children = it.current()->widget()->queryList("TQWidget");
318 for (TQObjectListIt childrenIt(*children); childrenIt.current(); ++childrenIt) {
319 // if (dynamic_cast<KexiFormDataItemInterface*>(childrenIt.current())) {
320 kexipluginsdbg << "KexiDBForm::updateTabStopsOrder(): also adding '"
321 << childrenIt.current()->className() << " " << childrenIt.current()->name()
322 << "' child to filtered widgets" << endl;
323 //it.current()->widget()->installEventFilter(childrenIt.current());
324 childrenIt.current()->installEventFilter(this);
325 // }
326 }
327 delete children;
328 if (fromWidget) {
329 kexipluginsdbg << "KexiDBForm::updateTabStopsOrder() tab order: " << fromWidget->name()
330 << " -> " << it.current()->widget()->name() << endl;
331 // setTabOrder( fromWidget, it.current()->widget() );
332 }
333 fromWidget = it.current()->widget();
334 d->orderedFocusWidgets.append( it.current()->widget() );
335 }
336
337 KexiFormDataItemInterface* dataItem = dynamic_cast<KexiFormDataItemInterface*>( it.current()->widget() );
338 if (dataItem && !dataItem->dataSource().isEmpty()) {
339 kexipluginsdbg << "#" << numberOfDataAwareWidgets << ": "
340 << dataItem->dataSource() << " (" << it.current()->widget()->name() << ")" << endl;
341
342// /*! @todo d->indicesForDataAwareWidgets SHOULDNT BE UPDATED HERE BECAUSE
343// THERE CAN BE ALSO NON-TABSTOP DATA WIDGETS!
344// */
345 d->indicesForDataAwareWidgets.replace(
346 dataItem,
347 numberOfDataAwareWidgets );
348 numberOfDataAwareWidgets++;
349
350 d->orderedDataAwareWidgets.append( it.current()->widget() );
351 }
352 }//for
353// }
354/* else {
355 //restore ordering
356 for (TQPtrListIterator<TQWidget> it(d->orderedFocusWidgets); it.current(); ++it) {
357 if (fromWidget) {
358 kdDebug() << "KexiDBForm::updateTabStopsOrder() tab order: " << fromWidget->name()
359 << " -> " << it.current()->name() << endl;
360 setTabOrder( fromWidget, it.current() );
361 }
362 fromWidget = it.current();
363 }
364// SET_FOCUS_USING_REASON(focusWidget(), TQFocusEvent::Tab);
365 }*/
366}
367
368void KexiDBForm::updateTabStopsOrder()
369{
370 for (TQPtrListIterator<TQWidget> it( d->orderedFocusWidgets ); it.current();) {
371 if (! (it.current()->focusPolicy() & TQWidget::TabFocus))
372 d->orderedFocusWidgets.remove( it.current() );
373 else
374 ++it;
375 }
376}
377
379{
380 for (TQPtrListIterator<TQWidget> it(d->orderedDataAwareWidgets); it.current(); ++it) {
381 KexiFormDataItemInterface* dataItem = dynamic_cast<KexiFormDataItemInterface*>( it.current() );
382 if (dataItem && !dataItem->dataSource().isEmpty()) {
383 if (dataAwareObject()->isReadOnly()) {
384 dataItem->setReadOnly( true );
385 }
386 }
387 }
388}
389
390bool KexiDBForm::eventFilter( TQObject * watched, TQEvent * e )
391{
392 //kexipluginsdbg << e->type() << endl;
393 if (e->type()==TQEvent::Resize && watched == this)
394 kexipluginsdbg << "RESIZE" << endl;
395 if (e->type()==TQEvent::KeyPress) {
396 if (preview()) {
397 TQKeyEvent *ke = static_cast<TQKeyEvent*>(e);
398 const int key = ke->key();
399 bool tab = ke->state() == TQt::NoButton && key == TQt::Key_Tab;
400 bool backtab = ((ke->state() == TQt::NoButton || ke->state() == TQt::ShiftButton) && key == TQt::Key_Backtab)
401 || (ke->state() == TQt::ShiftButton && key == TQt::Key_Tab);
402 TQObject *o = watched; //focusWidget();
403 TQWidget* realWidget = dynamic_cast<TQWidget*>(o); //will beused below (for tab/backtab handling)
404
405 if (!tab && !backtab) {
406 //for buttons, left/up and right/down keys act like tab/backtab (see qbutton.cpp)
407 if (realWidget->inherits("TQButton")) {
408 if (ke->state() == TQt::NoButton && (key == TQt::Key_Right || key == TQt::Key_Down))
409 tab = true;
410 else if (ke->state() == TQt::NoButton && (key == TQt::Key_Left || key == TQt::Key_Up))
411 backtab = true;
412 }
413 }
414
415 if (!tab && !backtab) {
416 // allow the editor widget to grab the key press event
417 while (true) {
418 if (!o || o == dynamic_cast<TQObject*>(d->dataAwareObject))
419 break;
420 if (dynamic_cast<KexiFormDataItemInterface*>(o)) {
421 realWidget = dynamic_cast<TQWidget*>(o); //will be used below
422 if (realWidget == this) //we have encountered 'this' form surface, give up
423 return false;
424 KexiFormDataItemInterface* dataItemIface = dynamic_cast<KexiFormDataItemInterface*>(o);
425 while (dataItemIface) {
426 if (dataItemIface->keyPressed(ke))
427 return false;
428 dataItemIface = dynamic_cast<KexiFormDataItemInterface*>(dataItemIface->parentInterface()); //try in parent, e.g. in combobox
429 }
430 break;
431 }
432 o = o->parent();
433 }
434 // try to handle global shortcuts at the KexiDataAwareObjectInterface
435 // level (e.g. for "next record" action)
436 int curRow = d->dataAwareObject->currentRow();
437 int curCol = d->dataAwareObject->currentColumn();
438 bool moveToFirstField; //if true, we'll move focus to the first field (in tab order)
439 bool moveToLastField; //if true, we'll move focus to the first field (in tab order)
440 if (! (ke->state() == TQt::NoButton && (key == TQt::Key_Home
441 || key == TQt::Key_End || key == TQt::Key_Down || key == TQt::Key_Up))
442 /* ^^ home/end/down/up are already handled by widgets */
443 && d->dataAwareObject->handleKeyPress(
444 ke, curRow, curCol, false, &moveToFirstField, &moveToLastField))
445 {
446 if (ke->isAccepted())
447 return true;
448 TQWidget* widgetToFocus;
449 if (moveToFirstField) {
450 widgetToFocus = d->orderedFocusWidgets.first(); //?
451 curCol = d->indexOfDataAwareWidget( widgetToFocus );
452 }
453 else if (moveToLastField) {
454 widgetToFocus = d->orderedFocusWidgets.last(); //?
455 curCol = d->indexOfDataAwareWidget( widgetToFocus );
456 }
457 else
458 widgetToFocus = d->orderedDataAwareWidgets.at( curCol ); //?
459
460 d->dataAwareObject->setCursorPosition( curRow, curCol );
461
462 if (widgetToFocus)
463 widgetToFocus->setFocus();
464 else
465 kexipluginswarn << "KexiDBForm::eventFilter(): widgetToFocus not found!" << endl;
466
467 ke->accept();
468 return true;
469 }
470 if (key == TQt::Key_Delete && ke->state()==TQt::ControlButton) {
472 d->dataAwareObject->deleteCurrentRow();
473 return true;
474 }
475 }
476 // handle Esc key
477 if (ke->state() == TQt::NoButton && key == TQt::Key_Escape) {
478 //cancel field editing/row editing if possible
479 if (d->dataAwareObject->cancelEditor())
480 return true;
481 else if (d->dataAwareObject->cancelRowEdit())
482 return true;
483 return false; // canceling not needed - pass the event to the active widget
484 }
485 // jstaniek: Fix for TQt bug (handling e.g. Alt+2, Ctrl+2 keys on every platform)
486 // It's important because we're using alt+2 short cut by default
487 // Damn! I've reported this to Trolltech in November 2004 - still not fixed.
488 if (ke->isAccepted() && (ke->state() & TQt::AltButton) && ke->text()>="0" && ke->text()<="9")
489 return true;
490
491 if (tab || backtab) {
492 //the watched widget can be a subwidget of a real widget, e.g. a drop down button of image box: find it
493 while (!KexiFormPart::library()->widgetInfoForClassName(realWidget->className()))
494 realWidget = realWidget->parentWidget();
495 if (!realWidget)
496 return true; //ignore
497 //the watched widget can be a subwidget of a real widget, e.g. autofield: find it
498 //TQWidget* realWidget = static_cast<TQWidget*>(watched);
499 while (dynamic_cast<KexiDataItemInterface*>(realWidget) && dynamic_cast<KexiDataItemInterface*>(realWidget)->parentInterface())
500 realWidget = dynamic_cast<TQWidget*>( dynamic_cast<KexiDataItemInterface*>(realWidget)->parentInterface() );
501
502 d->setOrderedFocusWidgetsIteratorTo( realWidget );
503 kexipluginsdbg << realWidget->name() << endl;
504
505 // find next/prev widget to focus
506 TQWidget *widgetToUnfocus = realWidget;
507 TQWidget *widgetToFocus = 0;
508 bool wasAtFirstWidget = false; //used to protect against infinite loop
509 while (true) {
510 if (tab) {
511 if (d->orderedFocusWidgets.first() && realWidget == d->orderedFocusWidgets.last()) {
512 if (wasAtFirstWidget)
513 break;
514 d->orderedFocusWidgetsIterator.toFirst();
515 wasAtFirstWidget = true;
516 }
517 else if (realWidget == d->orderedFocusWidgetsIterator.current()) {
518 ++d->orderedFocusWidgetsIterator; //next
519 }
520 else
521 return true; //ignore
522 }
523 else {//backtab
524 if (d->orderedFocusWidgets.last() && realWidget == d->orderedFocusWidgets.first()) {
525 d->orderedFocusWidgetsIterator.toLast();
526 }
527 else if (realWidget == d->orderedFocusWidgetsIterator.current()) {
528 --d->orderedFocusWidgetsIterator; //prev
529 }
530 else
531 return true; //ignore
532 }
533
534 widgetToFocus = d->orderedFocusWidgetsIterator.current();
535
536 TQObject *pageFor_widgetToFocus = 0;
537 KFormDesigner::TabWidget *tabWidgetFor_widgetToFocus
539 widgetToFocus, "KFormDesigner::TabWidget", pageFor_widgetToFocus);
540 if (tabWidgetFor_widgetToFocus && tabWidgetFor_widgetToFocus->currentPage()!=pageFor_widgetToFocus) {
541 realWidget = widgetToFocus;
542 continue; //the new widget to focus is placed on invisible tab page: move to next widget
543 }
544 break;
545 }//while
546
547 //set focus, but don't use just setFocus() because certain widgets
548 //behaves differently (e.g. TQLineEdit calls selectAll()) when
549 //focus event's reason is TQFocusEvent::Tab
550 if (widgetToFocus->focusProxy())
551 widgetToFocus = widgetToFocus->focusProxy();
552 if (widgetToFocus && d->dataAwareObject->acceptEditor()) {
553 if (tab) {
554 //try to accept this will validate the current input (if any)
555 KexiUtils::unsetFocusWithReason(widgetToUnfocus, TQFocusEvent::Tab);
556 KexiUtils::setFocusWithReason(widgetToFocus, TQFocusEvent::Tab);
557 kexipluginsdbg << "focusing " << widgetToFocus->name() << endl;
558 }
559 else {//backtab
560 KexiUtils::unsetFocusWithReason(widgetToUnfocus, TQFocusEvent::Backtab);
561 //set focus, see above note
562 KexiUtils::setFocusWithReason(d->orderedFocusWidgetsIterator.current(), TQFocusEvent::Backtab);
563 kexipluginsdbg << "focusing " << d->orderedFocusWidgetsIterator.current()->name() << endl;
564 }
565 }
566 return true;
567 }
568 }
569 }
570 else if (e->type()==TQEvent::FocusIn) {
571 bool focusDataWidget = preview();
572 if (static_cast<TQFocusEvent*>(e)->reason()==TQFocusEvent::Popup) {
573 kdDebug() << "->>> focus IN, popup" <<endl;
574 focusDataWidget = !d->popupFocused;
575 d->popupFocused = false;
576// if (d->widgetFocusedBeforePopup) {
577// watched = d->widgetFocusedBeforePopup;
578// d->widgetFocusedBeforePopup = 0;
579// }
580 }
581
582 if (focusDataWidget) {
583 kexipluginsdbg << "KexiDBForm: FocusIn: " << watched->className() << " " << watched->name() << endl;
584 if (d->dataAwareObject) {
585 TQWidget *dataItem = dynamic_cast<TQWidget*>(watched);
586 while (dataItem) {
587 while (dataItem && !dynamic_cast<KexiDataItemInterface*>(dataItem))
588 dataItem = dataItem->parentWidget();
589 if (!dataItem)
590 break;
591 kexipluginsdbg << "KexiDBForm: FocusIn: FOUND " << dataItem->className() << " " << dataItem->name() << endl;
592
593 const int index = d->indexOfDataAwareWidget(dataItem);
594 if (index>=0) {
595 kexipluginsdbg << "KexiDBForm: moving cursor to column #" << index << endl;
596 editedItem = 0;
597 if ((int)index!=d->dataAwareObject->currentColumn()) {
598 d->dataAwareObject->setCursorPosition( d->dataAwareObject->currentRow(), index /*column*/ );
599 }
600 break;
601 }
602 else
603 dataItem = dataItem->parentWidget();
604
605 dataItem->update();
606 }
607 }
608 }
609 }
610 else if (e->type()==TQEvent::FocusOut) {
611 if (static_cast<TQFocusEvent*>(e)->reason()==TQFocusEvent::Popup) {
612 //d->widgetFocusedBeforePopup = (TQWidget*)watched;
613 d->popupFocused = true;
614 }
615 else
616 d->popupFocused = false;
617// d->widgetFocusedBeforePopup = 0;
618// kdDebug() << "e->type()==TQEvent::FocusOut " << watched->className() << " " <<watched->name() << endl;
619// UNSET_FOCUS_USING_REASON(watched, static_cast<TQFocusEvent*>(e)->reason());
620 }
621 return KexiDBFormBase::eventFilter(watched, e);
622}
623
625{
626 return true;
627}
628
630{
631 return true;
632}
633
634bool KexiDBForm::isReadOnly() const
635{
636 if (d->dataAwareObject)
637 return d->dataAwareObject->isReadOnly();
639 return false;
640}
641
642void KexiDBForm::setReadOnly( bool readOnly )
643{
644 if (d->dataAwareObject)
645 d->dataAwareObject->setReadOnly( readOnly ); //???
646}
647
648TQWidget* KexiDBForm::widget()
649{
650 return this;
651}
652
654{
655 return false;
656}
657
659{
660 return false;
661}
662
664{
666}
667
668bool KexiDBForm::preview() const {
669 return dynamic_cast<KexiScrollView*>(d->dataAwareObject)
670 ? dynamic_cast<KexiScrollView*>(d->dataAwareObject)->preview() : false;
671}
672
673void KexiDBForm::dragMoveEvent( TQDragMoveEvent *e )
674{
675 KexiDBFormBase::dragMoveEvent( e );
676 emit handleDragMoveEvent(e);
677}
678
679void KexiDBForm::dropEvent( TQDropEvent *e )
680{
681 KexiDBFormBase::dropEvent( e );
682 emit handleDropEvent(e);
683}
684
685void KexiDBForm::setCursor( const TQCursor & cursor )
686{
687 //js: empty, to avoid fscking problems with random cursors!
689
690 if (KFormDesigner::FormManager::self()->isInserting()) //exception
691 KexiDBFormBase::setCursor(cursor);
692}
693
694#include "kexidbform.moc"
static FormManager * self()
Access to FormManager singleton.
A simple class representing a form.
Definition form.h:136
A tab widget providing information about height of the tab bar.
virtual void clear()
clears item's data, so the data will contain NULL data
virtual void setReadOnly(bool readOnly)
This implementation just disables read only widget.
virtual void clearForm()
virtual bool cursorAtEnd()
virtual bool cursorAtStart()
virtual void drawRects(const TQValueList< TQRect > &list, int type)
virtual bool valueIsNull()
virtual bool valueIsEmpty()
KexiFormDataItemInterface * editedItem
Points to a currently edited data item.
Definition kexidbform.h:132
void updateTabStopsOrder(KFormDesigner::Form *form)
virtual void dragMoveEvent(TQDragMoveEvent *e)
Used to emit handleDragMoveEvent() signal needed to control dragging over the container's surface.
void updateReadOnlyFlags()
called from KexiFormScrollView::initDataContents()
virtual void setInvalidState(const TQString &displayText)
virtual void initBuffer()
virtual void highlightWidgets(TQWidget *from, TQWidget *to)
virtual void dropEvent(TQDropEvent *e)
Used to emit handleDropEvent() signal needed to control dropping on the container's surface.
virtual TQWidget * widget()
virtual bool isReadOnly() const
The KexiDataAwareObjectInterface is an interface for record-based data object.
An interface for declaring widgets to be data-aware.
KexiDataItemInterface * parentInterface() const
An interface for declaring form widgets to be data-aware.
virtual void setReadOnly(bool readOnly)=0
static KFormDesigner::WidgetLibrary * library()
The scrollview which includes KexiDBForm.
TQPtrListIterator< ObjectTreeItem > ObjectTreeListIterator
An iterator for ObjectTreeList.
Definition objecttree.h:45
type * findParent(TQObject *o, const char *className, TQObject *&prevPrev)
KEXIUTILS_EXPORT void unsetFocusWithReason(TQWidget *widget, TQFocusEvent::Reason reason)
Unsets focus for widget widget with reason reason.
KEXIUTILS_EXPORT void setFocusWithReason(TQWidget *widget, TQFocusEvent::Reason reason)
Sets focus for widget widget with reason reason.