00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kexiinputtableedit.h"
00022
00023 #include <kexidb/field.h>
00024
00025 #include <qregexp.h>
00026 #include <qevent.h>
00027 #include <qlayout.h>
00028 #include <qtimer.h>
00029 #include <qpainter.h>
00030 #include <qapplication.h>
00031 #include <qclipboard.h>
00032 #include <qtooltip.h>
00033
00034 #include <kglobal.h>
00035 #include <klocale.h>
00036 #include <kdebug.h>
00037 #include <kglobalsettings.h>
00038 #include <kcompletionbox.h>
00039 #include <knumvalidator.h>
00040 #include <kexiutils/longlongvalidator.h>
00041
00043 class MyLineEdit : public KLineEdit
00044 {
00045 public:
00046 MyLineEdit(QWidget *parent, const char *name) : KLineEdit(parent,name)
00047 {}
00048 protected:
00049 virtual void drawFrame ( QPainter * p ) {
00050 p->setPen( QPen( colorGroup().text() ) );
00051 QRect r = rect();
00052 p->moveTo( r.topLeft() );
00053 p->lineTo( r.topRight() );
00054 p->lineTo( r.bottomRight() );
00055 p->lineTo( r.bottomLeft() );
00056 if (pos().x() == 0)
00057 p->lineTo( r.topLeft() );
00058 }
00059 };
00060
00061
00062
00063 KexiInputTableEdit::KexiInputTableEdit(KexiTableViewColumn &column, QWidget *parent)
00064 : KexiTableEdit(column, parent)
00065 {
00066 setName("KexiInputTableEdit");
00067
00068
00069
00070 init();
00071 }
00072
00073 KexiInputTableEdit::~KexiInputTableEdit()
00074 {
00075 }
00076
00077 void KexiInputTableEdit::init()
00078 {
00079 kdDebug() << "KexiInputTableEdit: m_origValue.typeName()==" << m_origValue.typeName() << endl;
00080 kdDebug() << "KexiInputTableEdit: type== " << field()->typeName() << endl;
00081 kdDebug() << "KexiInputTableEdit: displayed type== " << displayedField()->typeName() << endl;
00082
00083
00084 m_decsym = KGlobal::locale()->decimalSymbol();
00085 if (m_decsym.isEmpty())
00086 m_decsym=".";
00087
00088 const bool align_right = displayedField()->isNumericType();
00089
00090 if (!align_right) {
00091
00092 QHBoxLayout *lyr = new QHBoxLayout(this);
00093 lyr->addSpacing(4);
00094 lyr->setAutoAdd(true);
00095 }
00096
00097
00098 m_lineedit = new MyLineEdit(this, "KexiInputTableEdit-KLineEdit");
00099 setViewWidget(m_lineedit);
00100 if (align_right)
00101 m_lineedit->setAlignment(AlignRight);
00102
00103
00104
00105 m_calculatedCell = false;
00106
00107 #if 0 //js TODO
00108 connect(m_cview->completionBox(), SIGNAL(activated(const QString &)),
00109 this, SLOT(completed(const QString &)));
00110 connect(m_cview->completionBox(), SIGNAL(highlighted(const QString &)),
00111 this, SLOT(completed(const QString &)));
00112 m_cview->completionBox()->setTabHandling(true);
00113 #endif
00114
00115 }
00116
00117 void KexiInputTableEdit::setValueInternal(const QVariant& add, bool removeOld)
00118 {
00119 QString text( valueToText(removeOld ? QVariant() : m_origValue, add.toString(), true) );
00120
00121 if (text.isEmpty()) {
00122 if (m_origValue.toString().isEmpty()) {
00123
00124 m_lineedit->setText(QString::null);
00125 }
00126 }
00127 else {
00128 m_lineedit->setText(text);
00129 }
00130
00131 #if 0
00132
00133 m_cview->selectAll();
00134 #else
00135
00136 m_lineedit->end(false);
00137 #endif
00138 }
00139
00140 QString KexiInputTableEdit::valueToText(const QVariant& value, const QString& add, bool setValidator)
00141 {
00142 QString text;
00143
00144 if (field()->isFPNumericType()) {
00147 text = QString::number(value.toDouble(), 'f',
00148 QMAX(field()->visibleDecimalPlaces(), 10));
00150 if (value.toDouble() == 0.0) {
00151 text = add.isEmpty() ? "0" : add;
00152 }
00153 else {
00155 QStringList sl = QStringList::split(".", text);
00156 if (text.isEmpty()) {
00157
00158 }
00159 else if (sl.count()==2) {
00160 kdDebug() << "sl.count()=="<<sl.count()<< " " <<sl[0] << " | " << sl[1] << endl;
00161 const QString sl1 = sl[1];
00162 int pos = sl1.length()-1;
00163 if (pos>=1) {
00164 for (;pos>=0 && sl1[pos]=='0';pos--)
00165 ;
00166 pos++;
00167 }
00168 if (pos>0)
00169 text = sl[0] + m_decsym + sl1.left(pos);
00170 else
00171 text = sl[0];
00172 }
00173 text += add;
00174 }
00175 if (setValidator) {
00176 QValidator *validator = new KDoubleValidator(m_lineedit);
00177 m_lineedit->setValidator( validator );
00178 }
00179 }
00180 else {
00181 text = value.toString();
00182 if (field()->isIntegerType()) {
00183 if (value.toInt() == 0) {
00184 text = add;
00185 }
00186 else {
00187 text += add;
00188 }
00190 if (setValidator) {
00191 QValidator *validator;
00192 if (KexiDB::Field::BigInteger == field()->type()) {
00194 validator = new KexiUtils::LongLongValidator(m_lineedit);
00195 }
00196 else {
00197 validator = new KIntValidator(m_lineedit);
00198 }
00199 m_lineedit->setValidator( validator );
00200 }
00201 }
00202 else {
00203 text += add;
00204 }
00205 }
00206
00207 return text;
00208 }
00209
00210 void KexiInputTableEdit::paintEvent ( QPaintEvent * )
00211 {
00212 QPainter p(this);
00213 p.setPen( QPen( colorGroup().text() ) );
00214 p.drawRect( rect() );
00215 }
00216
00217 void
00218 KexiInputTableEdit::setRestrictedCompletion()
00219 {
00220 #if 0 //js TODO
00221 kdDebug() << "KexiInputTableEdit::setRestrictedCompletion()" << endl;
00222
00223 if(m_cview->text().isEmpty())
00224 return;
00225
00226 kdDebug() << "KexiInputTableEdit::setRestrictedCompletion(): something to do" << endl;
00227
00228 m_cview->useGlobalKeyBindings();
00229
00230 QStringList newC;
00231 QStringList::ConstIterator it, end( m_comp.constEnd() );
00232 for( it = m_comp.constBegin(); it != end; ++it)
00233 {
00234 if((*it).startsWith(m_cview->text()))
00235 newC.append(*it);
00236 }
00237 m_cview->setCompletedItems(newC);
00238 #endif
00239 }
00240
00241 void
00242 KexiInputTableEdit::completed(const QString &s)
00243 {
00244 kdDebug() << "KexiInputTableEdit::completed(): " << s << endl;
00245 m_lineedit->setText(s);
00246 }
00247
00248 bool KexiInputTableEdit::valueChanged()
00249 {
00250
00251
00252 return KexiTableEdit::valueChanged();
00253 }
00254
00255 bool KexiInputTableEdit::valueIsNull()
00256 {
00257 return m_lineedit->text().isNull();
00258 }
00259
00260 bool KexiInputTableEdit::valueIsEmpty()
00261 {
00262 return !m_lineedit->text().isNull() && m_lineedit->text().isEmpty();
00263 }
00264
00265 QVariant KexiInputTableEdit::value()
00266 {
00267 if (field()->isFPNumericType()) {
00269 QString txt = m_lineedit->text();
00270 if (m_decsym!=".")
00271 txt = txt.replace(m_decsym,".");
00272 bool ok;
00273 const double result = txt.toDouble(&ok);
00274 return ok ? QVariant(result) : QVariant();
00275 }
00276 else if (field()->isIntegerType()) {
00278 bool ok;
00279 if (KexiDB::Field::BigInteger == field()->type()) {
00280 if (field()->isUnsigned()) {
00281 const Q_ULLONG result = m_lineedit->text().toULongLong(&ok);
00282 return ok ? QVariant(result) : QVariant();
00283 }
00284 else {
00285 const Q_LLONG result = m_lineedit->text().toLongLong(&ok);
00286 return ok ? QVariant(result) : QVariant();
00287 }
00288 }
00289 if (KexiDB::Field::Integer == field()->type()) {
00290 if (field()->isUnsigned()) {
00291 const uint result = m_lineedit->text().toUInt(&ok);
00292 return ok ? QVariant(result) : QVariant();
00293 }
00294 }
00295
00296 const int result = m_lineedit->text().toInt(&ok);
00297 return ok ? QVariant(result) : QVariant();
00298 }
00299
00300 return QVariant( m_lineedit->text() );
00301 }
00302 #if 0
00303
00304 QString v;
00305 switch(m_type)
00306 {
00307 case QVariant::UInt:
00308 case QVariant::Int:
00309 case QVariant::Double:
00310
00311 if(!m_calculatedCell)
00312 {
00313 v = m_cview->text().replace(QRegExp("\\" + KGlobal::locale()->thousandsSeparator()), "");
00314 v = v.replace(QRegExp("\\" + KGlobal::locale()->decimalSymbol()), ".");
00315 v = v.replace(QRegExp("\\" + KGlobal::locale()->negativeSign()), "-");
00316 kdDebug() << "KexiInputTableEdit::value() converting => " << v.latin1() << endl;
00317 return QVariant(v);
00318 }
00319 else
00320 {
00321
00322 kdDebug() << "KexiInputTableEdit::value() calculating..." << endl;
00323 double result = 0;
00324 QString real = m_cview->text().right(m_cview->text().length() - 1);
00325 real = real.replace(QRegExp("\\" + KGlobal::locale()->thousandsSeparator()), "");
00326 real = real.replace(QRegExp("\\" + KGlobal::locale()->decimalSymbol()), ".");
00327 QStringList values = QStringList::split(QRegExp("[\\+|\\*|\\/|-]"), real, false);
00328 QStringList ops = QStringList::split(QRegExp("[0-9]{1,8}(?:\\.[0-9]+)?"), real, false);
00329
00330 double lastValue = 0;
00331 QString lastOp = "";
00332 for(int i=0; i < (int)values.count(); i++)
00333 {
00334 double next;
00335
00336 QString op = QString((*ops.at(i))).stripWhiteSpace();
00337
00338 if(!((*values.at(i+1)).isEmpty()) && i == 0)
00339 {
00340 double local = (*values.at(i)).toDouble();
00341 next = (*values.at(i+1)).toDouble();
00342
00343 QString op = (*ops.at(i));
00344 if(op == "+")
00345 result = local + next;
00346 else if(op == "-")
00347 result = local - next;
00348 else if(op == "*")
00349 result = local * next;
00350 else
00351 result = local / next;
00352 }
00353 else if(!(*values.at(i+1)).isEmpty())
00354 {
00355 next = (*values.at(i+1)).toDouble();
00356
00357 QString op = QString((*ops.at(i))).stripWhiteSpace();
00358 if(op == "+")
00359 result = result + next;
00360 else if(op == "-")
00361 result = result - next;
00362 else if(op == "*")
00363 result = result * next;
00364 else
00365 result = result / next;
00366 }
00367
00368 }
00369
00370 return QVariant(result);
00371
00372 }
00373 break;
00374
00375 default:
00376 kdDebug() << "KexiInputTableEdit::value() default..." << endl;
00377 return QVariant(m_cview->text());
00378 }
00379
00380 void
00381 KexiInputTableEdit::end(bool mark)
00382 {
00383 m_cview->end(mark);
00384 }
00385
00386 void
00387 KexiInputTableEdit::backspace()
00388 {
00389 m_cview->backspace();
00390 }
00391 #endif
00392
00393
00394 void
00395 KexiInputTableEdit::clear()
00396 {
00397 m_lineedit->clear();
00398 }
00399
00400 bool KexiInputTableEdit::cursorAtStart()
00401 {
00402 return m_lineedit->cursorPosition()==0;
00403 }
00404
00405 bool KexiInputTableEdit::cursorAtEnd()
00406 {
00407 return m_lineedit->cursorPosition()==(int)m_lineedit->text().length();
00408 }
00409
00410 QSize KexiInputTableEdit::totalSize()
00411 {
00412 if (!m_lineedit)
00413 return size();
00414 return m_lineedit->size();
00415 }
00416
00417 void KexiInputTableEdit::handleCopyAction(const QVariant& value, const QVariant& visibleValue)
00418 {
00419 Q_UNUSED(visibleValue);
00421 qApp->clipboard()->setText( valueToText(value, QString::null) );
00422 }
00423
00424 void KexiInputTableEdit::handleAction(const QString& actionName)
00425 {
00426 const bool alreadyVisible = m_lineedit->isVisible();
00427
00428 if (actionName=="edit_paste") {
00429 if (!alreadyVisible) {
00430 emit editRequested();
00431 m_lineedit->clear();
00432 }
00433 m_lineedit->paste();
00434 }
00435 else if (actionName=="edit_cut") {
00437 if (!alreadyVisible) {
00438 emit editRequested();
00439 m_lineedit->selectAll();
00440 }
00441 m_lineedit->cut();
00442 }
00443 }
00444
00445 bool KexiInputTableEdit::showToolTipIfNeeded(const QVariant& value, const QRect& rect,
00446 const QFontMetrics& fm, bool focused)
00447 {
00448 QString text( value.type()==QVariant::String ? value.toString()
00449 : valueToText(value, QString::null, false ) );
00450 QRect internalRect(rect);
00451 internalRect.setLeft(rect.x()+leftMargin());
00452 internalRect.setWidth(internalRect.width()-rightMargin(focused)-2*3);
00453 kexidbg << rect << " " << internalRect << " " << fm.width(text) << endl;
00454 return fm.width(text) > internalRect.width();
00455 }
00456
00457 void KexiInputTableEdit::moveCursorToEnd()
00458 {
00459 m_lineedit->end(false);
00460 }
00461
00462 void KexiInputTableEdit::moveCursorToStart()
00463 {
00464 m_lineedit->home(false);
00465 }
00466
00467 void KexiInputTableEdit::selectAll()
00468 {
00469 m_lineedit->selectAll();
00470 }
00471
00472 KEXI_CELLEDITOR_FACTORY_ITEM_IMPL(KexiInputEditorFactoryItem, KexiInputTableEdit)
00473
00474 #include "kexiinputtableedit.moc"