mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-05-06 20:23:08 +00:00
Revert auto reformatting and limit format to only emojies (text edit of chat).
Fix crash when creating video thumbnail on context management (let Qt to decide what to do).
This commit is contained in:
parent
c5bb7f4a26
commit
e326ba9437
7 changed files with 21 additions and 53 deletions
|
|
@ -87,7 +87,7 @@ ChatRoomProxyModel::~ChatRoomProxyModel(){
|
|||
|
||||
CREATE_PARENT_MODEL_FUNCTION(removeAllEntries)
|
||||
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendMessage, const QString &)
|
||||
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(forwardMessage, ChatMessageModel *)
|
||||
|
||||
CREATE_PARENT_MODEL_FUNCTION_WITH_ID(removeRow)
|
||||
|
|
@ -99,6 +99,11 @@ CREATE_PARENT_MODEL_FUNCTION(deleteChatRoom)
|
|||
#undef CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM
|
||||
#undef CREATE_PARENT_MODEL_FUNCTION_WITH_ID
|
||||
|
||||
void ChatRoomProxyModel::sendMessage(const QString &text){
|
||||
QString trim = text.trimmed();
|
||||
if (mChatRoomModel && !trim.isEmpty())
|
||||
mChatRoomModel->sendMessage(trim);
|
||||
}
|
||||
|
||||
void ChatRoomProxyModel::compose (const QString& text) {
|
||||
if (mChatRoomModel && !text.isEmpty())
|
||||
|
|
|
|||
|
|
@ -159,23 +159,20 @@ QImage ImageModel::createThumbnail(const QString& path){
|
|||
if(!format.isEmpty())
|
||||
originalImage = QImage(path, format);
|
||||
else if(Utils::isVideo(path)){
|
||||
QMediaPlayer player;
|
||||
QObject context;
|
||||
QMediaPlayer player(&context);
|
||||
player.setMedia(QUrl::fromLocalFile(path));
|
||||
player.setPosition(player.duration() / 2);
|
||||
VideoFrameGrabber grabber;
|
||||
VideoFrameGrabber grabber(&context);
|
||||
player.setVideoOutput(&grabber);
|
||||
QObject * context = new QObject();
|
||||
QObject::connect(&grabber, &VideoFrameGrabber::frameAvailable, context, [&context,&originalImage, &player](QImage frame) mutable{
|
||||
QObject::connect(&grabber, &VideoFrameGrabber::frameAvailable, &context, [&context,&originalImage, &player](QImage frame) mutable{
|
||||
originalImage = frame.copy();
|
||||
player.stop();
|
||||
context->deleteLater();// This will destroy context and initializer
|
||||
context = nullptr;
|
||||
}, Qt::DirectConnection);
|
||||
player.play();
|
||||
do{
|
||||
qApp->processEvents();
|
||||
}while(player.state() != QMediaPlayer::State::StoppedState);
|
||||
if(context) context->deleteLater();
|
||||
}
|
||||
}
|
||||
if (!originalImage.isNull()){
|
||||
|
|
|
|||
|
|
@ -705,7 +705,7 @@ bool Utils::codepointIsEmoji(uint code){
|
|||
(code >= 0x1f000 && code <= 0x1faff) || code == 0x200d || code == 0xfe0f;
|
||||
}
|
||||
|
||||
QString Utils::replaceEmoji(const QString &body){
|
||||
QString Utils::encodeEmojiToQmlRichFormat(const QString &body){
|
||||
QString fmtBody = "";
|
||||
QVector<uint> utf32_string = body.toUcs4();
|
||||
|
||||
|
|
@ -739,6 +739,7 @@ bool Utils::isOnlyEmojis(const QString& text){
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
QString Utils::encodeTextToQmlRichFormat(const QString& text, const QVariantMap& options){
|
||||
QString images;
|
||||
QStringList formattedText;
|
||||
|
|
@ -794,7 +795,7 @@ QString Utils::encodeTextToQmlRichFormat(const QString& text, const QVariantMap&
|
|||
if(images != "")
|
||||
images = "<div>" + images +"</div>";
|
||||
|
||||
return images + "<p style=\"white-space:pre-wrap;\">" + replaceEmoji(formattedText.join("")) + "</p>";
|
||||
return images + "<p style=\"white-space:pre-wrap;\">" + encodeEmojiToQmlRichFormat(formattedText.join("")) + "</p>";
|
||||
}
|
||||
|
||||
QString Utils::getFileContent(const QString& filePath){
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ public:
|
|||
Q_INVOKABLE static QPoint getCursorPosition();
|
||||
Q_INVOKABLE static QString getFileChecksum(const QString& filePath);
|
||||
static bool codepointIsEmoji(uint code);
|
||||
static QString replaceEmoji(const QString &body);
|
||||
Q_INVOKABLE static bool isOnlyEmojis(const QString& text);
|
||||
Q_INVOKABLE static QString encodeEmojiToQmlRichFormat(const QString &body);
|
||||
Q_INVOKABLE static QString encodeTextToQmlRichFormat(const QString& text, const QVariantMap& options = QVariantMap());
|
||||
Q_INVOKABLE static QString getFileContent(const QString& filePath);
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,10 @@ Item {
|
|||
function getText(){
|
||||
return textArea.getText(0, textArea.text.length)
|
||||
}
|
||||
|
||||
function insertEmoji(code){
|
||||
code = UtilsCpp.encodeEmojiToQmlRichFormat(code)
|
||||
textArea.insert(textArea.cursorPosition, code+' ') // Add a space or next text will be entered inside <font> of emoji.
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color: DroppableTextAreaStyle.outsideBackgroundColor.color
|
||||
|
|
@ -182,44 +185,10 @@ Item {
|
|||
height:flickableArea.height
|
||||
//onHeightChanged: height=flickableArea.height//TextArea change its height from content text. Force it to parent
|
||||
|
||||
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 // 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: {
|
||||
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()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
|
||||
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
|
||||
if(!isAutoRepeating){// We start repeat. Check if this is an "ignore" character
|
||||
if(event.key > Qt.Key_Any && event.key <= Qt.Key_ydiaeresis)// Remove the previous character if it is a printable character
|
||||
|
|
@ -229,10 +198,6 @@ Item {
|
|||
isAutoRepeating = false// We are no more repeating. Final decision is done on Releasing
|
||||
}
|
||||
Keys.onPressed: {
|
||||
if(!refreshFormatTimer.blockTextChanged){
|
||||
refreshFormatTimer.restartFromInput = true
|
||||
refreshFormatTimer.restart()
|
||||
}
|
||||
if(event.isAutoRepeat){
|
||||
isAutoRepeating = true// Where are repeating the key. Set the state.
|
||||
if(event.key > Qt.Key_Any && event.key <= Qt.Key_ydiaeresis){// Ignore character if it is repeating and printable character
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ Rectangle {
|
|||
}
|
||||
ChatEmojis{
|
||||
id: chatEmojis
|
||||
onEmojiClicked: textArea.insert(emoji)
|
||||
onEmojiClicked: textArea.insertEmoji(emoji)
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ Loader{// Use of Loader because of Repeater (items cannot be loaded dynamically)
|
|||
delegate: ChatConferenceInvitationMessage{
|
||||
id: calendarMessage
|
||||
contentModel: $modelData
|
||||
width: parent.width
|
||||
width: parent && parent.width
|
||||
availableWidth: mainItem.availableWidth
|
||||
gotoButtonMode: 1
|
||||
onExpandToggle: isExpanded=!isExpanded
|
||||
|
|
@ -203,7 +203,7 @@ Loader{// Use of Loader because of Repeater (items cannot be loaded dynamically)
|
|||
Component.onCompleted: messagesTextsList.updateBestWidth()
|
||||
delegate:
|
||||
ChatTextMessage {
|
||||
width: parent.width
|
||||
width: parent && parent.width
|
||||
contentModel: $modelData
|
||||
onLastTextSelectedChanged: mainItem.lastTextSelectedChanged(lastTextSelected)
|
||||
color: mainItem.useTextColor
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue