/* This file is part of the KDE project Copyright (C) 2002 Lucijan Busch Copyright (C) 2003-2007 Jaroslaw Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kexiinputtableedit.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //! @internal class MyLineEdit : public KLineEdit { public: MyLineEdit(TQWidget *parent, const char *name) : KLineEdit(parent,name) {} protected: virtual void drawFrame ( TQPainter * p ) { p->setPen( TQPen( colorGroup().text() ) ); TQRect r = rect(); p->moveTo( r.topLeft() ); p->lineTo( r.topRight() ); p->lineTo( r.bottomRight() ); p->lineTo( r.bottomLeft() ); if (pos().x() == 0) //draw left side only when it is @ the edge p->lineTo( r.topLeft() ); } }; //====================================================== KexiInputTableEdit::KexiInputTableEdit(KexiTableViewColumn &column, TQWidget *parent) : KexiTableEdit(column, parent) { setName("KexiInputTableEdit"); // m_type = f.type(); //copied because the rest of code uses m_type // m_field = &f; // m_origValue = value;//original value init(); } KexiInputTableEdit::~KexiInputTableEdit() { } void KexiInputTableEdit::init() { // kdDebug() << "KexiInputTableEdit: m_origValue.typeName()==" << m_origValue.typeName() << endl; // kdDebug() << "KexiInputTableEdit: type== " << field()->typeName() << endl; // kdDebug() << "KexiInputTableEdit: displayed type== " << displayedField()->typeName() << endl; m_textFormatter.setField( field() ); //init settings m_decsym = TDEGlobal::locale()->decimalSymbol(); if (m_decsym.isEmpty()) m_decsym=".";//default const bool align_right = displayedField()->isNumericType(); if (!align_right) { //create layer for internal editor TQHBoxLayout *lyr = new TQHBoxLayout(this); lyr->addSpacing(4); lyr->setAutoAdd(true); } //create internal editor m_lineedit = new MyLineEdit(this, "KexiInputTableEdit-KLineEdit"); setViewWidget(m_lineedit); if (align_right) m_lineedit->setAlignment(AlignRight); // m_cview->setFrame(false); // m_cview->setFrameStyle( TQFrame::Plain | TQFrame::Box ); // m_cview->setLineWidth( 1 ); m_calculatedCell = false; #if 0 //js TODO connect(m_cview->completionBox(), TQT_SIGNAL(activated(const TQString &)), this, TQT_SLOT(completed(const TQString &))); connect(m_cview->completionBox(), TQT_SIGNAL(highlighted(const TQString &)), this, TQT_SLOT(completed(const TQString &))); m_cview->completionBox()->setTabHandling(true); #endif } void KexiInputTableEdit::setValueInternal(const TQVariant& add, bool removeOld) { TQString text( m_textFormatter.valueToText(removeOld ? TQVariant() : m_origValue, add.toString()) ); if (text.isEmpty()) { if (m_origValue.toString().isEmpty()) { //we have to set NULL initial value: m_lineedit->setText(TQString()); } } else { m_lineedit->setText(text); } #if 0 //move to end is better by default m_cview->selectAll(); #else //js TODO: by default we're moving to the end of editor, ADD OPTION allowing "select all chars" m_lineedit->end(false); #endif if (!m_lineedit->validator()) { TQValidator *validator = new KexiDB::FieldValidator( *field(), m_lineedit, "KexiInputTableEdit-validator"); m_lineedit->setValidator( validator ); } } #if 0 //moved to KexiTextFormatter TQString KexiInputTableEdit::valueToText(KexiDB::Field* field, const TQVariant& value, const TQString& add) { TQString text; //result if (field->isFPNumericType()) { //! @todo precision! //! @todo support 'g' format text = TQString::number(value.toDouble(), 'f', TQMAX(field->visibleDecimalPlaces(), 10)); //<-- 10 is quite good maximum for fractional digits //! @todo add command line settings? if (value.toDouble() == 0.0) { text = add.isEmpty() ? "0" : add; //eat 0 } else { //! @todo (js): get decimal places settings here... TQStringList sl = TQStringList::split(".", text); if (text.isEmpty()) { //nothing } else if (sl.count()==2) { // kdDebug() << "sl.count()=="<=1) { for (;pos>=0 && sl1[pos]=='0';pos--) ; pos++; } if (pos>0) text = sl[0] + m_decsym + sl1.left(pos); else text = sl[0]; //no decimal point } text += add; } /*moved to KexiDB::FieldValidator if (setValidator && !m_lineedit->validator()) { TQValidator *validator = new KDoubleValidator(m_lineedit); m_lineedit->setValidator( validator ); }*/ } else { text = value.toString(); if (field->isIntegerType()) { if (value.toInt() == 0) { text = add; //eat 0 } else { text += add; } /*moved to KexiDB::FieldValidator //! @todo implement ranges here! if (setValidator && !m_lineedit->validator()) { TQValidator *validator; if (KexiDB::Field::BigInteger == field()->type()) { //! @todo use field->isUnsigned() for KexiUtils::ULongLongValidator validator = new KexiUtils::LongLongValidator(m_lineedit); } else { validator = new KIntValidator(m_lineedit); } m_lineedit->setValidator( validator ); }*/ } else {//default: text text += add; } } return text; } #endif void KexiInputTableEdit::paintEvent ( TQPaintEvent * /*e*/ ) { TQPainter p(this); p.setPen( TQPen( colorGroup().text() ) ); p.drawRect( rect() ); } void KexiInputTableEdit::setRestrictedCompletion() { #if 0 //js TODO kdDebug() << "KexiInputTableEdit::setRestrictedCompletion()" << endl; // KLineEdit *content = static_cast(m_view); if(m_cview->text().isEmpty()) return; kdDebug() << "KexiInputTableEdit::setRestrictedCompletion(): something to do" << endl; m_cview->useGlobalKeyBindings(); TQStringList newC; TQStringList::ConstIterator it, end( m_comp.constEnd() ); for( it = m_comp.constBegin(); it != end; ++it) { if((*it).startsWith(m_cview->text())) newC.append(*it); } m_cview->setCompletedItems(newC); #endif } void KexiInputTableEdit::completed(const TQString &s) { // kdDebug() << "KexiInputTableEdit::completed(): " << s << endl; m_lineedit->setText(s); } bool KexiInputTableEdit::valueChanged() { //not needed? if (m_lineedit->text()!=m_origValue.toString()) //not needed? return true; return KexiTableEdit::valueChanged(); } bool KexiInputTableEdit::valueIsNull() { return m_lineedit->text().isNull(); } bool KexiInputTableEdit::valueIsEmpty() { return !m_lineedit->text().isNull() && m_lineedit->text().isEmpty(); } TQVariant KexiInputTableEdit::value() { if (field()->isFPNumericType()) {//==KexiDB::Field::Double || m_type==KexiDB::Field::Float) { //! js @todo PRESERVE PRECISION! TQString txt = m_lineedit->text(); if (m_decsym!=".") txt = txt.replace(m_decsym,".");//convert back bool ok; const double result = txt.toDouble(&ok); return ok ? TQVariant(result) : TQVariant(); } else if (field()->isIntegerType()) { //! @todo check constraints bool ok; if (KexiDB::Field::BigInteger == field()->type()) { if (field()->isUnsigned()) { const TQ_ULLONG result = m_lineedit->text().toULongLong(&ok); return ok ? TQVariant(result) : TQVariant(); } else { const TQ_LLONG result = m_lineedit->text().toLongLong(&ok); return ok ? TQVariant(result) : TQVariant(); } } if (KexiDB::Field::Integer == field()->type()) { if (field()->isUnsigned()) { const uint result = m_lineedit->text().toUInt(&ok); return ok ? TQVariant(result) : TQVariant(); } } //default: signed int const int result = m_lineedit->text().toInt(&ok); return ok ? TQVariant(result) : TQVariant(); } //default: text return m_lineedit->text(); } void KexiInputTableEdit::clear() { m_lineedit->clear(); } bool KexiInputTableEdit::cursorAtStart() { return m_lineedit->cursorPosition()==0; } bool KexiInputTableEdit::cursorAtEnd() { return m_lineedit->cursorPosition()==(int)m_lineedit->text().length(); } TQSize KexiInputTableEdit::totalSize() { if (!m_lineedit) return size(); return m_lineedit->size(); } void KexiInputTableEdit::handleCopyAction(const TQVariant& value, const TQVariant& visibleValue) { Q_UNUSED(visibleValue); //! @todo handle rich text? tqApp->clipboard()->setText( m_textFormatter.valueToText(value, TQString()) ); } void KexiInputTableEdit::handleAction(const TQString& actionName) { const bool alreadyVisible = m_lineedit->isVisible(); if (actionName=="edit_paste") { if (!alreadyVisible) { //paste as the entire text if the cell was not in edit mode emit editRequested(); m_lineedit->clear(); } m_lineedit->paste(); } else if (actionName=="edit_cut") { //! @todo handle rich text? if (!alreadyVisible) { //cut the entire text if the cell was not in edit mode emit editRequested(); m_lineedit->selectAll(); } m_lineedit->cut(); } } bool KexiInputTableEdit::showToolTipIfNeeded(const TQVariant& value, const TQRect& rect, const TQFontMetrics& fm, bool focused) { TQString text( value.type()==TQVariant::String ? value.toString() : m_textFormatter.valueToText(value, TQString()) ); TQRect internalRect(rect); internalRect.setLeft(rect.x()+leftMargin()); internalRect.setWidth(internalRect.width()-rightMargin(focused)-2*3); kexidbg << rect << " " << internalRect << " " << fm.width(text) << endl; return fm.width(text) > internalRect.width(); } void KexiInputTableEdit::moveCursorToEnd() { m_lineedit->end(false/*!mark*/); } void KexiInputTableEdit::moveCursorToStart() { m_lineedit->home(false/*!mark*/); } void KexiInputTableEdit::selectAll() { m_lineedit->selectAll(); } KEXI_CELLEDITOR_FACTORY_ITEM_IMPL(KexiInputEditorFactoryItem, KexiInputTableEdit) #include "kexiinputtableedit.moc"