diff --git a/linphone-app/src/utils/UriTools.cpp b/linphone-app/src/utils/UriTools.cpp index 2e8c1121f..fe7728041 100644 --- a/linphone-app/src/utils/UriTools.cpp +++ b/linphone-app/src/utils/UriTools.cpp @@ -60,7 +60,7 @@ QVector > UriTools::parse(const QString& text, const QRegul else{ currentIndex += results.back().second.length(); if( currentIndex < text.size()) - results.push_back({false, text.mid(currentIndex)}); + results.append(parse(text.mid(currentIndex), regex)); } return results; } @@ -278,10 +278,9 @@ void UriTools::initRegularExpressions() { // Level 8. -------------------------------------------------------------------- // Regex to match URI. It respects the RFC 3986. - QString URI = "(?:" - + URI_SCHEME + ":" + "|" + "www\\." + ")" - + URI_HIER_PART + "(?:" + "\\?" + URI_QUERY + ")?" + - "(?:" + "#" + URI_FRAGMENT + ")?"; + QString URI = "(?:" + URI_SCHEME + ":" + "|" + "www\\." + ")" + + URI_HIER_PART + "(?:" + "\\?" + URI_QUERY + ")?" + + "(?:" + "#" + URI_FRAGMENT + ")?"; // Regex to match URI. It respects the RFC 3987. QString IRI = "(?:" + URI_SCHEME + ":" + "|" + "www\\." + ")" diff --git a/linphone-app/src/utils/Utils.cpp b/linphone-app/src/utils/Utils.cpp index 3c2a9629b..893ef6ff8 100644 --- a/linphone-app/src/utils/Utils.cpp +++ b/linphone-app/src/utils/Utils.cpp @@ -743,6 +743,7 @@ QString Utils::encodeTextToQmlRichFormat(const QString& text, const QVariantMap& QString images; QStringList formattedText; QStringList imageFormat; + bool lastWasUrl = false; for(auto format : QImageReader::supportedImageFormats()) imageFormat.append(QString::fromLatin1(format).toUpper()); if(options.contains("noLink") && options["noLink"].toBool()){ @@ -750,15 +751,21 @@ QString Utils::encodeTextToQmlRichFormat(const QString& text, const QVariantMap& }else{ auto primaryColor = App::getInstance()->getColorListModel()->getColor("i")->getColor(); auto iriParsed = UriTools::parseIri(text); + for(int i = 0 ; i < iriParsed.size() ; ++i){ QString iri = iriParsed[i].second.replace('&', "&") .replace('<', "\u2063<") .replace('>', "\u2063>") .replace('"', """) .replace('\'', "'"); - if(!iriParsed[i].first) + if(!iriParsed[i].first){ + if(lastWasUrl){ + lastWasUrl = false; + if(iri.front() != ' ') + iri.push_front(' '); + } formattedText.append(iri); - else{ + }else{ QString uri = iriParsed[i].second.left(3) == "www" ? "http://"+iriParsed[i].second : iriParsed[i].second ; int extIndex = iriParsed[i].second.lastIndexOf('.'); QString ext; @@ -774,11 +781,16 @@ QString Utils::encodeTextToQmlRichFormat(const QString& text, const QVariantMap& ? QString(" height='auto'") : "" ) + " src=\"" + iriParsed[i].second + "\" />"; - }else + }else{ formattedText.append( "" + iri + ""); + lastWasUrl = true; + } } } } + if(lastWasUrl && formattedText.last().back() != ' '){ + formattedText.push_back(" "); + } if(images != "") images = "
" + images +"
"; diff --git a/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml b/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml index bcec93067..eddeefbf8 100644 --- a/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml +++ b/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml @@ -185,23 +185,30 @@ Item { Timer{// This timer is used to rewrite rich texts from new text only on idle. id: refreshFormatTimer //This fix having the wrong format while typing next to emojies. - property bool blockTextChanged : false - property var backupCursorPosition - function updateBlockText(){ - blockTextChanged = false - textArea.cursorPosition = backupCursorPosition - } - interval: 300 + property bool blockTextChanged : false // Block text changed signal when the format is converted. + property bool textChanged: false // The text has been changed while timer is running (it's true when only key has been pressed like control keys) + property bool restartFromInput : false // Keep in mind that the current time loop has been reset by user inputs. + + interval: restartFromInput ? 1000 : 300 // Longer wait if user is currently entering text repeat: false onTriggered: { - blockTextChanged = true - backupCursorPosition = textArea.cursorPosition - textArea.text = UtilsCpp.encodeTextToQmlRichFormat(textArea.getText(0,textArea.text.length)) - Qt.callLater(updateBlockText) + if(textChanged){ + blockTextChanged = true // Block onTextChanged + var backupCursorPosition = textArea.cursorPosition + var lastLength = textArea.length + textArea.text = UtilsCpp.encodeTextToQmlRichFormat(textArea.getText(0,textArea.text.length))// It will send onTextChanged + backupCursorPosition += (textArea.length - lastLength) + textArea.cursorPosition = backupCursorPosition + // Reset states + blockTextChanged = false + textChanged = false + restartFromInput = false + } } } onTextChanged: { if(!refreshFormatTimer.blockTextChanged){ + refreshFormatTimer.textChanged = true refreshFormatTimer.restart() } } @@ -210,6 +217,7 @@ Item { property var isAutoRepeating : false // shutdown repeating key feature to let optional menu appears and do normal stuff (like accents menu) Keys.onReleased: { if(!refreshFormatTimer.blockTextChanged){ + refreshFormatTimer.restartFromInput = true refreshFormatTimer.restart() } if( event.isAutoRepeat){// We begin or are currently repeating a key @@ -222,6 +230,7 @@ Item { } Keys.onPressed: { if(!refreshFormatTimer.blockTextChanged){ + refreshFormatTimer.restartFromInput = true refreshFormatTimer.restart() } if(event.isAutoRepeat){