00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kexicomboboxpopup.h"
00021
00022 #include "kexidatatableview.h"
00023 #include "kexitableview_p.h"
00024 #include "kexitableitem.h"
00025 #include "kexitableedit.h"
00026
00027 #include <kexidb/lookupfieldschema.h>
00028
00029 #include <kdebug.h>
00030
00031 #include <qlayout.h>
00032 #include <qevent.h>
00033
00036 class KexiComboBoxPopup_KexiTableView : public KexiDataTableView
00037 {
00038 public:
00039 KexiComboBoxPopup_KexiTableView(QWidget* parent=0)
00040 : KexiDataTableView(parent, "KexiComboBoxPopup_tv")
00041 {
00042 init();
00043 }
00044 void init()
00045 {
00046 setReadOnly( true );
00047 setLineWidth( 0 );
00048 d->moveCursorOnMouseRelease = true;
00049 KexiTableView::Appearance a(appearance());
00050 a.navigatorEnabled = false;
00052 a.backgroundAltering = false;
00053 a.fullRowSelection = true;
00054 a.rowHighlightingEnabled = true;
00055 a.rowMouseOverHighlightingEnabled = true;
00056 a.persistentSelections = false;
00057 a.rowMouseOverHighlightingColor = colorGroup().highlight();
00058 a.rowMouseOverHighlightingTextColor = colorGroup().highlightedText();
00059 a.rowHighlightingTextColor = a.rowMouseOverHighlightingTextColor;
00060 a.gridEnabled = false;
00061 setAppearance(a);
00062 setInsertingEnabled( false );
00063 setSortingEnabled( false );
00064 setVerticalHeaderVisible( false );
00065 setHorizontalHeaderVisible( false );
00066 setContextMenuEnabled( false );
00067 setScrollbarToolTipsEnabled( false );
00068 installEventFilter(this);
00069 setBottomMarginInternal( - horizontalScrollBar()->sizeHint().height() );
00070 }
00071 virtual void setData( KexiTableViewData *data, bool owner = true )
00072 { KexiTableView::setData( data, owner ); }
00073 bool setData(KexiDB::Cursor *cursor)
00074 { return KexiDataTableView::setData( cursor ); }
00075 };
00076
00077
00078
00080 class KexiComboBoxPopupPrivate
00081 {
00082 public:
00083 KexiComboBoxPopupPrivate()
00084 : int_f(0)
00085 {
00086 max_rows = KexiComboBoxPopup::defaultMaxRows;
00087 }
00088 ~KexiComboBoxPopupPrivate() {
00089 delete int_f;
00090 }
00091
00092 KexiComboBoxPopup_KexiTableView *tv;
00093 KexiDB::Field *int_f;
00094 int max_rows;
00095 };
00096
00097
00098
00099 const int KexiComboBoxPopup::defaultMaxRows = 8;
00100
00101 KexiComboBoxPopup::KexiComboBoxPopup(QWidget* parent, KexiTableViewColumn &column)
00102 : QFrame( parent, "KexiComboBoxPopup", WType_Popup )
00103 {
00104 init();
00105
00106 setData(&column, 0);
00107 }
00108
00109 KexiComboBoxPopup::KexiComboBoxPopup(QWidget* parent, KexiDB::Field &field)
00110 : QFrame( parent, "KexiComboBoxPopup", WType_Popup )
00111 {
00112 init();
00113
00114 setData(0, &field);
00115 }
00116
00117 KexiComboBoxPopup::~KexiComboBoxPopup()
00118 {
00119 delete d;
00120 }
00121
00122 void KexiComboBoxPopup::init()
00123 {
00124 d = new KexiComboBoxPopupPrivate();
00125 setPaletteBackgroundColor(palette().color(QPalette::Active,QColorGroup::Base));
00126 setLineWidth( 1 );
00127 setFrameStyle( Box | Plain );
00128
00129 d->tv = new KexiComboBoxPopup_KexiTableView(this);
00130 installEventFilter(this);
00131
00132 connect(d->tv, SIGNAL(itemReturnPressed(KexiTableItem*,int,int)),
00133 this, SLOT(slotTVItemAccepted(KexiTableItem*,int,int)));
00134
00135 connect(d->tv, SIGNAL(itemMouseReleased(KexiTableItem*,int,int)),
00136 this, SLOT(slotTVItemAccepted(KexiTableItem*,int,int)));
00137
00138 connect(d->tv, SIGNAL(itemDblClicked(KexiTableItem*,int,int)),
00139 this, SLOT(slotTVItemAccepted(KexiTableItem*,int,int)));
00140 }
00141
00142 void KexiComboBoxPopup::setData(KexiTableViewColumn *column, KexiDB::Field *field)
00143 {
00144 if (column && !field)
00145 field = column->field();
00146 if (!field) {
00147 kexiwarn << "KexiComboBoxPopup::setData(): !field" << endl;
00148 return;
00149 }
00150
00151
00152 if (column && column->relatedData()) {
00153 d->tv->setColumnStretchEnabled( true, -1 );
00154 setDataInternal( column->relatedData(), false );
00155 return;
00156 }
00157
00158
00159 KexiDB::LookupFieldSchema *lookupFieldSchema = 0;
00160 if (field->table())
00161 lookupFieldSchema = field->table()->lookupFieldSchema( *field );
00162 if (lookupFieldSchema) {
00164 KexiDB::Cursor *cursor = 0;
00165 switch (lookupFieldSchema->rowSource().type()) {
00166 case KexiDB::LookupFieldSchema::RowSource::Table: {
00167 KexiDB::TableSchema *lookupTable
00168 = field->table()->connection()->tableSchema( lookupFieldSchema->rowSource().name() );
00169 if (!lookupTable)
00171 return;
00172 cursor = field->table()->connection()->prepareQuery( *lookupTable );
00173 break;
00174 }
00175 case KexiDB::LookupFieldSchema::RowSource::Query: {
00176 KexiDB::QuerySchema *lookupQuery
00177 = field->table()->connection()->querySchema( lookupFieldSchema->rowSource().name() );
00178 if (!lookupQuery)
00180 return;
00181 cursor = field->table()->connection()->prepareQuery( *lookupQuery );
00182 break;
00183 }
00184 default:;
00185 }
00186 if (!cursor)
00188 return;
00189
00190 if (d->tv->data())
00191 d->tv->data()->disconnect( this );
00192 d->tv->setData( cursor );
00193
00194 connect( d->tv, SIGNAL(dataRefreshed()), this, SLOT(slotDataReloadRequested()));
00195 updateSize();
00196 return;
00197 }
00198
00199 kdWarning() << "KexiComboBoxPopup::setData(KexiTableViewColumn &): no column relatedData \n - moving to setData(KexiDB::Field &)" << endl;
00200
00201
00202 d->tv->setColumnStretchEnabled( true, -1 );
00203
00205 d->int_f = new KexiDB::Field(field->name(), KexiDB::Field::Text);
00206 KexiTableViewData *data = new KexiTableViewData();
00207 data->addColumn( new KexiTableViewColumn( *d->int_f ) );
00208 QValueVector<QString> hints = field->enumHints();
00209 for(uint i=0; i < hints.size(); i++) {
00210 KexiTableItem *item = data->createItem();
00211 (*item)[0]=QVariant(hints[i]);
00212 kdDebug() << "added: '" << hints[i] <<"'"<<endl;
00213 data->append( item );
00214 }
00215 setDataInternal( data, true );
00216 }
00217
00218 void KexiComboBoxPopup::setDataInternal( KexiTableViewData *data, bool owner )
00219 {
00220 if (d->tv->data())
00221 d->tv->data()->disconnect( this );
00222 d->tv->setData( data, owner );
00223 connect( d->tv, SIGNAL(dataRefreshed()), this, SLOT(slotDataReloadRequested()));
00224
00225 updateSize();
00226 }
00227
00228 void KexiComboBoxPopup::updateSize(int minWidth)
00229 {
00230 const int rows = QMIN( d->max_rows, d->tv->rows() );
00231
00232 d->tv->adjustColumnWidthToContents(-1);
00233
00234 KexiTableEdit *te = dynamic_cast<KexiTableEdit*>(parentWidget());
00235 const int width = QMAX( d->tv->tableSize().width(),
00236 (te ? te->totalSize().width() : (parentWidget()?parentWidget()->width():0)) );
00237 kexidbg << "KexiComboBoxPopup::updateSize(): size=" << size() << endl;
00238 resize( QMAX(minWidth, width) , d->tv->rowHeight() * rows +2 );
00239 kexidbg << "KexiComboBoxPopup::updateSize(): size after=" << size() << endl;
00240
00241
00242 d->tv->setColumnStretchEnabled(true, d->tv->columns()-1);
00243 }
00244
00245 KexiTableView* KexiComboBoxPopup::tableView()
00246 {
00247 return d->tv;
00248 }
00249
00250 void KexiComboBoxPopup::resize( int w, int h )
00251 {
00252 d->tv->horizontalScrollBar()->hide();
00253 d->tv->verticalScrollBar()->hide();
00254 d->tv->move(1,1);
00255 d->tv->resize( w-2, h-2 );
00256 QFrame::resize(w,h);
00257 update();
00258 updateGeometry();
00259 }
00260
00261 void KexiComboBoxPopup::setMaxRows(int r)
00262 {
00263 d->max_rows = r;
00264 }
00265
00266 int KexiComboBoxPopup::maxRows() const
00267 {
00268 return d->max_rows;
00269 }
00270
00271 void KexiComboBoxPopup::slotTVItemAccepted(KexiTableItem *item, int row, int)
00272 {
00273 hide();
00274 emit rowAccepted(item, row);
00275 }
00276
00277 bool KexiComboBoxPopup::eventFilter( QObject *o, QEvent *e )
00278 {
00279 if (o==this && e->type()==QEvent::Hide) {
00280 emit hidden();
00281 }
00282 else if (e->type()==QEvent::MouseButtonPress) {
00283 kdDebug() << "QEvent::MousePress" << endl;
00284 }
00285 else if (o==d->tv) {
00286 if (e->type()==QEvent::KeyPress) {
00287 QKeyEvent *ke = static_cast<QKeyEvent*>(e);
00288 const int k = ke->key();
00289 if ((ke->state()==NoButton && (k==Key_Escape || k==Key_F4))
00290 || (ke->state()==AltButton && k==Key_Up))
00291 {
00292 hide();
00293 emit cancelled();
00294 return true;
00295 }
00296 }
00297 }
00298 return QFrame::eventFilter( o, e );
00299 }
00300
00301 void KexiComboBoxPopup::slotDataReloadRequested()
00302 {
00303 updateSize();
00304 }
00305
00306 #include "kexicomboboxpopup.moc"