/** Remove any existing auto completion suggestion */ void HintingLineEdit::clearSuggestion() { if (!hasSelectedText()) return; // Carefully cut out the selected text QString line = text(); line = line.left(selectionStart()) + line.mid(selectionStart() + selectedText().length()); setText(line); }
QString ChatItem::selection() const { if (selectionMode() == FullSelection) return data(MessageModel::DisplayRole).toString(); if (selectionMode() == PartialSelection) { int start = qMin(selectionStart(), selectionEnd()); int end = start + qAbs(selectionStart() - selectionEnd()); QTextCursor cSelect(document()); cSelect.setPosition(start); cSelect.setPosition(end, QTextCursor::KeepAnchor); return cSelect.selectedText(); } return QString(); }
QAbstractTextDocumentLayout::Selection ChatItem::selectionLayout() const { QAbstractTextDocumentLayout::Selection selection; if (!hasSelection()) return selection; int start; int end; if (selectionMode() == FullSelection) { start = 0; end = document()->characterCount()-1; } else { start = selectionStart(); end = selectionEnd(); } QTextCursor c(document()); c.setPosition(start); c.setPosition(end, QTextCursor::KeepAnchor); selection.cursor = c; return selection; }
//VOXOX CHANGE by Rolando - 2009.05.11 - method called when lineedit lost focus void VoxOxToolTipLineEdit::leaveEvent ( QEvent * event ){ if (QLineEdit::text() == _toolTip || QLineEdit::text().isEmpty()) {//VOXOX CHANGE by Rolando - 2009.05.11 - if current text is equal to tooltip or is empty displayToolTipMessage(); } else{ int cursorPositionValue = cursorPosition();//VOXOX CHANGE by Rolando - 2009.06.02 - gets current Cursor Position int intSelectedStart = -1; QString stringText; if(hasSelectedText()){//VOXOX CHANGE by Rolando - 2009.06.02 - if there is selected text stringText = selectedText();//VOXOX CHANGE by Rolando - 2009.06.02 - gets selected text intSelectedStart = selectionStart();//VOXOX CHANGE by Rolando - 2009.06.02 - gets position where selection starts } if(_message == QLineEdit::text()){//VOXOX CHANGE by Rolando - 2009.05.11 - if current text is equal to _message then sets _shortMessage QLineEdit::setText(_shortMessage); } else{//VOXOX CHANGE by Rolando - 2009.05.11 - if current text is not equal to _message then updates _shortMessage and _message and then sets _shortMessage as current text updateMessageText(QLineEdit::text()); QLineEdit::setText(_shortMessage); } //VOXOX CHANGE by Rolando - 2009.10.13 if(intSelectedStart >= 0 && intSelectedStart + stringText.length() <= getMaximumCharsAllowed()){//VOXOX CHANGE by Rolando - 2009.06.02 - if there is a text selected setSelection(intSelectedStart, stringText.length());//VOXOX CHANGE by Rolando - 2009.06.02 - as we set the long message in lineedit, we need to set the text was selected } currentTextChanged(text()); } QLineEdit::leaveEvent(event); //changeFocusToParent();//VOXOX CHANGE by Rolando - 2009.05.22 - method to send focus to another widget when mouse leaves the lineedit }
void VoxOxToolTipLineEdit::keyPressEvent(QKeyEvent * event) { if (!_cleared) { clearLineEdit(); repaintPrimaryColor(); } if (event->key()==Qt::Key_Return || event->key()==Qt::Key_Enter) {//if key pressed was return or enter if(!QLineEdit::text().isEmpty()){ updateMessageText(QLineEdit::text()); QLineEdit::setText(_shortMessage); currentTextChanged(text()); } QLineEdit::keyPressEvent(event); changeFocusToParent();//VOXOX CHANGE by Rolando - 2009.05.22 - method to send focus to another widget when mouse leaves the lineedit } else{//if key pressed was not return or enter key int cursorPositionValue = cursorPosition();//VOXOX CHANGE by Rolando - 2009.06.02 - gets current Cursor Position bool isShortMessage = QLineEdit::text() == _shortMessage;//VOXOX CHANGE by Rolando - 2009.06.02 - we need to check if current text is equal to _shortMessage int intSelectedStart = -1; QString text; if(hasSelectedText()){//VOXOX CHANGE by Rolando - 2009.06.02 - if there is selected text text = selectedText();//VOXOX CHANGE by Rolando - 2009.06.02 - gets selected text intSelectedStart = selectionStart();//VOXOX CHANGE by Rolando - 2009.06.02 - gets position where selection starts } QLineEdit::setText(_message);//VOXOX CHANGE by Rolando - 2009.06.02 - sets long message if(intSelectedStart >= 0){//VOXOX CHANGE by Rolando - 2009.06.02 - if there is a text selected setSelection(intSelectedStart, text.length());//VOXOX CHANGE by Rolando - 2009.06.02 - as we set the long message in lineedit, we need to set the text was selected } else{ //VOXOX CHANGE by Rolando - 2009.06.02 - if there is not a text selected if(isShortMessage){//VOXOX CHANGE by Rolando - 2009.06.02 - if we had currentText equal to _shortMessage //VOXOX CHANGE by Rolando - 2009.10.13 if(cursorPositionValue == _shortMessage.length()){//VOXOX CHANGE by Rolando - 2009.06.02 - if cursor position is the rightest pos allowed setCursorPosition(_message.length());//VOXOX CHANGE by Rolando - 2009.06.02 - we move the cursor to rightest position after we changed the current text by _message } else{ //VOXOX CHANGE by Rolando - 2009.06.02 - if cursor position is not the rightest pos allowed setCursorPosition(cursorPositionValue);//VOXOX CHANGE by Rolando - 2009.06.02 - if cursor position is not the rightest pos allowed } } else{ //VOXOX CHANGE by Rolando - 2009.06.02 - if we had not currentText equal to _shortMessage setCursorPosition(cursorPositionValue);//VOXOX CHANGE by Rolando - 2009.06.02 - we move the cursor to old position + 1 } } QLineEdit::keyPressEvent(event);//processes event - it should be processed before update _shortMessage and _message variables updateMessageText(QLineEdit::text());//VOXOX CHANGE by Rolando - 2009.06.02 - we update the short and long messages } keyPressedSignal(event->key()); }
void CharLineEdit::keyPressEvent(QKeyEvent* event) { bool handled = false; if (selectionStart() == -1) { switch (event->key()) { case Qt::Key_Backspace: if (isAtEndOfSeparator()) { // Delete separator characters in a single keypress. // Don't use setText This method maintains the undo history backspace(); backspace(); backspace(); handled = true; } break; case Qt::Key_Delete: if (isAtStartOfSeparator()) { del(); del(); del(); handled = true; } break; case Qt::Key_Left: if (isAtEndOfSeparator()) { cursorBackward(false, 3); handled = true; } break; case Qt::Key_Right: if (isAtStartOfSeparator()) { cursorForward(false, 3); handled = true; } break; } } if (handled) { event->ignore(); } else { QLineEdit::keyPressEvent(event); } emit keyPressed(event); }
void LineEditWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_selectionStart = selectionStart(); } QLineEdit::mousePressEvent(event); }
QString ContentsChatItem::selection() const { if (selectionMode() == FullSelection) return data(MessageModel::DisplayRole).toString(); if (selectionMode() == PartialSelection) { int start = qMin(selectionStart(), selectionEnd()); int end = start + qAbs(selectionStart() - selectionEnd()); int offset = 0; for (const Smiley &s : privateData()->smileys) { if(s.smileyfiedStart() >= start && s.smileyfiedStart()+1 <= end) { offset += s.text().count() - ((s.type() == Smiley::Emoji) ? s.graphics().count() : 1); } } return data(MessageModel::DisplayRole).toString().mid(start, end-start+offset);; } return QString(); }
void ItemEditorWidget::search(const QRegExp &re) { if ( !re.isValid() || re.isEmpty() ) return; auto tc = textCursor(); tc.setPosition(tc.selectionStart()); setTextCursor(tc); findNext(re); }
WT_USTRING WLineEdit::selectedText() const { if (selectionStart() != -1) { WApplication *app = WApplication::instance(); return WString::fromUTF8(UTF8Substr(text().toUTF8(), app->selectionStart(), app->selectionEnd() - app->selectionStart())); } else return WString::Empty; }
void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState& exceptionState) { if (start > end) { exceptionState.throwDOMException(IndexSizeError, "The provided start value (" + String::number(start) + ") is larger than the provided end value (" + String::number(end) + ")."); return; } if (hasAuthorShadowRoot()) return; String text = innerTextValue(); unsigned textLength = text.length(); unsigned replacementLength = replacement.length(); unsigned newSelectionStart = selectionStart(); unsigned newSelectionEnd = selectionEnd(); start = std::min(start, textLength); end = std::min(end, textLength); if (start < end) text.replace(start, end - start, replacement); else text.insert(replacement, start); setInnerTextValue(text); // FIXME: What should happen to the value (as in value()) if there's no renderer? if (!renderer()) return; subtreeHasChanged(); if (equalIgnoringCase(selectionMode, "select")) { newSelectionStart = start; newSelectionEnd = start + replacementLength; } else if (equalIgnoringCase(selectionMode, "start")) newSelectionStart = newSelectionEnd = start; else if (equalIgnoringCase(selectionMode, "end")) newSelectionStart = newSelectionEnd = start + replacementLength; else { // Default is "preserve". long delta = replacementLength - (end - start); if (newSelectionStart > end) newSelectionStart += delta; else if (newSelectionStart > start) newSelectionStart = start; if (newSelectionEnd > end) newSelectionEnd += delta; else if (newSelectionEnd > start) newSelectionEnd = start + replacementLength; } setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirection); }
void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode& ec) { if (start > end) { ec = INDEX_SIZE_ERR; return; } String text = innerTextValue(); unsigned textLength = text.length(); unsigned replacementLength = replacement.length(); unsigned newSelectionStart = selectionStart(); unsigned newSelectionEnd = selectionEnd(); start = std::min(start, textLength); end = std::min(end, textLength); if (start < end) text.replace(start, end - start, replacement); else text.insert(replacement, start); setInnerTextValue(text); // FIXME: What should happen to the value (as in value()) if there's no renderer? if (!renderer()) return; subtreeHasChanged(); if (equalIgnoringCase(selectionMode, "select")) { newSelectionStart = start; newSelectionEnd = start + replacementLength; } else if (equalIgnoringCase(selectionMode, "start")) newSelectionStart = newSelectionEnd = start; else if (equalIgnoringCase(selectionMode, "end")) newSelectionStart = newSelectionEnd = start + replacementLength; else { // Default is "preserve". long delta = replacementLength - (end - start); if (newSelectionStart > end) newSelectionStart += delta; else if (newSelectionStart > start) newSelectionStart = start; if (newSelectionEnd > end) newSelectionEnd += delta; else if (newSelectionEnd > start) newSelectionEnd = start + replacementLength; } setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirection); }
void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState& exceptionState) { if (start > end) { exceptionState.throwDOMException(IndexSizeError, "The provided start value (" + String::number(start) + ") is larger than the provided end value (" + String::number(end) + ")."); return; } if (openShadowRoot()) return; String text = innerEditorValue(); unsigned textLength = text.length(); unsigned replacementLength = replacement.length(); unsigned newSelectionStart = selectionStart(); unsigned newSelectionEnd = selectionEnd(); start = std::min(start, textLength); end = std::min(end, textLength); if (start < end) text.replace(start, end - start, replacement); else text.insert(replacement, start); setValue(text, TextFieldEventBehavior::DispatchNoEvent); if (selectionMode == "select") { newSelectionStart = start; newSelectionEnd = start + replacementLength; } else if (selectionMode == "start") { newSelectionStart = newSelectionEnd = start; } else if (selectionMode == "end") { newSelectionStart = newSelectionEnd = start + replacementLength; } else { ASSERT(selectionMode == "preserve"); long delta = replacementLength - (end - start); if (newSelectionStart > end) newSelectionStart += delta; else if (newSelectionStart > start) newSelectionStart = start; if (newSelectionEnd > end) newSelectionEnd += delta; else if (newSelectionEnd > start) newSelectionEnd = start + replacementLength; } setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirection); }
WT_USTRING WLineEdit::selectedText() const { if (selectionStart() != -1) { WApplication *app = WApplication::instance(); std::string result = UTF8Substr(text().toUTF8(), app->selectionStart(), app->selectionEnd() - app->selectionStart()); #ifdef WT_TARGET_JAVA return result; #else return WString::fromUTF8(result); #endif } else return WString::Empty; }
void KSqueezedTextLabel::mouseReleaseEvent(QMouseEvent* ev) { #if QT_VERSION >= 0x040700 if (QApplication::clipboard()->supportsSelection() && textInteractionFlags() != Qt::NoTextInteraction && ev->button() == Qt::LeftButton && !d->fullText.isEmpty() && hasSelectedText()) { // Expand "..." when selecting with the mouse QString txt = selectedText(); const QChar ellipsisChar(0x2026); // from qtextengine.cpp const int dotsPos = txt.indexOf(ellipsisChar); if (dotsPos > -1) { // Ex: abcde...yz, selecting de...y (selectionStart=3) // charsBeforeSelection = selectionStart = 2 (ab) // charsAfterSelection = 1 (z) // final selection length= 26 - 2 - 1 = 23 const int start = selectionStart(); int charsAfterSelection = text().length() - start - selectedText().length(); txt = d->fullText; // Strip markup tags if (textFormat() == Qt::RichText || (textFormat() == Qt::AutoText && Qt::mightBeRichText(txt))) { txt.replace(QRegExp(QStringLiteral("<[^>]*>")), QStringLiteral("")); // account for stripped characters charsAfterSelection -= d->fullText.length() - txt.length(); } txt = txt.mid(selectionStart(), txt.length() - start - charsAfterSelection); } QApplication::clipboard()->setText(txt, QClipboard::Selection); } else #endif { QLabel::mouseReleaseEvent(ev); } }
void AnnotationDialog::CompletableLineEdit::selectPrevNextMatch( bool next ) { int itemStart = text().lastIndexOf( QRegExp(QString::fromLatin1("[!&|]")) ) +1; QString input = text().mid( itemStart ); QList<QTreeWidgetItem*> items = m_listView->findItems( input, Qt::MatchContains, 0 ); if ( items.isEmpty() ) return; QTreeWidgetItem* item = items.at(0); if ( next ) item = m_listView->itemBelow(item); else item = m_listView->itemAbove(item); if ( item ) selectItemAndUpdateLineEdit( item, itemStart, text().left( selectionStart() ) ); }
QPoint SyntaxLineEdit::getTokenUnderCursor() { if (selectionStart() >= 0) return (QPoint(0,0)); int pos = cursorPosition(); int start = pos; int len = 0; while (start > 0 && token_chars_.contains(text().at(start -1))) { start--; len++; } while (pos < text().length() && token_chars_.contains(text().at(pos))) { pos++; len++; } return QPoint(start, len); }
QMap<int, QList<QRectF>> TextDocumentAdapter::GetTextPositions (const QString& text, Qt::CaseSensitivity cs) { const auto& pageSize = Doc_->pageSize (); const auto pageHeight = pageSize.height (); QTextEdit hackyEdit; hackyEdit.setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); hackyEdit.setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff); hackyEdit.setFixedSize (Doc_->pageSize ().toSize ()); hackyEdit.setDocument (Doc_.get ()); Doc_->setPageSize (pageSize); const auto tdFlags = cs == Qt::CaseSensitive ? QTextDocument::FindCaseSensitively : QTextDocument::FindFlags (); QMap<int, QList<QRectF>> result; auto cursor = Doc_->find (text, 0, tdFlags); while (!cursor.isNull ()) { auto endRect = hackyEdit.cursorRect (cursor); auto startCursor = cursor; startCursor.setPosition (cursor.selectionStart ()); auto rect = hackyEdit.cursorRect (startCursor); const int pageNum = rect.y () / pageHeight; rect.moveTop (rect.y () - pageHeight * pageNum); endRect.moveTop (endRect.y () - pageHeight * pageNum); if (rect.y () != endRect.y ()) { rect.setWidth (pageSize.width () - rect.x ()); endRect.setX (0); } auto bounding = rect | endRect; result [pageNum] << bounding; cursor = Doc_->find (text, cursor, tdFlags); } return result; }
void LineEditWidget::setCompletion(const QString &completion) { m_completion = completion; if (m_shouldIgnoreCompletion) { m_shouldIgnoreCompletion = false; return; } QString currentText(text().mid(selectionStart())); if (m_completion != currentText) { setText(m_completion); setCursorPosition(currentText.length()); setSelection(currentText.length(), (m_completion.length() - currentText.length())); } }
void VoxOxToolTipLineEdit::enterEvent ( QEvent * event ) { if (_cleared) { int cursorPositionValue = cursorPosition();//VOXOX CHANGE by Rolando - 2009.06.02 - gets current Cursor Position int intSelectedStart = -1; QString stringText; if(hasSelectedText()){//VOXOX CHANGE by Rolando - 2009.06.02 - if there is selected text stringText = selectedText();//VOXOX CHANGE by Rolando - 2009.06.02 - gets selected text intSelectedStart = selectionStart();//VOXOX CHANGE by Rolando - 2009.06.02 - gets position where selection starts } if(_shortMessage == QLineEdit::text()){ QLineEdit::setText(_message); } //VOXOX CHANGE by Rolando - 2009.10.13 if(intSelectedStart >= 0 && intSelectedStart + stringText.length() <= getMaximumCharsAllowed()){//VOXOX CHANGE by Rolando - 2009.06.02 - if there is a text selected setSelection(intSelectedStart, stringText.length());//VOXOX CHANGE by Rolando - 2009.06.02 - as we set the long message in lineedit, we need to set the text was selected } } QLineEdit::enterEvent(event); }
bool WLineEdit::hasSelectedText() const { return selectionStart() != -1; }
void KawaiiLineEdit::keyPressEvent(QKeyEvent *evt) { if(!mRomajiMode) return QLineEdit::keyPressEvent(evt); if(evt->key() == Qt::Key_Backspace || evt->key() == Qt::Key_Delete) { if( mActiveText.isEmpty() ) { if( !selectedText().isEmpty() ) { mRealText.remove(selectionStart(), selectedText().length()); mInsertPosition = selectionStart(); } else if(evt->key() == Qt::Key_Delete) // Delete after the cursor { mRealText.remove(cursorPosition(), 1); mInsertPosition = cursorPosition(); } else if(cursorPosition() > 0) // Delete character before cursor { mRealText.remove(cursorPosition() - 1, 1); mInsertPosition = cursorPosition() - 1; } evt->accept(); updateText(); return; } // Remove the last character in the string (if there is one) mActiveText.chop(1); evt->accept(); updateText(); return; } else if(evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Return) { if( mActiveText.isEmpty() ) return QLineEdit::keyPressEvent(evt); mRealText.insert(mInsertPosition, mDisplayText); mInsertPosition += mDisplayText.length(); mDisplayMode = Hiragana; mDisplayText.clear(); mActiveText.clear(); evt->accept(); updateText(); setCursorPosition(mInsertPosition); return; } else if( !mActiveText.isEmpty() && (evt->key() == Qt::Key_Left || evt->key() == Qt::Key_Right || evt->key() == Qt::Key_Home || evt->key() == Qt::Key_End) ) { evt->accept(); return; } else if( !mActiveText.isEmpty() && evt->key() == Qt::Key_F7) { mDisplayMode = (mDisplayMode == Hiragana) ? Katakana : Hiragana; evt->accept(); updateText(); return; } // Normal key, clear the text first if( !evt->text().isEmpty() ) { if( mActiveText.isEmpty() ) mInsertPosition = cursorPosition(); // If there is a selection, delete it if( !selectedText().isEmpty() && mActiveText.isEmpty() ) { mRealText.remove(selectionStart(), selectedText().length()); mInsertPosition = selectionStart(); } mActiveText += evt->text(); evt->accept(); updateText(); return; } QLineEdit::keyPressEvent(evt); }
void AnnotationDialog::CompletableLineEdit::keyPressEvent( QKeyEvent* ev ) { if ( ev->key() == Qt::Key_Down || ev->key() == Qt::Key_Up ) { selectPrevNextMatch( ev->key() == Qt::Key_Down ); return; } if ( m_mode == SearchMode && ( ev->key() == Qt::Key_Return || ev->key() == Qt::Key_Enter) ) { //Confirm autocomplete, deselect all text handleSpecialKeysInSearch( ev ); m_listSelect->showOnlyItemsMatching( QString() ); // Show all again after confirming autocomplete suggestion. return; } if ( m_mode != SearchMode && isSpecialKey( ev ) ) return; // Don't insert the special character. if ( ev->key() == Qt::Key_Space && ev->modifiers() & Qt::ControlModifier ) { mergePreviousImageSelection(); return; } QString prevContent = text(); if ( ev->text().isEmpty() || !ev->text()[0].isPrint() ) { // If final Return is handled by the default implementation, // it can "leak" to other widgets. So we swallow it here: if ( ev->key() == Qt::Key_Return || ev->key() == Qt::Key_Enter ) emit KLineEdit::returnPressed( text() ); else KLineEdit::keyPressEvent( ev ); if ( prevContent != text() ) m_listSelect->showOnlyItemsMatching( text() ); return; } // &,|, or ! should result in the current item being inserted if ( m_mode == SearchMode && isSpecialKey( ev ) ) { handleSpecialKeysInSearch( ev ); m_listSelect->showOnlyItemsMatching( QString() ); // Show all again after a special caracter. return; } int cursorPos = cursorPosition(); int selStart = selectionStart(); KLineEdit::keyPressEvent( ev ); // Find the text of the current item int itemStart = 0; QString input = text(); if ( m_mode == SearchMode ) { input = input.left( cursorPosition() ); itemStart = input.lastIndexOf(QRegExp(QString::fromLatin1("[!&|]"))) + 1; if (itemStart > 0) { itemStart++; } input = input.mid( itemStart ); } // Find the text in the listView QTreeWidgetItem* item = findItemInListView( input ); if ( !item && m_mode == SearchMode ) { // revert setText( prevContent ); setCursorPosition( cursorPos ); item = findItemInListView( input ); if(selStart>=0) setSelection( selStart, prevContent.length() ); // Reset previous selection. } if ( item ) { selectItemAndUpdateLineEdit( item, itemStart, input ); m_listSelect->showOnlyItemsMatching( input ); } else if (m_mode != SearchMode ) m_listSelect->showOnlyItemsMatching( input ); }
// common function for wheel up/down and key up/down // delta is in wheel units: a delta of 120 means to increment by 1 void SpinBox::increment(int delta, int shift) // shift = 1 means to increment * 10, shift = -1 means / 10 { bool ok; QString str = text(); //qDebug() << "increment from " << str; const double oldVal = str.toDouble(&ok); if (!ok) { // Not a valid double value, don't do anything return; } bool useCursorPositionIncr = appPTR->getCurrentSettings()->useCursorPositionIncrements(); // First, treat the standard case: use the Knob increment if (!useCursorPositionIncr) { double val = oldVal; _imp->currentDelta += delta; double inc = std::pow(10., shift) * _imp->currentDelta * _imp->increment / 120.; double maxiD = 0.; double miniD = 0.; switch (_imp->type) { case eSpinBoxTypeDouble: { maxiD = _imp->maxi.toDouble(); miniD = _imp->mini.toDouble(); val += inc; _imp->currentDelta = 0; break; } case eSpinBoxTypeInt: { maxiD = _imp->maxi.toInt(); miniD = _imp->mini.toInt(); val += (int)inc; // round towards zero // Update the current delta, which contains the accumulated error _imp->currentDelta -= ( (int)inc ) * 120. / _imp->increment; assert(std::abs(_imp->currentDelta) < 120); break; } } val = std::max( miniD, std::min(val, maxiD) ); if (val != oldVal) { setValue(val); Q_EMIT valueChanged(val); } return; } // From here on, we treat the positin-based increment. if ( (str.indexOf( QLatin1Char('e') ) != -1) || (str.indexOf( QLatin1Char('E') ) != -1) ) { // Sorry, we don't handle numbers with an exponent, although these are valid doubles return; } _imp->currentDelta += delta; int inc_int = _imp->currentDelta / 120; // the number of integert increments // Update the current delta, which contains the accumulated error _imp->currentDelta -= inc_int * 120; if (inc_int == 0) { // Nothing is changed, just return return; } // Within the value, we modify: // - if there is no selection, the first digit right after the cursor (or if it is an int and the cursor is at the end, the last digit) // - if there is a selection, the first digit after the start of the selection int len = str.size(); // used for chopping spurious characters if (len <= 0) { return; // should never happen } // The position in str of the digit to modify in str() (may be equal to str.size()) int pos = ( hasSelectedText() ? selectionStart() : cursorPosition() ); //if (pos == len) { // select the last character? // pos = len - 1; //} // The position of the decimal dot int dot = str.indexOf( QLatin1Char('.') ); if (dot == -1) { dot = str.size(); } // Now, chop trailing and leading whitespace (and update len, pos and dot) // Leading whitespace while ( len > 0 && str[0].isSpace() ) { str.remove(0, 1); --len; if (pos > 0) { --pos; } --dot; assert(dot >= 0); assert(len > 0); } // Trailing whitespace while ( len > 0 && str[len - 1].isSpace() ) { str.remove(len - 1, 1); --len; if (pos > len) { --pos; } if (dot > len) { --dot; } assert(len > 0); } assert( oldVal == str.toDouble() ); // check that the value hasn't changed due to whitespace manipulation // On int types, there should not be any dot if ( (_imp->type == eSpinBoxTypeInt) && (len > dot) ) { // Remove anything after the dot, including the dot str.resize(dot); len = dot; } // Adjust pos so that it doesn't point to a dot or a sign assert( 0 <= pos && pos <= str.size() ); while ( pos < str.size() && ( pos == dot || str[pos] == QLatin1Char('+') || str[pos] == QLatin1Char('-') ) ) { ++pos; } assert(len >= pos); // Set the shift (may have to be done twice due to the dot) pos -= shift; if (pos == dot) { pos -= shift; } // Now, add leading and trailing zeroes so that pos is a valid digit position // (beware of the sign!) // Trailing zeroes: // (No trailing zeroes on int, of course) assert( len == str.size() ); if ( (_imp->type == eSpinBoxTypeInt) && (pos >= len) ) { // If this is an int and we are beyond the last position, change the last digit pos = len - 1; // also reset the shift if it was negative if (shift < 0) { shift = 0; } } while ( pos >= str.size() ) { assert(_imp->type == eSpinBoxTypeDouble); // Add trailing zero, maybe preceded by a dot if (pos == dot) { str.append( QLatin1Char('.') ); ++pos; // increment pos, because we just added a '.', and next iteration will add a '0' ++len; } else { assert(pos > dot); str.append( QLatin1Char('0') ); ++len; } assert( pos >= (str.size() - 1) ); } // Leading zeroes: bool hasSign = ( str[0] == QLatin1Char('-') || str[0] == QLatin1Char('+') ); while ( pos < 0 || ( pos == 0 && ( str[0] == QLatin1Char('-') || str[0] == QLatin1Char('+') ) ) ) { // Add leading zero str.insert( hasSign ? 1 : 0, QLatin1Char('0') ); ++pos; ++dot; ++len; } assert( len == str.size() ); assert( 0 <= pos && pos < str.size() && str[pos].isDigit() ); QString noDotStr = str; int noDotLen = len; if (dot != len) { // Remove the dot noDotStr.remove(dot, 1); --noDotLen; } assert( (_imp->type == eSpinBoxTypeInt && noDotLen == dot) || noDotLen >= dot ); double val = oldVal; // The value, as a double if ( (noDotLen > 16) && (16 >= dot) ) { // don't handle more than 16 significant digits (this causes over/underflows in the following) assert( noDotLen == noDotStr.size() ); noDotLen = 16; noDotStr.resize(noDotLen); } qlonglong llval = noDotStr.toLongLong(&ok); // The value, as a long long int if (!ok) { // Not a valid long long value, don't do anything return; } int llpowerOfTen = dot - noDotLen; // llval must be post-multiplied by this power of ten assert(llpowerOfTen <= 0); // check that val and llval*10^llPowerOfTen are close enough (relative error should be less than 1e-8) assert(std::abs(val * std::pow(10., -llpowerOfTen) - llval) / std::max( qlonglong(1), std::abs(llval) ) < 1e-8); // If pos is at the end if ( pos == str.size() ) { switch (_imp->type) { case eSpinBoxTypeDouble: if ( dot == str.size() ) { str += QString::fromUtf8(".0"); len += 2; ++pos; } else { str += QLatin1Char('0'); ++len; } break; case eSpinBoxTypeInt: // take the character before --pos; break; } } // Compute the full value of the increment assert( len == str.size() ); assert(pos != dot); assert( 0 <= pos && pos < len && str[pos].isDigit() ); int powerOfTen = dot - pos - (pos < dot); // the power of ten assert( (_imp->type == eSpinBoxTypeDouble) || ( powerOfTen >= 0 && dot == str.size() ) ); if (powerOfTen - llpowerOfTen > 16) { // too many digits to handle, don't do anything // (may overflow when adjusting llval) return; } double inc = inc_int * std::pow(10., (double)powerOfTen); // Check that we are within the authorized range double maxiD, miniD; switch (_imp->type) { case eSpinBoxTypeInt: maxiD = _imp->maxi.toInt(); miniD = _imp->mini.toInt(); break; case eSpinBoxTypeDouble: default: maxiD = _imp->maxi.toDouble(); miniD = _imp->mini.toDouble(); break; } val += inc; if ( (val < miniD) || (maxiD < val) ) { // out of the authorized range, don't do anything return; } // Adjust llval so that the increment becomes an int, and avoid rounding errors if (powerOfTen >= llpowerOfTen) { llval += inc_int * std::pow(10., powerOfTen - llpowerOfTen); } else { llval *= std::pow(10., llpowerOfTen - powerOfTen); llpowerOfTen -= llpowerOfTen - powerOfTen; llval += inc_int; } // check that val and llval*10^llPowerOfTen are still close enough (relative error should be less than 1e-8) assert(std::abs(val * std::pow(10., -llpowerOfTen) - llval) / std::max( qlonglong(1), std::abs(llval) ) < 1e-8); QString newStr; newStr.setNum(llval); bool newStrHasSign = newStr[0] == QLatin1Char('+') || newStr[0] == QLatin1Char('-'); // the position of the decimal dot int newDot = newStr.size() + llpowerOfTen; // add leading zeroes if newDot is not a valid position (beware of sign!) while ( newDot <= int(newStrHasSign) ) { newStr.insert( int(newStrHasSign), QLatin1Char('0') ); ++newDot; } assert( 0 <= newDot && newDot <= newStr.size() ); assert( newDot == newStr.size() || newStr[newDot].isDigit() ); if ( newDot != newStr.size() ) { assert(_imp->type == eSpinBoxTypeDouble); newStr.insert( newDot, QLatin1Char('.') ); } // Check that the backed string is close to the wanted value (relative error should be less than 1e-8) assert( (newStr.toDouble() - val) / std::max( 1e-8, std::abs(val) ) < 1e-8 ); // The new cursor position int newPos = newDot + (pos - dot); // Remove the shift (may have to be done twice due to the dot) newPos += shift; if (newPos == newDot) { // adjust newPos newPos += shift; } assert( 0 <= newDot && newDot <= newStr.size() ); // Now, add leading and trailing zeroes so that newPos is a valid digit position // (beware of the sign!) // Trailing zeroes: while ( newPos >= newStr.size() ) { assert(_imp->type == eSpinBoxTypeDouble); // Add trailing zero, maybe preceded by a dot if (newPos == newDot) { newStr.append( QLatin1Char('.') ); } else { assert(newPos > newDot); newStr.append( QLatin1Char('0') ); } assert( newPos >= (newStr.size() - 1) ); } // Leading zeroes: bool newHasSign = ( newStr[0] == QLatin1Char('-') || newStr[0] == QLatin1Char('+') ); while ( newPos < 0 || ( newPos == 0 && ( newStr[0] == QLatin1Char('-') || newStr[0] == QLatin1Char('+') ) ) ) { // add leading zero newStr.insert( newHasSign ? 1 : 0, QLatin1Char('0') ); ++newPos; ++newDot; } assert( 0 <= newPos && newPos < newStr.size() && newStr[newPos].isDigit() ); // Set the text and cursor position //qDebug() << "increment setting text to " << newStr; setText(newStr, newPos); // Set the selection assert( newPos + 1 <= newStr.size() ); setSelection(newPos + 1, -1); Q_EMIT valueChanged( value() ); } // increment
void HTMLTextFormControlElement::setRangeText(const String& replacement, ExceptionState& exceptionState) { setRangeText(replacement, selectionStart(), selectionEnd(), "preserve", exceptionState); }
void LibraryFilterLineEdit::paintEvent(QPaintEvent *) { QStylePainter p(this); QStyleOptionFrame o; initStyleOption(&o); o.palette = QApplication::palette(); //o.rect.adjust(0, 0, -1, 0); p.fillRect(rect(), o.palette.base().color()); QRect rLeft = QRect(o.rect.x(), o.rect.y() + 1, o.rect.height(), o.rect.y() + o.rect.height() - 2); QRect rRight = QRect(o.rect.x() + o.rect.width() - o.rect.height(), o.rect.y() + 1, o.rect.height(), o.rect.y() + o.rect.height() - 2); QRect rText = QRect(rLeft.x() + rLeft.width(), rLeft.y(), rRight.x(), rRight.y() + rRight.height()); //rLeft.adjust(0, 1, 0, -1); //rRight.adjust(0, 1, 0, -1); if (hasFocus()) { p.setPen(QPen(o.palette.highlight().color())); } else { p.setPen(QPen(o.palette.mid().color())); } p.save(); p.setRenderHint(QPainter::Antialiasing, true); QPainterPath painterPath; // 2---1----> Left curve is painted with 2 calls to cubicTo, starting in 1 <----10--9 // | | First cubic call is with points p1, p2 and p3 | | // 3 + Second is with points p3, p4 and p5 + 8 // | | With that, a half circle can be filled with linear gradient | | // 4---5----> <----6---7 painterPath.moveTo(rLeft.x() + rLeft.width(), rLeft.y()); painterPath.cubicTo(rLeft.x() + rLeft.width(), rLeft.y(), rLeft.x() + rLeft.width() / 2.0f, rLeft.y(), rLeft.x() + rLeft.width() / 2.0f, rLeft.y() + rLeft.height() / 2.0f); painterPath.cubicTo(rLeft.x() + rLeft.width() / 2.0f, rLeft.y() + rLeft.height() / 2.0f, rLeft.x() + rLeft.width() / 2.0f, rLeft.y() + rLeft.height(), rLeft.x() + rLeft.width(), rLeft.y() + rLeft.height()); painterPath.lineTo(rRight.x(), rRight.y() + rRight.height()); painterPath.cubicTo(rRight.x(), rRight.y() + rRight.height(), rRight.x() + rRight.width() / 2.0f, rRight.y() + rRight.height(), rRight.x() + rRight.width() / 2.0f, rRight.y() + rRight.height() / 2.0f); painterPath.cubicTo(rRight.x() + rRight.width() / 2.0f, rRight.y() + rRight.height() / 2.0f, rRight.x() + rRight.width() / 2.0f, rRight.y(), rRight.x(), rRight.y()); painterPath.closeSubpath(); p.drawPath(painterPath); p.setRenderHint(QPainter::Antialiasing, false); p.restore(); // Paint text and cursor if (hasFocus() || !text().isEmpty()) { // Highlight selected text p.setPen(o.palette.text().color()); if (hasSelectedText()) { QRect rectTextLeft, rectTextMid, rectTextRight; QString leftText, midText, rightText; int sStart = selectionStart(); int sEnd = selectedText().length() - 1; // Four uses cases to highlight a text if (sStart > 0 && sEnd < text().size() - 1) { // a[b]cd leftText = text().left(sStart); midText = selectedText(); rightText = text().mid(sStart + selectedText().length()); rectTextLeft.setX(rText.x()); rectTextLeft.setY(rText.y()); rectTextLeft.setWidth(fontMetrics().width(leftText)); rectTextLeft.setHeight(rText.height()); rectTextMid.setX(rectTextLeft.x() + rectTextLeft.width()); rectTextMid.setY(rText.y()); rectTextMid.setWidth(fontMetrics().width(midText)); rectTextMid.setHeight(rText.height()); rectTextRight.setX(rectTextMid.x() + rectTextMid.width()); rectTextRight.setY(rText.y()); rectTextRight.setWidth(fontMetrics().width(rightText)); rectTextRight.setHeight(rText.height()); p.fillRect(rectTextLeft, o.palette.base()); p.fillRect(rectTextMid, o.palette.highlight()); p.fillRect(rectTextRight, o.palette.base()); p.drawText(rectTextLeft, Qt::AlignLeft | Qt::AlignVCenter, leftText); p.save(); p.setPen(o.palette.highlightedText().color()); p.drawText(rectTextMid, Qt::AlignLeft | Qt::AlignVCenter, midText); p.restore(); p.drawText(rectTextRight, Qt::AlignLeft | Qt::AlignVCenter, rightText); } else if (sStart == 0 && sEnd < text().size() - 1) { // [ab]cd midText = selectedText(); rightText = text().mid(sStart + selectedText().length()); rectTextMid.setX(rText.x()); rectTextMid.setY(rText.y()); rectTextMid.setWidth(fontMetrics().width(midText)); rectTextMid.setHeight(rText.height()); rectTextRight.setX(rectTextMid.x() + rectTextMid.width()); rectTextRight.setY(rText.y()); rectTextRight.setWidth(fontMetrics().width(rightText)); rectTextRight.setHeight(rText.height()); p.fillRect(rectTextMid, o.palette.highlight()); p.fillRect(rectTextRight, o.palette.base()); p.save(); p.setPen(o.palette.highlightedText().color()); p.drawText(rectTextMid, Qt::AlignLeft | Qt::AlignVCenter, midText); p.restore(); p.drawText(rectTextRight, Qt::AlignLeft | Qt::AlignVCenter, rightText); } else if (sStart == 0 && sEnd == text().size() - 1) { // [abcd] midText = selectedText(); rectTextMid.setX(rText.x()); rectTextMid.setY(rText.y()); rectTextMid.setWidth(fontMetrics().width(midText)); rectTextMid.setHeight(rText.height()); p.fillRect(rectTextMid, o.palette.highlight()); p.save(); p.setPen(o.palette.highlightedText().color()); p.drawText(rectTextMid, Qt::AlignLeft | Qt::AlignVCenter, midText); p.restore(); } else { // ab[cd] // never? } } else { p.drawText(rText, Qt::AlignLeft | Qt::AlignVCenter, text()); } rText.adjust(0, 2, 0, -2); this->drawCursor(&p, rText); } else { p.setPen(o.palette.mid().color()); p.drawText(rText, Qt::AlignLeft | Qt::AlignVCenter, placeholderText()); } }
void HTMLTextFormControlElement::setSelectionEnd(int end) { setSelectionRange(min(end, selectionStart()), end, selectionDirection()); }
void HTMLTextFormControlElement::setSelectionDirection(const String& direction) { setSelectionRange(selectionStart(), selectionEnd(), direction); }
void HTMLTextFormControlElement::setRangeText(const String& replacement, ExceptionCode& ec) { setRangeText(replacement, selectionStart(), selectionEnd(), String(), ec); }
String HTMLTextFormControlElement::selectedText() const { if (!isTextFormControl()) return String(); return value().substring(selectionStart(), selectionEnd() - selectionStart()); }