enlarge image size when single in message #LINQT-2008
This commit is contained in:
parent
580819df3a
commit
924224abc5
9 changed files with 175 additions and 40 deletions
|
|
@ -57,16 +57,16 @@ void ChatMessageContentProxy::setChatMessageGui(ChatMessageGui *chat) {
|
||||||
getListModel<ChatMessageContentList>()->setChatMessageGui(chat);
|
getListModel<ChatMessageContentList>()->setChatMessageGui(chat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChatMessageGui *ChatMessageContentProxy::getChatMessageAtIndex(int i) {
|
ChatMessageContentGui *ChatMessageContentProxy::getChatMessageContentAtIndex(int i) {
|
||||||
// auto model = getListModel<ChatMessageContentList>();
|
auto model = getListModel<ChatMessageContentList>();
|
||||||
// auto sourceIndex = mapToSource(index(i, 0)).row();
|
auto sourceIndex = mapToSource(index(i, 0)).row();
|
||||||
// if (model) {
|
if (model) {
|
||||||
// auto chat = model->getAt<ChatMessageCore>(sourceIndex);
|
auto chat = model->getAt<ChatMessageContentCore>(sourceIndex);
|
||||||
// if (chat) return new ChatMessageGui(chat);
|
if (chat) return new ChatMessageContentGui(chat);
|
||||||
// else return nullptr;
|
else return nullptr;
|
||||||
// }
|
}
|
||||||
// return nullptr;
|
return nullptr;
|
||||||
// }
|
}
|
||||||
|
|
||||||
void ChatMessageContentProxy::addFiles(const QStringList &paths) {
|
void ChatMessageContentProxy::addFiles(const QStringList &paths) {
|
||||||
auto model = getListModel<ChatMessageContentList>();
|
auto model = getListModel<ChatMessageContentList>();
|
||||||
|
|
@ -99,8 +99,5 @@ bool ChatMessageContentProxy::SortFilterList::filterAcceptsRow(int sourceRow, co
|
||||||
|
|
||||||
bool ChatMessageContentProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft,
|
bool ChatMessageContentProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft,
|
||||||
const QModelIndex &sourceRight) const {
|
const QModelIndex &sourceRight) const {
|
||||||
auto l = getItemAtSource<ChatMessageContentList, ChatMessageCore>(sourceLeft.row());
|
return true;
|
||||||
auto r = getItemAtSource<ChatMessageContentList, ChatMessageCore>(sourceRight.row());
|
|
||||||
if (l && r) return l->getTimestamp() <= r->getTimestamp();
|
|
||||||
else return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ public:
|
||||||
ChatMessageGui *getChatMessageGui();
|
ChatMessageGui *getChatMessageGui();
|
||||||
void setChatMessageGui(ChatMessageGui *chat);
|
void setChatMessageGui(ChatMessageGui *chat);
|
||||||
|
|
||||||
|
Q_INVOKABLE ChatMessageContentGui *getChatMessageContentAtIndex(int i);
|
||||||
|
|
||||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||||
|
|
||||||
Q_INVOKABLE void addFiles(const QStringList &paths);
|
Q_INVOKABLE void addFiles(const QStringList &paths);
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,8 @@ public:
|
||||||
// Max image size in bytes. (1Mb)
|
// Max image size in bytes. (1Mb)
|
||||||
static constexpr qint64 MaxImageSize = 1024000; // In Bytes.
|
static constexpr qint64 MaxImageSize = 1024000; // In Bytes.
|
||||||
static constexpr qint64 FileSizeLimit = 524288000; // In Bytes.
|
static constexpr qint64 FileSizeLimit = 524288000; // In Bytes.
|
||||||
static constexpr int ThumbnailImageFileWidth = 100;
|
static constexpr int ThumbnailImageFileWidth = 285;
|
||||||
static constexpr int ThumbnailImageFileHeight = 100;
|
static constexpr int ThumbnailImageFileHeight = 345;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
// LINPHONE
|
// LINPHONE
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
||||||
view/Control/Display/Chat/Event.qml
|
view/Control/Display/Chat/Event.qml
|
||||||
view/Control/Display/Chat/EphemeralEvent.qml
|
view/Control/Display/Chat/EphemeralEvent.qml
|
||||||
view/Control/Display/Chat/FileView.qml
|
view/Control/Display/Chat/FileView.qml
|
||||||
|
view/Control/Display/Chat/ImageFileView.qml
|
||||||
|
view/Control/Display/Chat/AnimatedImageFileView.qml
|
||||||
view/Control/Display/Contact/Avatar.qml
|
view/Control/Display/Contact/Avatar.qml
|
||||||
view/Control/Display/Contact/Contact.qml
|
view/Control/Display/Contact/Contact.qml
|
||||||
view/Control/Display/Contact/Presence.qml
|
view/Control/Display/Contact/Presence.qml
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQml.Models
|
import QtQml.Models
|
||||||
|
import QtQuick.Controls.Basic as Control
|
||||||
|
|
||||||
import Linphone
|
import Linphone
|
||||||
import UtilsCpp
|
import UtilsCpp
|
||||||
|
|
@ -8,7 +9,7 @@ import UtilsCpp
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
GridLayout {
|
GridLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
property ChatMessageGui chatMessageGui: null
|
property ChatMessageContentProxy proxyModel
|
||||||
property bool isHoveringFile: false
|
property bool isHoveringFile: false
|
||||||
property int itemCount: delModel.count
|
property int itemCount: delModel.count
|
||||||
property int itemWidth: Math.round(95 * DefaultStyle.dp)
|
property int itemWidth: Math.round(95 * DefaultStyle.dp)
|
||||||
|
|
@ -43,12 +44,7 @@ GridLayout {
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: delModel
|
id: delModel
|
||||||
model: ChatMessageContentProxy {
|
model: mainItem.proxyModel
|
||||||
id: contentProxy
|
|
||||||
filterType: ChatMessageContentProxy.FilterContentType.File
|
|
||||||
chatMessageGui: mainItem.chatMessageGui
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: FileView {
|
delegate: FileView {
|
||||||
id: avatarCell
|
id: avatarCell
|
||||||
contentGui: modelData
|
contentGui: modelData
|
||||||
|
|
|
||||||
56
Linphone/view/Control/Display/Chat/AnimatedImageFileView.qml
Normal file
56
Linphone/view/Control/Display/Chat/AnimatedImageFileView.qml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls as Control
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtMultimedia
|
||||||
|
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp
|
||||||
|
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Separated file to show a single image bigger in chat message
|
||||||
|
// The FileView file does not allow that as it is a Loader and the image
|
||||||
|
// is reloaded everytime the message becomes visible again. It causes the
|
||||||
|
// chat message not to be able to adapt its size according to the painted
|
||||||
|
// size of the image
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
AnimatedImage {
|
||||||
|
id: mainItem
|
||||||
|
property ChatMessageContentGui contentGui
|
||||||
|
|
||||||
|
mipmap: false//SettingsModel.mipmapEnabled
|
||||||
|
autoTransform: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: contentGui && UtilsCpp.isAnimatedImage(contentGui.core.filePath) ? ('file:/'+ contentGui.core.filePath) : ""
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: 'hovered'
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
// Changing cursor in MouseArea seems not to work with the Loader
|
||||||
|
// Use override cursor for this case
|
||||||
|
onContainsMouseChanged: {
|
||||||
|
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
|
||||||
|
else UtilsCpp.restoreGlobalCursor()
|
||||||
|
mainItem.state = containsMouse ? 'hovered' : ''
|
||||||
|
}
|
||||||
|
onPressed: (mouse) => {
|
||||||
|
mouse.accepted = true
|
||||||
|
// if(SettingsModel.isVfsEncrypted){
|
||||||
|
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
|
||||||
|
// contentGui: mainItem.contentGui,
|
||||||
|
// }, function (status) {
|
||||||
|
// })
|
||||||
|
// }else
|
||||||
|
mainItem.contentGui.core.lOpenFile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ import QtQuick.Effects
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Controls.Basic as Control
|
import QtQuick.Controls.Basic as Control
|
||||||
import Linphone
|
import Linphone
|
||||||
|
import UtilsCpp
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Simple content display without reply and forward. These modules need to be splitted because of cyclic dependencies.
|
// Simple content display without reply and forward. These modules need to be splitted because of cyclic dependencies.
|
||||||
|
|
@ -30,6 +31,11 @@ ColumnLayout {
|
||||||
spacing: Math.round(5 * DefaultStyle.dp)
|
spacing: Math.round(5 * DefaultStyle.dp)
|
||||||
property int padding: Math.round(10 * DefaultStyle.dp)
|
property int padding: Math.round(10 * DefaultStyle.dp)
|
||||||
|
|
||||||
|
property ChatMessageContentProxy filescontentProxy: ChatMessageContentProxy {
|
||||||
|
filterType: ChatMessageContentProxy.FilterContentType.File
|
||||||
|
chatMessageGui: mainItem.chatMessageGui
|
||||||
|
}
|
||||||
|
|
||||||
// VOICE MESSAGES
|
// VOICE MESSAGES
|
||||||
Repeater {
|
Repeater {
|
||||||
id: messagesVoicesList
|
id: messagesVoicesList
|
||||||
|
|
@ -70,15 +76,39 @@ ColumnLayout {
|
||||||
onMouseEvent: (event) => mainItem.mouseEvent(event)
|
onMouseEvent: (event) => mainItem.mouseEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// SINGLE FILE
|
||||||
|
ImageFileView {
|
||||||
|
id: singleImageFile
|
||||||
|
visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isImage(contentGui.core.filePath)
|
||||||
|
contentGui: mainItem.filescontentProxy.count === 1
|
||||||
|
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
|
||||||
|
: null
|
||||||
|
width: Math.round(285 * DefaultStyle.dp)
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
AnimatedImageFileView {
|
||||||
|
id: singleAnimatedImageFile
|
||||||
|
visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isAnimatedImage(contentGui.core.filePath)
|
||||||
|
contentGui: mainItem.filescontentProxy.count === 1
|
||||||
|
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
|
||||||
|
: null
|
||||||
|
Layout.preferredWidth: Math.round(285 * DefaultStyle.dp)
|
||||||
|
Layout.preferredHeight: paintedHeight
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
// FILES
|
// FILES
|
||||||
ChatFilesGridLayout {
|
ChatFilesGridLayout {
|
||||||
id: messageFilesList
|
id: messageFilesList
|
||||||
visible: itemCount > 0
|
visible: mainItem.filescontentProxy.count > 0
|
||||||
Layout.fillWidth: true
|
&& !singleImageFile.visible
|
||||||
|
&& !singleAnimatedImageFile.visible
|
||||||
|
Layout.fillWidth: visible
|
||||||
|
Layout.fillHeight: visible
|
||||||
maxWidth: Math.round(115*3 * DefaultStyle.dp)
|
maxWidth: Math.round(115*3 * DefaultStyle.dp)
|
||||||
Layout.fillHeight: true
|
// Layout.fillHeight: true
|
||||||
// Layout.preferredHeight: contentHeight
|
proxyModel: visible ? mainItem.filescontentProxy : null
|
||||||
chatMessageGui: mainItem.chatMessageGui
|
|
||||||
// onIsHoveringFileChanged: mainItem.isFileHoveringChanged(isHoveringFile)
|
// onIsHoveringFileChanged: mainItem.isFileHoveringChanged(isHoveringFile)
|
||||||
// borderWidth: mainItem.fileBorderWidth
|
// borderWidth: mainItem.fileBorderWidth
|
||||||
// property int availableSection: mainItem.availableWidth / mainItem.filesBestWidth
|
// property int availableSection: mainItem.availableWidth / mainItem.filesBestWidth
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,6 @@ Item {
|
||||||
property bool isImage: UtilsCpp.isImage(filePath)
|
property bool isImage: UtilsCpp.isImage(filePath)
|
||||||
property bool isPdf: UtilsCpp.isPdf(filePath)
|
property bool isPdf: UtilsCpp.isPdf(filePath)
|
||||||
property bool isThumbnail: isVideo || isImage || isPdf
|
property bool isThumbnail: isVideo || isImage || isPdf
|
||||||
property int overriddenWidth
|
|
||||||
property int overriddenHeight
|
|
||||||
// property to change default view display
|
// property to change default view display
|
||||||
property bool showAsSquare: true
|
property bool showAsSquare: true
|
||||||
// default image
|
// default image
|
||||||
|
|
@ -40,6 +38,7 @@ Item {
|
||||||
? AppIcons.fileText
|
? AppIcons.fileText
|
||||||
: AppIcons.file
|
: AppIcons.file
|
||||||
: ''
|
: ''
|
||||||
|
property var thumbnailFillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
enabled: contentGui
|
enabled: contentGui
|
||||||
|
|
@ -60,12 +59,9 @@ Item {
|
||||||
id: thumbnailImage
|
id: thumbnailImage
|
||||||
Item {
|
Item {
|
||||||
id: thumbnailSource
|
id: thumbnailSource
|
||||||
property bool isVideo: UtilsCpp.isVideo(mainItem.filePath)
|
|
||||||
property bool isImage: UtilsCpp.isImage(mainItem.filePath)
|
|
||||||
property bool isPdf: UtilsCpp.isPdf(mainItem.filePath)
|
|
||||||
Image {
|
Image {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: thumbnailSource.isPdf
|
visible: mainItem.isPdf
|
||||||
source: AppIcons.filePdf
|
source: AppIcons.filePdf
|
||||||
sourceSize.width: mainItem.width
|
sourceSize.width: mainItem.width
|
||||||
sourceSize.height: mainItem.height
|
sourceSize.height: mainItem.height
|
||||||
|
|
@ -82,24 +78,24 @@ Item {
|
||||||
}
|
}
|
||||||
Image {
|
Image {
|
||||||
id: image
|
id: image
|
||||||
visible: thumbnailSource.isImage && status !== Image.Loading
|
visible: mainItem.isImage && status !== Image.Loading
|
||||||
mipmap: false//SettingsModel.mipmapEnabled
|
mipmap: false//SettingsModel.mipmapEnabled
|
||||||
source: mainItem.thumbnail
|
source: mainItem.thumbnail
|
||||||
sourceSize.width: mainItem.width
|
sourceSize.width: mainItem.width
|
||||||
sourceSize.height: mainItem.height
|
sourceSize.height: mainItem.height
|
||||||
autoTransform: true
|
autoTransform: true
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
fillMode: mainItem.thumbnailFillMode
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: thumbnailSource.isVideo
|
visible: mainItem.isVideo
|
||||||
color: DefaultStyle.grey_1000
|
color: DefaultStyle.grey_1000
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Video {
|
Video {
|
||||||
id: videoThumbnail
|
id: videoThumbnail
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
position: 100
|
position: 100
|
||||||
source: "file:///" + mainItem.filePath
|
source: mainItem.isVideo ? "file:///" + mainItem.filePath : ""
|
||||||
fillMode: playbackState === MediaPlayer.PlayingState ? VideoOutput.PreserveAspectFit : VideoOutput.PreserveAspectCrop
|
fillMode: playbackState === MediaPlayer.PlayingState ? VideoOutput.PreserveAspectFit : VideoOutput.PreserveAspectCrop
|
||||||
MouseArea {
|
MouseArea {
|
||||||
propagateComposedEvents: false
|
propagateComposedEvents: false
|
||||||
|
|
|
||||||
56
Linphone/view/Control/Display/Chat/ImageFileView.qml
Normal file
56
Linphone/view/Control/Display/Chat/ImageFileView.qml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls as Control
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtMultimedia
|
||||||
|
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp
|
||||||
|
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Separated file to show a single image bigger in chat message
|
||||||
|
// The FileView file does not allow that as it is a Loader and the image
|
||||||
|
// is reloaded everytime the message becomes visible again. It causes the
|
||||||
|
// chat message not to be able to adapt its size according to the painted
|
||||||
|
// size of the image
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
Image {
|
||||||
|
id: mainItem
|
||||||
|
property ChatMessageContentGui contentGui
|
||||||
|
|
||||||
|
mipmap: false//SettingsModel.mipmapEnabled
|
||||||
|
autoTransform: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: contentGui && contentGui.core.thumbnail || ""
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: 'hovered'
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
// Changing cursor in MouseArea seems not to work with the Loader
|
||||||
|
// Use override cursor for this case
|
||||||
|
onContainsMouseChanged: {
|
||||||
|
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
|
||||||
|
else UtilsCpp.restoreGlobalCursor()
|
||||||
|
mainItem.state = containsMouse ? 'hovered' : ''
|
||||||
|
}
|
||||||
|
onPressed: (mouse) => {
|
||||||
|
mouse.accepted = true
|
||||||
|
// if(SettingsModel.isVfsEncrypted){
|
||||||
|
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
|
||||||
|
// contentGui: mainItem.contentGui,
|
||||||
|
// }, function (status) {
|
||||||
|
// })
|
||||||
|
// }else
|
||||||
|
mainItem.contentGui.core.lOpenFile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue