mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
send message with files
This commit is contained in:
parent
9d5935fb53
commit
f69c5c3703
20 changed files with 1588 additions and 1064 deletions
|
|
@ -163,7 +163,7 @@ add_option(OPTION_LIST ENABLE_FFMPEG "Build mediastreamer2 with ffmpeg video sup
|
||||||
add_option(OPTION_LIST ENABLE_LDAP "Enable LDAP support." YES)
|
add_option(OPTION_LIST ENABLE_LDAP "Enable LDAP support." YES)
|
||||||
add_option(OPTION_LIST ENABLE_NON_FREE_CODECS "Enable the use of non free codecs" YES)
|
add_option(OPTION_LIST ENABLE_NON_FREE_CODECS "Enable the use of non free codecs" YES)
|
||||||
add_option(OPTION_LIST ENABLE_NON_FREE_FEATURES "Enable the use of non free codecs" ${ENABLE_NON_FREE_CODECS})
|
add_option(OPTION_LIST ENABLE_NON_FREE_FEATURES "Enable the use of non free codecs" ${ENABLE_NON_FREE_CODECS})
|
||||||
add_option(OPTION_LIST ENABLE_QT_KEYCHAIN "Build QtKeychain to manage VFS from System key stores." ON)
|
add_option(OPTION_LIST ENABLE_QT_KEYCHAIN "Build QtKeychain to manage VFS from System key stores." OFF)
|
||||||
add_option(OPTION_LIST ENABLE_QRCODE "Enable QRCode support" OFF)#Experimental
|
add_option(OPTION_LIST ENABLE_QRCODE "Enable QRCode support" OFF)#Experimental
|
||||||
add_option(OPTION_LIST ENABLE_RELATIVE_PREFIX "Set Internal packages relative to the binary" ON)
|
add_option(OPTION_LIST ENABLE_RELATIVE_PREFIX "Set Internal packages relative to the binary" ON)
|
||||||
add_option(OPTION_LIST ENABLE_SANITIZER "Enable sanitizer." OFF)
|
add_option(OPTION_LIST ENABLE_SANITIZER "Enable sanitizer." OFF)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "ChatCore.hpp"
|
#include "ChatCore.hpp"
|
||||||
#include "core/App.hpp"
|
#include "core/App.hpp"
|
||||||
|
#include "core/chat/message/content/ChatMessageContentGui.hpp"
|
||||||
#include "core/friend/FriendCore.hpp"
|
#include "core/friend/FriendCore.hpp"
|
||||||
#include "core/setting/SettingsCore.hpp"
|
#include "core/setting/SettingsCore.hpp"
|
||||||
#include "model/tool/ToolModel.hpp"
|
#include "model/tool/ToolModel.hpp"
|
||||||
|
|
@ -208,6 +209,21 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
||||||
linMessage->send();
|
linMessage->send();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
mChatModelConnection->makeConnectToCore(&ChatCore::lSendMessage, [this](QString message, QVariantList files) {
|
||||||
|
if (Utils::isEmptyMessage(message) && files.size() == 0) return;
|
||||||
|
QList<std::shared_ptr<ChatMessageContentModel>> filesContent;
|
||||||
|
for (auto &file : files) {
|
||||||
|
auto contentGui = qvariant_cast<ChatMessageContentGui *>(file);
|
||||||
|
if (contentGui) {
|
||||||
|
auto contentCore = contentGui->mCore;
|
||||||
|
filesContent.append(contentCore->getContentModel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mChatModelConnection->invokeToModel([this, message, filesContent]() {
|
||||||
|
auto linMessage = mChatModel->createMessage(message, filesContent);
|
||||||
|
linMessage->send();
|
||||||
|
});
|
||||||
|
});
|
||||||
mChatModelConnection->makeConnectToModel(
|
mChatModelConnection->makeConnectToModel(
|
||||||
&ChatModel::chatMessageSending, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
&ChatModel::chatMessageSending, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||||
const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
const std::shared_ptr<const linphone::EventLog> &eventLog) {
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@ signals:
|
||||||
void lUpdateUnreadCount();
|
void lUpdateUnreadCount();
|
||||||
void lUpdateLastUpdatedTime();
|
void lUpdateLastUpdatedTime();
|
||||||
void lSendTextMessage(QString message);
|
void lSendTextMessage(QString message);
|
||||||
|
void lSendMessage(QString message, QVariantList files);
|
||||||
void lCompose();
|
void lCompose();
|
||||||
void lLeave();
|
void lLeave();
|
||||||
void lSetMuted(bool muted);
|
void lSetMuted(bool muted);
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,117 @@ int ChatMessageContentList::findFirstUnreadIndex() {
|
||||||
return it == chatList.end() ? -1 : std::distance(chatList.begin(), it);
|
return it == chatList.end() ? -1 : std::distance(chatList.begin(), it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatMessageContentList::addFiles(const QStringList &paths) {
|
||||||
|
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||||
|
|
||||||
|
QStringList finalList;
|
||||||
|
QList<QFileInfo> fileList;
|
||||||
|
|
||||||
|
int nbNotFound = 0;
|
||||||
|
QString lastNotFound;
|
||||||
|
int nbExcess = 0;
|
||||||
|
int count = rowCount();
|
||||||
|
|
||||||
|
for (auto &path : paths) {
|
||||||
|
QFileInfo file(path.toUtf8());
|
||||||
|
// #ifdef _WIN32
|
||||||
|
// // A bug from FileDialog suppose that the file is local and overwrite the uri by removing "\\".
|
||||||
|
// if (!file.exists()) {
|
||||||
|
// path.prepend("\\\\");
|
||||||
|
// file.setFileName(path);
|
||||||
|
// }
|
||||||
|
// #endif
|
||||||
|
if (!file.exists()) {
|
||||||
|
++nbNotFound;
|
||||||
|
lastNotFound = path;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count + finalList.count() >= 12) {
|
||||||
|
++nbExcess;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
finalList.append(path);
|
||||||
|
fileList.append(file);
|
||||||
|
}
|
||||||
|
if (nbNotFound > 0) {
|
||||||
|
//: Error adding file
|
||||||
|
Utils::showInformationPopup(tr("popup_error_title"),
|
||||||
|
//: File was not found: %1
|
||||||
|
(nbNotFound == 1 ? tr("popup_error_path_does_not_exist_message").arg(lastNotFound)
|
||||||
|
//: %n files were not found
|
||||||
|
: tr("popup_error_nb_files_not_found_message").arg(nbNotFound)),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
if (nbExcess > 0) {
|
||||||
|
//: Error
|
||||||
|
Utils::showInformationPopup(tr("popup_error_title"),
|
||||||
|
//: You can send 12 files maximum at a time. %n files were ignored
|
||||||
|
tr("popup_error_max_files_count_message", "", nbExcess), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
mModelConnection->invokeToModel([this, finalList, fileList] {
|
||||||
|
int nbTooBig = 0;
|
||||||
|
int nbMimeError = 0;
|
||||||
|
QString lastMimeError;
|
||||||
|
QList<QSharedPointer<ChatMessageContentCore>> contentList;
|
||||||
|
for (auto &file : fileList) {
|
||||||
|
qint64 fileSize = file.size();
|
||||||
|
if (fileSize > Constants::FileSizeLimit) {
|
||||||
|
++nbTooBig;
|
||||||
|
qWarning() << QString("Unable to send file. (Size limit=%1)").arg(Constants::FileSizeLimit);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto name = file.fileName().toStdString();
|
||||||
|
auto path = file.filePath();
|
||||||
|
std::shared_ptr<linphone::Content> content = CoreModel::getInstance()->getCore()->createContent();
|
||||||
|
QStringList mimeType = QMimeDatabase().mimeTypeForFile(path).name().split('/');
|
||||||
|
if (mimeType.length() != 2) {
|
||||||
|
++nbMimeError;
|
||||||
|
lastMimeError = path;
|
||||||
|
qWarning() << QString("Unable to get supported mime type for: `%1`.").arg(path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
content->setType(Utils::appStringToCoreString(mimeType[0]));
|
||||||
|
content->setSubtype(Utils::appStringToCoreString(mimeType[1]));
|
||||||
|
content->setSize(size_t(fileSize));
|
||||||
|
content->setName(name);
|
||||||
|
content->setFilePath(Utils::appStringToCoreString(path));
|
||||||
|
contentList.append(ChatMessageContentCore::create(content, nullptr));
|
||||||
|
}
|
||||||
|
if (nbTooBig > 0) {
|
||||||
|
//: Error adding file
|
||||||
|
Utils::showInformationPopup(
|
||||||
|
tr("popup_error_title"),
|
||||||
|
//: %n files were ignored cause they exceed the maximum size. (Size limit=%2)
|
||||||
|
tr("popup_error_file_too_big_message").arg(nbTooBig).arg(Constants::FileSizeLimit), false);
|
||||||
|
}
|
||||||
|
if (nbMimeError > 0) {
|
||||||
|
//: Error adding file
|
||||||
|
Utils::showInformationPopup(tr("popup_error_title"),
|
||||||
|
//: Unable to get supported mime type for: `%1`.
|
||||||
|
(nbMimeError == 1
|
||||||
|
? tr("popup_error_unsupported_file_message").arg(lastMimeError)
|
||||||
|
//: Unable to get supported mime type for %1 files.
|
||||||
|
: tr("popup_error_unsupported_files_message").arg(nbMimeError)),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
mModelConnection->invokeToCore([this, contentList] {
|
||||||
|
for (auto &contentCore : contentList) {
|
||||||
|
connect(contentCore.get(), &ChatMessageContentCore::isFileChanged, this, [this, contentCore] {
|
||||||
|
int i = -1;
|
||||||
|
get(contentCore.get(), &i);
|
||||||
|
emit dataChanged(index(i), index(i));
|
||||||
|
});
|
||||||
|
add(contentCore);
|
||||||
|
contentCore->lCreateThumbnail(
|
||||||
|
true); // Was not created because linphone::Content is not considered as a file (yet)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ChatMessageContentList::setSelf(QSharedPointer<ChatMessageContentList> me) {
|
void ChatMessageContentList::setSelf(QSharedPointer<ChatMessageContentList> me) {
|
||||||
mModelConnection = SafeConnection<ChatMessageContentList, CoreModel>::create(me, CoreModel::getInstance());
|
mModelConnection = SafeConnection<ChatMessageContentList, CoreModel>::create(me, CoreModel::getInstance());
|
||||||
|
|
||||||
|
|
@ -101,57 +212,8 @@ void ChatMessageContentList::setSelf(QSharedPointer<ChatMessageContentList> me)
|
||||||
}
|
}
|
||||||
resetData<ChatMessageContentCore>(contents);
|
resetData<ChatMessageContentCore>(contents);
|
||||||
});
|
});
|
||||||
mModelConnection->makeConnectToCore(&ChatMessageContentList::lAddFile, [this](const QString &path) {
|
mModelConnection->makeConnectToCore(&ChatMessageContentList::lAddFiles,
|
||||||
QFile file(path);
|
[this](const QStringList &paths) { addFiles(paths); });
|
||||||
// #ifdef _WIN32
|
|
||||||
// // A bug from FileDialog suppose that the file is local and overwrite the uri by removing "\\".
|
|
||||||
// if (!file.exists()) {
|
|
||||||
// path.prepend("\\\\");
|
|
||||||
// file.setFileName(path);
|
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
if (!file.exists()) return;
|
|
||||||
if (rowCount() >= 12) {
|
|
||||||
//: Error
|
|
||||||
Utils::showInformationPopup(tr("popup_error_title"),
|
|
||||||
//: You can add 12 files maximum
|
|
||||||
tr("popup_error_max_files_count_message"), false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 fileSize = file.size();
|
|
||||||
if (fileSize > Constants::FileSizeLimit) {
|
|
||||||
qWarning() << QStringLiteral("Unable to send file. (Size limit=%1)").arg(Constants::FileSizeLimit);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto name = QFileInfo(file).fileName().toStdString();
|
|
||||||
mModelConnection->invokeToModel([this, path, fileSize, name] {
|
|
||||||
std::shared_ptr<linphone::Content> content = CoreModel::getInstance()->getCore()->createContent();
|
|
||||||
{
|
|
||||||
QStringList mimeType = QMimeDatabase().mimeTypeForFile(path).name().split('/');
|
|
||||||
if (mimeType.length() != 2) {
|
|
||||||
qWarning() << QStringLiteral("Unable to get supported mime type for: `%1`.").arg(path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
content->setType(Utils::appStringToCoreString(mimeType[0]));
|
|
||||||
content->setSubtype(Utils::appStringToCoreString(mimeType[1]));
|
|
||||||
}
|
|
||||||
content->setSize(size_t(fileSize));
|
|
||||||
content->setName(name);
|
|
||||||
content->setFilePath(Utils::appStringToCoreString(path));
|
|
||||||
auto contentCore = ChatMessageContentCore::create(content, nullptr);
|
|
||||||
mModelConnection->invokeToCore([this, contentCore] {
|
|
||||||
connect(contentCore.get(), &ChatMessageContentCore::isFileChanged, this, [this, contentCore] {
|
|
||||||
int i = -1;
|
|
||||||
get(contentCore.get(), &i);
|
|
||||||
emit dataChanged(index(i), index(i));
|
|
||||||
});
|
|
||||||
add(contentCore);
|
|
||||||
contentCore->lCreateThumbnail(
|
|
||||||
true); // Was not created because linphone::Content is not considered as a file (yet)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
emit lUpdate();
|
emit lUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,13 @@ public:
|
||||||
|
|
||||||
int findFirstUnreadIndex();
|
int findFirstUnreadIndex();
|
||||||
|
|
||||||
|
void addFiles(const QStringList &paths);
|
||||||
|
|
||||||
void setSelf(QSharedPointer<ChatMessageContentList> me);
|
void setSelf(QSharedPointer<ChatMessageContentList> me);
|
||||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void lAddFile(QString path);
|
void lAddFiles(QStringList paths);
|
||||||
void isFileChanged();
|
void isFileChanged();
|
||||||
void lUpdate();
|
void lUpdate();
|
||||||
void chatMessageChanged();
|
void chatMessageChanged();
|
||||||
|
|
|
||||||
|
|
@ -68,9 +68,9 @@ void ChatMessageContentProxy::setChatMessageGui(ChatMessageGui *chat) {
|
||||||
// return nullptr;
|
// return nullptr;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
void ChatMessageContentProxy::addFile(const QString &path) {
|
void ChatMessageContentProxy::addFiles(const QStringList &paths) {
|
||||||
auto model = getListModel<ChatMessageContentList>();
|
auto model = getListModel<ChatMessageContentList>();
|
||||||
if (model) emit model->lAddFile(path.toUtf8());
|
if (model) emit model->lAddFiles(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatMessageContentProxy::removeContent(ChatMessageContentGui *contentGui) {
|
void ChatMessageContentProxy::removeContent(ChatMessageContentGui *contentGui) {
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ public:
|
||||||
|
|
||||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||||
|
|
||||||
Q_INVOKABLE void addFile(const QString &path);
|
Q_INVOKABLE void addFiles(const QStringList &paths);
|
||||||
Q_INVOKABLE void removeContent(ChatMessageContentGui *contentGui);
|
Q_INVOKABLE void removeContent(ChatMessageContentGui *contentGui);
|
||||||
Q_INVOKABLE void clear();
|
Q_INVOKABLE void clear();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,15 @@ QVariant LimitProxy::getAt(const int &atIndex) const {
|
||||||
return sourceModel()->data(mapToSource(modelIndex), 0);
|
return sourceModel()->data(mapToSource(modelIndex), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantList LimitProxy::getAll() const {
|
||||||
|
QVariantList ret;
|
||||||
|
for (int i = 0; i < getCount(); ++i) {
|
||||||
|
auto modelIndex = index(i, 0);
|
||||||
|
if (modelIndex.isValid()) ret.append(sourceModel()->data(mapToSource(modelIndex), 0));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int LimitProxy::getCount() const {
|
int LimitProxy::getCount() const {
|
||||||
return rowCount();
|
return rowCount();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void displayMore();
|
Q_INVOKABLE void displayMore();
|
||||||
Q_INVOKABLE QVariant getAt(const int &index) const;
|
Q_INVOKABLE QVariant getAt(const int &index) const;
|
||||||
|
Q_INVOKABLE QVariantList getAll() const;
|
||||||
virtual int getCount() const;
|
virtual int getCount() const;
|
||||||
|
|
||||||
// Get the item following by what is shown from 2 lists
|
// Get the item following by what is shown from 2 lists
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -132,6 +132,16 @@ std::shared_ptr<linphone::ChatMessage> ChatModel::createTextMessageFromText(QStr
|
||||||
return mMonitor->createMessageFromUtf8(Utils::appStringToCoreString(text));
|
return mMonitor->createMessageFromUtf8(Utils::appStringToCoreString(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<linphone::ChatMessage>
|
||||||
|
ChatModel::createMessage(QString text, QList<std::shared_ptr<ChatMessageContentModel>> filesContent) {
|
||||||
|
auto message = mMonitor->createEmptyMessage();
|
||||||
|
for (auto &content : filesContent) {
|
||||||
|
message->addFileContent(content->getContent());
|
||||||
|
}
|
||||||
|
if (!text.isEmpty()) message->addUtf8TextContent(Utils::appStringToCoreString(text));
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
void ChatModel::compose() {
|
void ChatModel::compose() {
|
||||||
mMonitor->compose();
|
mMonitor->compose();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#ifndef CHAT_MODEL_H_
|
#ifndef CHAT_MODEL_H_
|
||||||
#define CHAT_MODEL_H_
|
#define CHAT_MODEL_H_
|
||||||
|
|
||||||
|
#include "model/chat/message/content/ChatMessageContentModel.hpp"
|
||||||
#include "model/listener/Listener.hpp"
|
#include "model/listener/Listener.hpp"
|
||||||
#include "tool/AbstractObject.hpp"
|
#include "tool/AbstractObject.hpp"
|
||||||
#include "tool/LinphoneEnums.hpp"
|
#include "tool/LinphoneEnums.hpp"
|
||||||
|
|
@ -49,12 +50,13 @@ public:
|
||||||
void deleteChatRoom();
|
void deleteChatRoom();
|
||||||
void leave();
|
void leave();
|
||||||
std::shared_ptr<linphone::ChatMessage> createTextMessageFromText(QString text);
|
std::shared_ptr<linphone::ChatMessage> createTextMessageFromText(QString text);
|
||||||
|
std::shared_ptr<linphone::ChatMessage> createMessage(QString text,
|
||||||
|
QList<std::shared_ptr<ChatMessageContentModel>> filesContent);
|
||||||
void compose();
|
void compose();
|
||||||
linphone::ChatRoom::State getState() const;
|
linphone::ChatRoom::State getState() const;
|
||||||
void setMuted(bool muted);
|
void setMuted(bool muted);
|
||||||
void enableEphemeral(bool enable);
|
void enableEphemeral(bool enable);
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void historyDeleted();
|
void historyDeleted();
|
||||||
void messagesRead();
|
void messagesRead();
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,11 @@ QImage ThumbnailAsyncImageResponse::createThumbnail(const QString &path, QImage
|
||||||
else if (rotation == 7 || rotation == 8) transform.rotate(-90);
|
else if (rotation == 7 || rotation == 8) transform.rotate(-90);
|
||||||
thumbnail = thumbnail.transformed(transform);
|
thumbnail = thumbnail.transformed(transform);
|
||||||
if (rotation == 2 || rotation == 4 || rotation == 5 || rotation == 7)
|
if (rotation == 2 || rotation == 4 || rotation == 5 || rotation == 7)
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||||
|
thumbnail = thumbnail.mirrored(true, false);
|
||||||
|
#else
|
||||||
thumbnail = thumbnail.flipped(Qt::Horizontal);
|
thumbnail = thumbnail.flipped(Qt::Horizontal);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return thumbnail;
|
return thumbnail;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ ListView {
|
||||||
mainItem.currentIndex = indexToSelect
|
mainItem.currentIndex = indexToSelect
|
||||||
}
|
}
|
||||||
onLayoutChanged: {
|
onLayoutChanged: {
|
||||||
var chatToSelect = getAt(mainItem.currentIndex)
|
|
||||||
selectChat(mainItem.currentChatGui)
|
selectChat(mainItem.currentChatGui)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,24 +39,28 @@ Item {
|
||||||
property bool isOutgoing: false
|
property bool isOutgoing: false
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
propagateComposedEvents: true
|
propagateComposedEvents: true
|
||||||
// Changing of cursor seems not to work with the Loader
|
function handleMouseMove (mouse) {
|
||||||
// Use override cursor for this case
|
thumbnailProvider.state = Utils.pointIsInItem(this, thumbnailProvider, mouse)
|
||||||
|
? 'hovered'
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
onMouseXChanged: (mouse) => handleMouseMove.call(this, mouse)
|
||||||
|
onMouseYChanged: (mouse) => handleMouseMove.call(this, mouse)
|
||||||
onEntered: {
|
onEntered: {
|
||||||
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
|
|
||||||
thumbnailProvider.state = 'hovered'
|
thumbnailProvider.state = 'hovered'
|
||||||
}
|
}
|
||||||
onExited: {
|
onExited: {
|
||||||
UtilsCpp.restoreGlobalCursor()
|
|
||||||
thumbnailProvider.state = ''
|
thumbnailProvider.state = ''
|
||||||
}
|
}
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: (mouse) => {
|
onClicked: (mouse) => {
|
||||||
mouse.accepted = false
|
mouse.accepted = false
|
||||||
if(mainItem.isTransferring) {
|
if(mainItem.isTransferring) {
|
||||||
mainItem.contentGui.core.lCancelDownloadFile()
|
mainItem.contentGui.core.lCancelDownloadFile()
|
||||||
mouse.accepted = true
|
mouse.accepted = true
|
||||||
|
thumbnailProvider.state = ''
|
||||||
}
|
}
|
||||||
else if(!mainItem.contentGui.core.wasDownloaded) {
|
else if(!mainItem.contentGui.core.wasDownloaded) {
|
||||||
mouse.accepted = true
|
mouse.accepted = true
|
||||||
|
|
@ -64,6 +68,7 @@ Item {
|
||||||
mainItem.contentGui.core.lDownloadFile()
|
mainItem.contentGui.core.lDownloadFile()
|
||||||
} else if (Utils.pointIsInItem(this, thumbnailProvider, mouse)) {
|
} else if (Utils.pointIsInItem(this, thumbnailProvider, mouse)) {
|
||||||
mouse.accepted = true
|
mouse.accepted = true
|
||||||
|
thumbnailProvider.state = ''
|
||||||
// if(SettingsModel.isVfsEncrypted){
|
// if(SettingsModel.isVfsEncrypted){
|
||||||
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
|
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
|
||||||
// contentGui: mainItem.contentGui,
|
// contentGui: mainItem.contentGui,
|
||||||
|
|
@ -290,5 +295,11 @@ Item {
|
||||||
states: State {
|
states: State {
|
||||||
name: 'hovered'
|
name: 'hovered'
|
||||||
}
|
}
|
||||||
|
// Changing cursor in MouseArea seems not to work with the Loader
|
||||||
|
// Use override cursor for this case
|
||||||
|
onStateChanged: {
|
||||||
|
if (state === 'hovered') UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
|
||||||
|
else UtilsCpp.restoreGlobalCursor()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls.Basic as Control
|
import QtQuick.Controls.Basic as Control
|
||||||
|
import QtQuick.Dialogs
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Linphone
|
import Linphone
|
||||||
import UtilsCpp
|
import UtilsCpp
|
||||||
|
|
@ -47,6 +48,12 @@ Control.Control {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
id: fileDialog
|
||||||
|
fileMode: FileDialog.OpenFiles
|
||||||
|
onAccepted: _emitFiles(fileDialog.selectedFiles)
|
||||||
|
}
|
||||||
|
|
||||||
// width: mainItem.implicitWidth
|
// width: mainItem.implicitWidth
|
||||||
// height: mainItem.height
|
// height: mainItem.height
|
||||||
leftPadding: Math.round(15 * DefaultStyle.dp)
|
leftPadding: Math.round(15 * DefaultStyle.dp)
|
||||||
|
|
@ -80,7 +87,7 @@ Control.Control {
|
||||||
style: ButtonStyle.noBackground
|
style: ButtonStyle.noBackground
|
||||||
icon.source: AppIcons.paperclip
|
icon.source: AppIcons.paperclip
|
||||||
onClicked: {
|
onClicked: {
|
||||||
console.log("TODO : open explorer to attach file")
|
fileDialog.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Control.Control {
|
Control.Control {
|
||||||
|
|
@ -144,10 +151,9 @@ Control.Control {
|
||||||
onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle)
|
onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle)
|
||||||
wrapMode: TextEdit.WordWrap
|
wrapMode: TextEdit.WordWrap
|
||||||
Keys.onPressed: (event) => {
|
Keys.onPressed: (event) => {
|
||||||
if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return)
|
if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return))
|
||||||
&& (!(event.modifier & Qt.ShiftModifier))) {
|
if(!(event.modifiers & Qt.ShiftModifier)) {
|
||||||
mainItem.sendText()
|
mainItem.sendText()
|
||||||
sendingTextArea.clear()
|
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +174,6 @@ Control.Control {
|
||||||
icon.source: AppIcons.paperPlaneRight
|
icon.source: AppIcons.paperPlaneRight
|
||||||
onClicked: {
|
onClicked: {
|
||||||
mainItem.sendText()
|
mainItem.sendText()
|
||||||
sendingTextArea.clear()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,10 +148,6 @@ RowLayout {
|
||||||
leftPadding: Math.round(19 * DefaultStyle.dp)
|
leftPadding: Math.round(19 * DefaultStyle.dp)
|
||||||
rightPadding: Math.round(19 * DefaultStyle.dp)
|
rightPadding: Math.round(19 * DefaultStyle.dp)
|
||||||
|
|
||||||
function addFile(path) {
|
|
||||||
contents.addFile(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
@ -212,6 +208,14 @@ RowLayout {
|
||||||
onClicked: contents.removeContent(modelData)
|
onClicked: contents.removeContent(modelData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Control.ScrollBar.horizontal: selectedFilesScrollbar
|
||||||
|
}
|
||||||
|
ScrollBar {
|
||||||
|
id: selectedFilesScrollbar
|
||||||
|
active: true
|
||||||
|
anchors.bottom: selectedFilesArea.bottom
|
||||||
|
anchors.left: selectedFilesArea.left
|
||||||
|
anchors.right: selectedFilesArea.right
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ChatDroppableTextArea {
|
ChatDroppableTextArea {
|
||||||
|
|
@ -228,9 +232,16 @@ RowLayout {
|
||||||
}
|
}
|
||||||
mainItem.chat.core.sendingText = text
|
mainItem.chat.core.sendingText = text
|
||||||
}
|
}
|
||||||
onSendText: mainItem.chat.core.lSendTextMessage(text)
|
onSendText: {
|
||||||
|
var filesContents = contents.getAll()
|
||||||
|
if (filesContents.length === 0)
|
||||||
|
mainItem.chat.core.lSendTextMessage(text)
|
||||||
|
else mainItem.chat.core.lSendMessage(text, filesContents)
|
||||||
|
messageSender.textArea.clear()
|
||||||
|
contents.clear()
|
||||||
|
}
|
||||||
onDropped: (files) => {
|
onDropped: (files) => {
|
||||||
files.forEach(selectedFilesArea.addFile)
|
contents.addFiles(files)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
external/CMakeLists.txt
vendored
4
external/CMakeLists.txt
vendored
|
|
@ -1,8 +1,6 @@
|
||||||
|
|
||||||
add_subdirectory(linphone-sdk/)
|
add_subdirectory(linphone-sdk/)
|
||||||
if(ENABLE_QT_KEYCHAIN)
|
if(ENABLE_QT_KEYCHAIN)
|
||||||
function(add_linphone_keychain)
|
find_package(Qt6 REQUIRED COMPONENTS Test)
|
||||||
add_subdirectory(qtkeychain/)
|
add_subdirectory(qtkeychain/)
|
||||||
endfunction()
|
|
||||||
add_linphone_keychain()
|
|
||||||
endif()
|
endif()
|
||||||
Loading…
Add table
Reference in a new issue