kexi

kexicomboboxpopup.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This program is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this program; see the file COPYING.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
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; //TODO: remove this -temporary
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     //setup tv data
00106     setData(&column, 0);
00107 }
00108 
00109 KexiComboBoxPopup::KexiComboBoxPopup(QWidget* parent, KexiDB::Field &field)
00110  : QFrame( parent, "KexiComboBoxPopup", WType_Popup )
00111 {
00112     init();
00113     //setup tv data
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     // case 1: simple related data
00152     if (column && column->relatedData()) {
00153         d->tv->setColumnStretchEnabled( true, -1 ); //only needed when using single column
00154         setDataInternal( column->relatedData(), false  );
00155         return;
00156     }
00157 
00158     // case 2: lookup field
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     // case 3: enum hints
00202     d->tv->setColumnStretchEnabled( true, -1 ); //only needed when using single column
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();//new KexiTableItem(1);
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/*sanity*/)) );
00237     kexidbg << "KexiComboBoxPopup::updateSize(): size=" << size() << endl;
00238     resize( QMAX(minWidth, width)/*+(d->tv->columns()>1?2:0)*/ /*(d->updateSizeCalled?0:1)*/, d->tv->rowHeight() * rows +2 );
00239     kexidbg << "KexiComboBoxPopup::updateSize(): size after=" << size() << endl;
00240 
00241     //stretch the last column
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"
KDE Home | KDE Accessibility Home | Description of Access Keys