00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qtoolbutton.h>
00022 #include <qlayout.h>
00023 #include <qlabel.h>
00024 #include <qvalidator.h>
00025 #include <qtooltip.h>
00026 #include <qscrollview.h>
00027
00028 #include <klocale.h>
00029 #include <kiconloader.h>
00030 #include <klineedit.h>
00031
00032 #include "kexirecordnavigator.h"
00033 #include "kexirecordmarker.h"
00034
00036 class KexiRecordNavigatorPrivate
00037 {
00038 public:
00039 KexiRecordNavigatorPrivate()
00040 : handler(0)
00041 , editingIndicatorLabel(0)
00042 , editingIndicatorEnabled(false)
00043 , editingIndicatorVisible(false)
00044 {
00045 }
00046 KexiRecordNavigatorHandler *handler;
00047 QHBoxLayout *lyr;
00048
00049 QLabel *editingIndicatorLabel;
00050 bool editingIndicatorEnabled : 1;
00051 bool editingIndicatorVisible : 1;
00052 };
00053
00054
00055
00056 KexiRecordNavigatorHandler::KexiRecordNavigatorHandler()
00057 {
00058 }
00059
00060 KexiRecordNavigatorHandler::~KexiRecordNavigatorHandler()
00061 {
00062 }
00063
00064
00065
00066 KexiRecordNavigator::KexiRecordNavigator(QWidget *parent, int leftMargin, const char *name)
00067 : QFrame(parent, name)
00068 , m_view(0)
00069 , m_isInsertingEnabled(true)
00070 , d( new KexiRecordNavigatorPrivate() )
00071 {
00072 if (parent->inherits("QScrollView"))
00073 setParentView( dynamic_cast<QScrollView*>(parent) );
00074 setFrameStyle(QFrame::NoFrame);
00075 d->lyr = new QHBoxLayout(this,0,0,"nav_lyr");
00076
00077 m_textLabel = new QLabel(this);
00078 d->lyr->addWidget( m_textLabel );
00079 setLabelText(i18n("Row:"));
00080
00081 int bw = 6+SmallIcon("navigator_first").width();
00082 QFont f = font();
00083 f.setPixelSize((bw > 12) ? 12 : bw);
00084 QFontMetrics fm(f);
00085 m_nav1DigitWidth = fm.width("8");
00086
00087 d->lyr->addWidget( m_navBtnFirst = new QToolButton(this) );
00088 m_navBtnFirst->setFixedWidth(bw);
00089 m_navBtnFirst->setFocusPolicy(NoFocus);
00090 m_navBtnFirst->setIconSet( SmallIconSet("navigator_first") );
00091 QToolTip::add(m_navBtnFirst, i18n("First row"));
00092
00093 d->lyr->addWidget( m_navBtnPrev = new QToolButton(this) );
00094 m_navBtnPrev->setFixedWidth(bw);
00095 m_navBtnPrev->setFocusPolicy(NoFocus);
00096 m_navBtnPrev->setIconSet( SmallIconSet("navigator_prev") );
00097 m_navBtnPrev->setAutoRepeat(true);
00098 QToolTip::add(m_navBtnPrev, i18n("Previous row"));
00099
00100 d->lyr->addSpacing( 6 );
00101
00102 d->lyr->addWidget( m_navRecordNumber = new KLineEdit(this) );
00103 m_navRecordNumber->setAlignment(AlignRight | AlignVCenter);
00104 m_navRecordNumber->setFocusPolicy(ClickFocus);
00105 m_navRecordNumber->installEventFilter(this);
00106
00107 m_navRecordNumberValidator = new QIntValidator(1, INT_MAX, this);
00108 m_navRecordNumber->setValidator(m_navRecordNumberValidator);
00109 m_navRecordNumber->installEventFilter(this);
00110 QToolTip::add(m_navRecordNumber, i18n("Current row number"));
00111
00112 KLineEdit *lbl_of = new KLineEdit(i18n("of"), this);
00113 lbl_of->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Preferred);
00114 lbl_of->setMaximumWidth(fm.width(lbl_of->text())+8);
00115 lbl_of->setReadOnly(true);
00116 lbl_of->setLineWidth(0);
00117 lbl_of->setFocusPolicy(NoFocus);
00118 lbl_of->setAlignment(AlignCenter);
00119 d->lyr->addWidget( lbl_of );
00120
00121 d->lyr->addWidget( m_navRecordCount = new KLineEdit(this) );
00122 m_navRecordCount->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Preferred);
00123 m_navRecordCount->setReadOnly(true);
00124 m_navRecordCount->setLineWidth(0);
00125 m_navRecordCount->setFocusPolicy(NoFocus);
00126 m_navRecordCount->setAlignment(AlignLeft | AlignVCenter);
00127 QToolTip::add(m_navRecordCount, i18n("Number of rows"));
00128
00129 lbl_of->setFont(f);
00130 m_navRecordNumber->setFont(f);
00131 m_navRecordCount->setFont(f);
00132 setFont(f);
00133
00134 d->lyr->addWidget( m_navBtnNext = new QToolButton(this) );
00135 m_navBtnNext->setFixedWidth(bw);
00136 m_navBtnNext->setFocusPolicy(NoFocus);
00137 m_navBtnNext->setIconSet( SmallIconSet("navigator_next") );
00138 m_navBtnNext->setAutoRepeat(true);
00139 QToolTip::add(m_navBtnNext, i18n("Next row"));
00140
00141 d->lyr->addWidget( m_navBtnLast = new QToolButton(this) );
00142 m_navBtnLast->setFixedWidth(bw);
00143 m_navBtnLast->setFocusPolicy(NoFocus);
00144 m_navBtnLast->setIconSet( SmallIconSet("navigator_last") );
00145 QToolTip::add(m_navBtnLast, i18n("Last row"));
00146
00147 d->lyr->addSpacing( 6 );
00148 d->lyr->addWidget( m_navBtnNew = new QToolButton(this) );
00149 m_navBtnNew->setFixedWidth(bw);
00150 m_navBtnNew->setFocusPolicy(NoFocus);
00151 m_navBtnNew->setIconSet( SmallIconSet("navigator_new") );
00152 QToolTip::add(m_navBtnNew, i18n("New row"));
00153 m_navBtnNext->setEnabled(isInsertingEnabled());
00154
00155 d->lyr->addSpacing( 6 );
00156 d->lyr->addStretch(10);
00157
00158 connect(m_navBtnPrev,SIGNAL(clicked()),this,SLOT(slotPrevButtonClicked()));
00159 connect(m_navBtnNext,SIGNAL(clicked()),this,SLOT(slotNextButtonClicked()));
00160 connect(m_navBtnLast,SIGNAL(clicked()),this,SLOT(slotLastButtonClicked()));
00161 connect(m_navBtnFirst,SIGNAL(clicked()),this,SLOT(slotFirstButtonClicked()));
00162 connect(m_navBtnNew,SIGNAL(clicked()),this,SLOT(slotNewButtonClicked()));
00163
00164 setRecordCount(0);
00165 setCurrentRecordNumber(0);
00166
00167 updateGeometry(leftMargin);
00168 }
00169
00170 KexiRecordNavigator::~KexiRecordNavigator()
00171 {
00172 delete d;
00173 }
00174
00175 void KexiRecordNavigator::setInsertingEnabled(bool set)
00176 {
00177 if (m_isInsertingEnabled==set)
00178 return;
00179 m_isInsertingEnabled = set;
00180 if (isEnabled())
00181 m_navBtnNew->setEnabled( m_isInsertingEnabled );
00182 }
00183
00184 void KexiRecordNavigator::setEnabled( bool set )
00185 {
00186 QFrame::setEnabled(set);
00187 if (set && !m_isInsertingEnabled)
00188 m_navBtnNew->setEnabled( false );
00189 }
00190
00191 bool KexiRecordNavigator::eventFilter( QObject *o, QEvent *e )
00192 {
00193 if (o==m_navRecordNumber) {
00194 bool recordEntered = false;
00195 bool ret;
00196 if (e->type()==QEvent::KeyPress) {
00197 QKeyEvent *ke = static_cast<QKeyEvent*>(e);
00198 switch (ke->key()) {
00199 case Qt::Key_Escape: {
00200 ke->accept();
00201 m_navRecordNumber->undo();
00202 if (m_view)
00203 m_view->setFocus();
00204 return true;
00205 }
00206 case Qt::Key_Enter:
00207 case Qt::Key_Return:
00208 case Qt::Key_Tab:
00209 case Qt::Key_BackTab:
00210 {
00211 recordEntered=true;
00212 ke->accept();
00213 ret = true;
00214 }
00215 default:;
00216 }
00217 }
00218 else if (e->type()==QEvent::FocusOut) {
00219 if (static_cast<QFocusEvent*>(e)->reason()!=QFocusEvent::Tab
00220 && static_cast<QFocusEvent*>(e)->reason()!=QFocusEvent::Backtab
00221 && static_cast<QFocusEvent*>(e)->reason()!=QFocusEvent::Other)
00222 recordEntered=true;
00223 ret = false;
00224 }
00225
00226 if (recordEntered) {
00227 bool ok=true;
00228 uint r = m_navRecordNumber->text().toUInt(&ok);
00229 if (!ok || r<1)
00230 r = (recordCount()>0)?1:0;
00231 if (m_view && (hasFocus() || e->type()==QEvent::KeyPress))
00232 m_view->setFocus();
00233 setCurrentRecordNumber(r);
00234 emit recordNumberEntered(r);
00235 if (d->handler)
00236 d->handler->moveToRecordRequested(r-1);
00237 return ret;
00238 }
00239 }
00240
00241
00242
00243
00244
00245
00246 return false;
00247 }
00248
00249 void KexiRecordNavigator::setCurrentRecordNumber(uint r)
00250 {
00251 uint recCnt = recordCount();
00252 if (r>(recCnt+(m_isInsertingEnabled?1:0)))
00253 r = recCnt+(m_isInsertingEnabled?1:0);
00254 QString n;
00255 if (r>0)
00256 n = QString::number(r);
00257 else
00258 n = " ";
00259
00260
00261
00262
00263
00264
00265 m_navRecordNumber->setText(n);
00266 m_navRecordCount->deselect();
00267 updateButtons(recCnt);
00268 }
00269
00270 void KexiRecordNavigator::updateButtons(uint recCnt)
00271 {
00272 const uint r = currentRecordNumber();
00273 if (isEnabled()) {
00274 m_navBtnPrev->setEnabled(r > 1);
00275 m_navBtnFirst->setEnabled(r > 1);
00276 m_navBtnNext->setEnabled(r > 0
00277 && r < (recCnt +(m_isInsertingEnabled?(1+d->editingIndicatorVisible):0) ) );
00278 m_navBtnLast->setEnabled(r!=(recCnt+(m_isInsertingEnabled?1:0)) && (m_isInsertingEnabled || recCnt>0));
00279 }
00280 }
00281
00282 void KexiRecordNavigator::setRecordCount(uint count)
00283 {
00284 const QString & n = QString::number(count);
00285 if (m_isInsertingEnabled && currentRecordNumber()==0) {
00286 setCurrentRecordNumber(1);
00287 }
00288 if (m_navRecordCount->text().length() != n.length()) {
00289 m_navRecordCount->setFixedWidth(m_nav1DigitWidth*n.length()+6);
00290
00291 if (m_view && m_view->horizontalScrollBar()->isVisible()) {
00292
00293 resize(width()+(n.length()-m_navRecordCount->text().length())*m_nav1DigitWidth, height());
00294
00295 }
00296 }
00297
00298 const int w = m_nav1DigitWidth*QMAX( QMAX(n.length(),2)+1,m_navRecordNumber->text().length()+1)+6;
00299 if (m_navRecordNumber->width()!=w)
00300 m_navRecordNumber->setFixedWidth(w);
00301
00302 m_navRecordCount->setText(n);
00303 m_navRecordCount->deselect();
00304 if (m_view)
00305 m_view->updateScrollBars();
00306 updateButtons(recordCount());
00307 }
00308
00309 uint KexiRecordNavigator::currentRecordNumber() const
00310 {
00311 bool ok=true;
00312 int r = m_navRecordNumber->text().toInt(&ok);
00313 if (!ok || r<1)
00314 r = 0;
00315 return r;
00316 }
00317
00318 uint KexiRecordNavigator::recordCount() const
00319 {
00320 bool ok=true;
00321 int r = m_navRecordCount->text().toInt(&ok);
00322 if (!ok || r<1)
00323 r = 0;
00324 return r;
00325 }
00326
00327 void KexiRecordNavigator::setParentView(QScrollView *view)
00328 {
00329 m_view = view;
00330 }
00331
00332 void KexiRecordNavigator::updateGeometry(int leftMargin)
00333 {
00334 QFrame::updateGeometry();
00335 if (m_view) {
00336 int navWidth;
00337 if (m_view->horizontalScrollBar()->isVisible()) {
00338 navWidth = sizeHint().width();
00339 }
00340 else {
00341 navWidth = leftMargin + m_view->clipper()->width();
00342 }
00343
00344 setGeometry(
00345 m_view->frameWidth(),
00346 m_view->height() - m_view->horizontalScrollBar()->sizeHint().height()-m_view->frameWidth(),
00347 navWidth,
00348 m_view->horizontalScrollBar()->sizeHint().height()
00349 );
00350
00351 m_view->updateScrollBars();
00352 }
00353 }
00354
00355 void KexiRecordNavigator::setHBarGeometry( QScrollBar & hbar, int x, int y, int w, int h )
00356 {
00357 hbar.setGeometry( x + width(), y, w - width(), h );
00358 }
00359
00360 void KexiRecordNavigator::setLabelText(const QString& text)
00361 {
00362 m_textLabel->setText(text.isEmpty() ? QString::null : (QString::fromLatin1(" ")+text+" "));
00363 }
00364
00365 void KexiRecordNavigator::setInsertingButtonVisible(bool set)
00366 {
00367 if (set)
00368 m_navBtnNew->show();
00369 else
00370 m_navBtnNew->hide();
00371 }
00372
00373 void KexiRecordNavigator::slotPrevButtonClicked()
00374 {
00375 emit prevButtonClicked();
00376 if (d->handler)
00377 d->handler->moveToPreviousRecordRequested();
00378 }
00379
00380 void KexiRecordNavigator::slotNextButtonClicked()
00381 {
00382 emit nextButtonClicked();
00383 if (d->handler)
00384 d->handler->moveToNextRecordRequested();
00385 }
00386
00387 void KexiRecordNavigator::slotLastButtonClicked()
00388 {
00389 emit lastButtonClicked();
00390 if (d->handler)
00391 d->handler->moveToLastRecordRequested();
00392 }
00393
00394 void KexiRecordNavigator::slotFirstButtonClicked()
00395 {
00396 emit firstButtonClicked();
00397 if (d->handler)
00398 d->handler->moveToFirstRecordRequested();
00399 }
00400
00401 void KexiRecordNavigator::slotNewButtonClicked()
00402 {
00403 emit newButtonClicked();
00404 if (d->handler)
00405 d->handler->addNewRecordRequested();
00406 }
00407
00408
00409 void KexiRecordNavigator::setRecordHandler(KexiRecordNavigatorHandler *handler)
00410 {
00411 d->handler = handler;
00412 }
00413
00414 bool KexiRecordNavigator::editingIndicatorVisible() const
00415 {
00416 return d->editingIndicatorVisible;
00417 }
00418
00419 bool KexiRecordNavigator::editingIndicatorEnabled() const
00420 {
00421 return d->editingIndicatorEnabled;
00422 }
00423
00424 void KexiRecordNavigator::setEditingIndicatorEnabled(bool set)
00425 {
00426 d->editingIndicatorEnabled = set;
00427 if (d->editingIndicatorEnabled) {
00428 if (!d->editingIndicatorLabel) {
00429 d->editingIndicatorLabel = new QLabel(this);
00430 d->editingIndicatorLabel->setAlignment(Qt::AlignCenter);
00431 QPixmap pix;
00432 pix.convertFromImage( *KexiRecordMarker::penImage() );
00433 d->editingIndicatorLabel->setFixedWidth( pix.width() + 2*2 );
00434 d->lyr->insertWidget( 0, d->editingIndicatorLabel );
00435 }
00436 d->editingIndicatorLabel->show();
00437 }
00438 else {
00439 if (d->editingIndicatorLabel) {
00440 d->editingIndicatorLabel->hide();
00441 }
00442 }
00443 }
00444
00445 void KexiRecordNavigator::showEditingIndicator(bool show)
00446 {
00447 d->editingIndicatorVisible = show;
00448 updateButtons(recordCount());
00449 if (!d->editingIndicatorEnabled)
00450 return;
00451 if (d->editingIndicatorVisible) {
00452 QPixmap pix;
00453 pix.convertFromImage( *KexiRecordMarker::penImage() );
00454 d->editingIndicatorLabel->setPixmap( pix );
00455 QToolTip::add( d->editingIndicatorLabel, i18n("Editing indicator") );
00456 }
00457 else {
00458 d->editingIndicatorLabel->setPixmap( QPixmap() );
00459 QToolTip::remove( d->editingIndicatorLabel );
00460 }
00461 }
00462
00463 #include "kexirecordnavigator.moc"