kexi

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
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
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
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 bool cursorAtStart()
virtual void clearForm()
virtual void dragMoveEvent(TQDragMoveEvent *e)
Used to emit handleDragMoveEvent() signal needed to control dragging over the container's surface.
virtual bool cursorAtEnd()
virtual void dropEvent(TQDropEvent *e)
Used to emit handleDropEvent() signal needed to control dropping on the container's surface.
virtual void drawRects(const TQValueList< TQRect > &list, int type)
virtual void clear()
clears item's data, so the data will contain NULL data
KexiFormDataItemInterface * editedItem
Definition kexidbform.h:132
void updateTabStopsOrder(KFormDesigner::Form *form)
virtual void setCursor(const TQCursor &cursor)
virtual bool valueIsEmpty()
void updateReadOnlyFlags()
called from KexiFormScrollView::initDataContents()
virtual void setInvalidState(const TQString &displayText)
virtual void initBuffer()
virtual void highlightWidgets(TQWidget *from, TQWidget *to)
virtual TQWidget * widget()
virtual void setReadOnly(bool readOnly)
This implementation just disables read only widget.
virtual bool eventFilter(TQObject *watched, TQEvent *e)
virtual bool valueIsNull()
virtual bool isReadOnly() const
The KexiDataAwareObjectInterface is an interface for record-based data object.
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.