merge upstream
This commit is contained in:
commit
dfdad76d97
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/spectral.iml" filepath="$PROJECT_DIR$/.idea/spectral.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="CPP_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/include/SortFilterProxyModel" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/include/libqmatrixclient" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,153 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeRunConfigurationManager" shouldGenerate="true" shouldDeleteObsolete="true">
|
||||
<generated />
|
||||
</component>
|
||||
<component name="CMakeSettings">
|
||||
<configurations>
|
||||
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
|
||||
</configurations>
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="1dc08437-54b4-4b19-9a54-6472ca11c95f" name="Default Changelist" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/include/libqmatrixclient" beforeDir="false" afterPath="$PROJECT_DIR$/include/libqmatrixclient" afterDir="false" />
|
||||
</list>
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ClangdSettings">
|
||||
<option name="formatViaClangd" value="false" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/src/spectraluser.cpp">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="75">
|
||||
<caret line="5" lean-forward="true" selection-start-line="5" selection-end-line="5" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="CHANGED_PATHS">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/src/spectraluser.cpp" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="MacroExpansionManager">
|
||||
<option name="directoryName" value="KjZzvpQi" />
|
||||
</component>
|
||||
<component name="ProjectConfigurationFiles">
|
||||
<option name="files">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/.idea/spectral.iml" />
|
||||
<option value="$PROJECT_DIR$/.idea/vcs.xml" />
|
||||
<option value="$PROJECT_DIR$/.idea/modules.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds">
|
||||
<option name="x" value="1928" />
|
||||
<option name="y" value="8" />
|
||||
<option name="width" value="539" />
|
||||
<option name="height" value="687" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||
<component name="ProjectView">
|
||||
<navigator proportions="" version="1">
|
||||
<foldersAlwaysOnTop value="true" />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
<path>
|
||||
<item name="spectral" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="spectral" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="spectral" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="spectral" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="Scope" />
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="RunDashboard">
|
||||
<option name="ruleStates">
|
||||
<list>
|
||||
<RuleState>
|
||||
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
<RuleState>
|
||||
<option name="name" value="StatusDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="1dc08437-54b4-4b19-9a54-6472ca11c95f" name="Default Changelist" comment="" />
|
||||
<created>1558287890866</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1558287890866</updated>
|
||||
<workItem from="1558287893419" duration="176000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TimeTrackingManager">
|
||||
<option name="totallyTimeSpent" value="176000" />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="1928" y="8" width="539" height="687" extended-state="0" />
|
||||
<layout>
|
||||
<window_info id="Favorites" side_tool="true" />
|
||||
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.6136821" />
|
||||
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Database Changes" />
|
||||
<window_info anchor="bottom" id="Version Control" />
|
||||
<window_info anchor="bottom" id="Terminal" />
|
||||
<window_info anchor="bottom" id="Event Log" side_tool="true" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" />
|
||||
<window_info anchor="bottom" id="Run" order="2" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
<window_info anchor="bottom" id="TODO" order="6" />
|
||||
<window_info anchor="right" id="Cargo" />
|
||||
<window_info anchor="right" id="Database" />
|
||||
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
|
||||
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/src/spectraluser.cpp">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="75">
|
||||
<caret line="5" lean-forward="true" selection-start-line="5" selection-end-line="5" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,71 @@
|
|||
import QtQuick 2.12
|
||||
|
||||
Rectangle {
|
||||
property alias topLeftRadius: topLeftRect.radius
|
||||
property alias topRightRadius: topRightRect.radius
|
||||
property alias bottomLeftRadius: bottomLeftRect.radius
|
||||
property alias bottomRightRadius: bottomRightRect.radius
|
||||
|
||||
property alias topLeftVisible: topLeftRect.visible
|
||||
property alias topRightVisible: topRightRect.visible
|
||||
property alias bottomLeftVisible: bottomLeftRect.visible
|
||||
property alias bottomRightVisible: bottomRightRect.visible
|
||||
|
||||
antialiasing: true
|
||||
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
||||
id: topLeftRect
|
||||
|
||||
antialiasing: true
|
||||
|
||||
color: parent.color
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
||||
id: topRightRect
|
||||
|
||||
antialiasing: true
|
||||
|
||||
color: parent.color
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
||||
id: bottomLeftRect
|
||||
|
||||
antialiasing: true
|
||||
|
||||
color: parent.color
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
||||
id: bottomRightRect
|
||||
|
||||
antialiasing: true
|
||||
|
||||
color: parent.color
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ import QtQuick 2.12
|
|||
import QtQuick.Controls 2.12
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import Spectral.Setting 0.1
|
||||
|
||||
Item {
|
||||
property string hint: "H"
|
||||
property string source: ""
|
||||
|
@ -35,7 +37,7 @@ Item {
|
|||
visible: !realSource || image.status != Image.Ready
|
||||
|
||||
radius: height / 2
|
||||
color: stringToColor(hint)
|
||||
color: MPalette.accent
|
||||
antialiasing: true
|
||||
|
||||
Label {
|
||||
|
@ -50,16 +52,16 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
function stringToColor(str) {
|
||||
var hash = 0;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
var colour = '#';
|
||||
for (var j = 0; j < 3; j++) {
|
||||
var value = (hash >> (j * 8)) & 0xFF;
|
||||
colour += ('00' + value.toString(16)).substr(-2);
|
||||
}
|
||||
return colour;
|
||||
}
|
||||
// function stringToColor(str) {
|
||||
// var hash = 0;
|
||||
// for (var i = 0; i < str.length; i++) {
|
||||
// hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
// }
|
||||
// var colour = '#';
|
||||
// for (var j = 0; j < 3; j++) {
|
||||
// var value = (hash >> (j * 8)) & 0xFF;
|
||||
// colour += ('00' + value.toString(16)).substr(-2);
|
||||
// }
|
||||
// return colour;
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -67,65 +67,25 @@ ColumnLayout {
|
|||
Control {
|
||||
Layout.maximumWidth: messageListView.width - (!sentByMe ? 36 + messageRow.spacing : 0) - 48
|
||||
|
||||
verticalPadding: 8
|
||||
horizontalPadding: 16
|
||||
padding: 0
|
||||
|
||||
background: AutoRectangle {
|
||||
readonly property int minorRadius: 2
|
||||
|
||||
id: bubbleBackground
|
||||
|
||||
background: Rectangle {
|
||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
||||
radius: 18
|
||||
antialiasing: true
|
||||
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
topLeftVisible: true
|
||||
topRightVisible: true
|
||||
bottomLeftVisible: true
|
||||
bottomRightVisible: true
|
||||
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
||||
visible: true
|
||||
|
||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
||||
radius: 5
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
||||
visible: true
|
||||
|
||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
||||
radius: 5
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
||||
visible: true
|
||||
|
||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
||||
radius: 5
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
||||
visible: true
|
||||
|
||||
color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent
|
||||
radius: 5
|
||||
}
|
||||
topLeftRadius: minorRadius
|
||||
topRightRadius: minorRadius
|
||||
bottomLeftRadius: minorRadius
|
||||
bottomRightRadius: minorRadius
|
||||
|
||||
AutoMouseArea {
|
||||
anchors.fill: parent
|
||||
|
@ -166,63 +126,72 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
|
||||
Control {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Layout.topMargin: 8
|
||||
Layout.leftMargin: 8
|
||||
Layout.rightMargin: 8
|
||||
|
||||
padding: 4
|
||||
rightPadding: 12
|
||||
|
||||
visible: replyVisible
|
||||
|
||||
Avatar {
|
||||
Layout.preferredWidth: 28
|
||||
Layout.preferredHeight: 28
|
||||
Layout.alignment: Qt.AlignTop
|
||||
contentItem: RowLayout {
|
||||
Avatar {
|
||||
Layout.preferredWidth: 28
|
||||
Layout.preferredHeight: 28
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
source: replyVisible ? replyAuthor.avatarMediaId : ""
|
||||
hint: replyVisible ? replyAuthor.displayName : "H"
|
||||
source: replyVisible ? replyAuthor.avatarMediaId : ""
|
||||
hint: replyVisible ? replyAuthor.displayName : "H"
|
||||
|
||||
RippleEffect {
|
||||
anchors.fill: parent
|
||||
RippleEffect {
|
||||
anchors.fill: parent
|
||||
|
||||
circular: true
|
||||
circular: true
|
||||
|
||||
onClicked: userDetailDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom, "user": replyAuthor}).open()
|
||||
}
|
||||
}
|
||||
|
||||
Control {
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: replyVisible
|
||||
|
||||
padding: 0
|
||||
|
||||
background: RippleEffect {
|
||||
onClicked: goToEvent(replyEventId)
|
||||
onClicked: userDetailDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom, "user": replyAuthor}).open()
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Label {
|
||||
color: darkBackground ? "white" : MPalette.lighter
|
||||
text: "<style>a{color: " + (darkBackground ? "white" : MPalette.foreground) + ";} .user-pill{}</style>" + (replyDisplay || "")
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
|
||||
color: !sentByMe ? MPalette.foreground : "white"
|
||||
text: "<style>a{color: " + color + ";} .user-pill{}</style>" + (replyDisplay || "")
|
||||
|
||||
wrapMode: Label.Wrap
|
||||
textFormat: Label.RichText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
background: Rectangle {
|
||||
color: sentByMe ? MPalette.accent : MPalette.background
|
||||
radius: 18
|
||||
|
||||
visible: replyVisible
|
||||
color: darkBackground ? "white" : MPalette.lighter
|
||||
AutoMouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onClicked: goToEvent(replyEventId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextEdit {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.topMargin: 8
|
||||
Layout.bottomMargin: 8
|
||||
|
||||
id: contentLabel
|
||||
|
||||
text: "<style>a{color: " + (darkBackground ? "white" : MPalette.foreground) + ";} .user-pill{}</style>" + display
|
||||
text: "<style>a{color: " + color + ";} .user-pill{}</style>" + display
|
||||
|
||||
color: darkBackground ? "white" : MPalette.foreground
|
||||
|
||||
|
|
|
@ -7,3 +7,4 @@ AutoListView 2.0 AutoListView.qml
|
|||
AutoTextField 2.0 AutoTextField.qml
|
||||
Avatar 2.0 Avatar.qml
|
||||
FullScreenImage 2.0 FullScreenImage.qml
|
||||
AutoRectangle 2.0 AutoRectangle.qml
|
||||
|
|
|
@ -27,8 +27,8 @@ Dialog {
|
|||
Layout.preferredWidth: 72
|
||||
Layout.preferredHeight: 72
|
||||
|
||||
hint: user ? user.displayName : "No name"
|
||||
source: user ? user.avatarMediaId : null
|
||||
hint: user.displayName
|
||||
source: user.avatarMediaId
|
||||
|
||||
RippleEffect {
|
||||
anchors.fill: parent
|
||||
|
@ -50,10 +50,19 @@ Dialog {
|
|||
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
text: user ? user.displayName : "No Name"
|
||||
text: user.displayName
|
||||
color: MPalette.foreground
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: user.bridgeName
|
||||
|
||||
text: user.bridgeName
|
||||
color: MPalette.lighter
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
|
||||
|
@ -89,7 +98,7 @@ Dialog {
|
|||
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
text: user ? user.id : "No ID"
|
||||
text: user.id
|
||||
color: MPalette.accent
|
||||
}
|
||||
|
||||
|
|
|
@ -11,3 +11,4 @@ FontFamilyDialog 2.0 FontFamilyDialog.qml
|
|||
AccountDetailDialog 2.0 AccountDetailDialog.qml
|
||||
OpenFileDialog 2.0 OpenFileDialog.qml
|
||||
OpenFolderDialog 2.0 OpenFolderDialog.qml
|
||||
ImageClipboardDialog 2.0 ImageClipboardDialog.qml
|
||||
|
|
|
@ -31,7 +31,7 @@ Item {
|
|||
|
||||
connection: root.connection
|
||||
|
||||
onNewMessage: if (!window.active && MSettings.showNotification) spectralController.postNotification(roomId, eventId, roomName, senderName, text, icon)
|
||||
onNewMessage: if (!window.active && MSettings.showNotification) notificationsManager.postNotification(roomId, eventId, roomName, senderName, text, icon)
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
|
@ -54,6 +54,16 @@ Item {
|
|||
|
||||
sorters: [
|
||||
RoleSorter { roleName: "category" },
|
||||
ExpressionSorter {
|
||||
expression: {
|
||||
return modelLeft.highlightCount > 0;
|
||||
}
|
||||
},
|
||||
ExpressionSorter {
|
||||
expression: {
|
||||
return modelLeft.notificationCount > 0;
|
||||
}
|
||||
},
|
||||
RoleSorter {
|
||||
roleName: "lastActiveTime"
|
||||
sortOrder: Qt.DescendingOrder
|
||||
|
|
|
@ -3,10 +3,12 @@ import QtQuick.Controls 2.12
|
|||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import Qt.labs.qmlmodels 1.0
|
||||
import Qt.labs.platform 1.0
|
||||
|
||||
import Spectral.Component 2.0
|
||||
import Spectral.Component.Emoji 2.0
|
||||
import Spectral.Component.Timeline 2.0
|
||||
import Spectral.Dialog 2.0
|
||||
import Spectral.Effect 2.0
|
||||
|
||||
import Spectral 0.1
|
||||
|
@ -23,6 +25,121 @@ Item {
|
|||
room: currentRoom
|
||||
}
|
||||
|
||||
DropArea {
|
||||
anchors.fill: parent
|
||||
|
||||
enabled: currentRoom
|
||||
|
||||
onDropped: {
|
||||
if (!drop.hasUrls) return
|
||||
|
||||
roomPanelInput.attach(drop.urls[0])
|
||||
}
|
||||
}
|
||||
|
||||
ImageClipboard {
|
||||
id: imageClipboard
|
||||
}
|
||||
|
||||
Popup {
|
||||
anchors.centerIn: parent
|
||||
|
||||
id: attachDialog
|
||||
|
||||
padding: 16
|
||||
|
||||
contentItem: RowLayout {
|
||||
Control {
|
||||
Layout.preferredWidth: 160
|
||||
Layout.fillHeight: true
|
||||
|
||||
padding: 16
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 16
|
||||
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
icon: "\ue2c8"
|
||||
font.pixelSize: 64
|
||||
color: MPalette.lighter
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
text: "Choose local file"
|
||||
}
|
||||
}
|
||||
|
||||
background: RippleEffect {
|
||||
onClicked: {
|
||||
attachDialog.close()
|
||||
|
||||
var fileDialog = openFileDialog.createObject(ApplicationWindow.overlay)
|
||||
|
||||
fileDialog.chosen.connect(function(path) {
|
||||
if (!path) return
|
||||
|
||||
roomPanelInput.attach(path)
|
||||
})
|
||||
|
||||
fileDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 1
|
||||
Layout.fillHeight: true
|
||||
|
||||
color: MPalette.banner
|
||||
}
|
||||
|
||||
Control {
|
||||
Layout.preferredWidth: 160
|
||||
Layout.fillHeight: true
|
||||
|
||||
padding: 16
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 16
|
||||
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
icon: "\ue410"
|
||||
font.pixelSize: 64
|
||||
color: MPalette.lighter
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
text: "Clipboard image"
|
||||
color: MPalette.foreground
|
||||
}
|
||||
}
|
||||
|
||||
background: RippleEffect {
|
||||
onClicked: {
|
||||
var localPath = StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/screenshots/" + (new Date()).getTime() + ".png"
|
||||
if (!imageClipboard.saveImage(localPath)) return
|
||||
roomPanelInput.attach(localPath)
|
||||
attachDialog.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: openFileDialog
|
||||
|
||||
OpenFileDialog {}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import QtQuick.Controls.Material 2.12
|
|||
|
||||
import Spectral.Component 2.0
|
||||
import Spectral.Component.Emoji 2.0
|
||||
import Spectral.Dialog 2.0
|
||||
import Spectral.Effect 2.0
|
||||
import Spectral.Setting 0.1
|
||||
|
||||
|
@ -21,6 +22,9 @@ Control {
|
|||
property int autoCompleteBeginPosition
|
||||
property int autoCompleteEndPosition
|
||||
|
||||
property bool hasAttachment: false
|
||||
property url attachmentPath
|
||||
|
||||
id: root
|
||||
|
||||
padding: 0
|
||||
|
@ -171,13 +175,13 @@ Control {
|
|||
Layout.alignment: Qt.AlignBottom
|
||||
|
||||
id: uploadButton
|
||||
visible: !isReply
|
||||
visible: !isReply && !hasAttachment
|
||||
|
||||
contentItem: MaterialIcon {
|
||||
icon: "\ue226"
|
||||
}
|
||||
|
||||
onClicked: currentRoom.chooseAndUploadFile()
|
||||
onClicked: attachDialog.open()
|
||||
|
||||
BusyIndicator {
|
||||
anchors.fill: parent
|
||||
|
@ -202,6 +206,51 @@ Control {
|
|||
onClicked: clearReply()
|
||||
}
|
||||
|
||||
Control {
|
||||
Layout.margins: 6
|
||||
Layout.preferredHeight: 36
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
visible: hasAttachment
|
||||
|
||||
rightPadding: 8
|
||||
|
||||
background: Rectangle {
|
||||
color: MPalette.accent
|
||||
radius: height / 2
|
||||
antialiasing: true
|
||||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 0
|
||||
|
||||
ToolButton {
|
||||
Layout.preferredWidth: height
|
||||
Layout.fillHeight: true
|
||||
|
||||
id: cancelAttachmentButton
|
||||
|
||||
contentItem: MaterialIcon {
|
||||
icon: "\ue5cd"
|
||||
color: "white"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
hasAttachment = false
|
||||
attachmentPath = ""
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
text: attachmentPath != "" ? attachmentPath.toString().substring(attachmentPath.toString().lastIndexOf('/') + 1, attachmentPath.length) : ""
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextArea {
|
||||
property real progress: 0
|
||||
|
||||
|
@ -252,7 +301,7 @@ Control {
|
|||
Keys.onReturnPressed: {
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
insert(cursorPosition, "\n")
|
||||
} else if (text) {
|
||||
} else {
|
||||
postMessage(text)
|
||||
text = ""
|
||||
closeAll()
|
||||
|
@ -304,9 +353,16 @@ Control {
|
|||
}
|
||||
|
||||
function postMessage(text) {
|
||||
if (text.trim().length === 0) { return }
|
||||
if(!currentRoom) { return }
|
||||
|
||||
if (hasAttachment) {
|
||||
currentRoom.uploadFile(attachmentPath, text)
|
||||
clearAttachment()
|
||||
return
|
||||
}
|
||||
|
||||
if (text.trim().length === 0) { return }
|
||||
|
||||
var PREFIX_ME = '/me '
|
||||
var PREFIX_NOTICE = '/notice '
|
||||
var PREFIX_RAINBOW = '/rainbow '
|
||||
|
@ -372,6 +428,10 @@ Control {
|
|||
}
|
||||
}
|
||||
|
||||
ImageClipboard {
|
||||
id: imageClipboard
|
||||
}
|
||||
|
||||
function insert(str) {
|
||||
inputField.insert(inputField.cursorPosition, str)
|
||||
}
|
||||
|
@ -396,4 +456,14 @@ Control {
|
|||
autoCompleteListView.visible = false
|
||||
emojiPicker.visible = false
|
||||
}
|
||||
|
||||
function attach(localPath) {
|
||||
hasAttachment = true
|
||||
attachmentPath = localPath
|
||||
}
|
||||
|
||||
function clearAttachment() {
|
||||
hasAttachment = false
|
||||
attachmentPath = ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 52a81dfa8a5415be369d819837f445479b833cde
|
||||
Subproject commit d6f39dcb0de69322479f287514a8c36afcb3fe7b
|
|
@ -56,12 +56,17 @@ ApplicationWindow {
|
|||
|
||||
quitOnLastWindowClosed: !MSettings.showTray
|
||||
|
||||
onErrorOccured: errorControl.show(error + ": " + detail, 3000)
|
||||
}
|
||||
|
||||
NotificationsManager {
|
||||
id: notificationsManager
|
||||
|
||||
onNotificationClicked: {
|
||||
roomListForm.enteredRoom = spectralController.connection.room(roomId)
|
||||
roomForm.goToEvent(eventId)
|
||||
showWindow()
|
||||
}
|
||||
onErrorOccured: errorControl.show(error + ": " + detail, 3000)
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
|
|
1
res.qrc
1
res.qrc
|
@ -58,5 +58,6 @@
|
|||
<file>imports/Spectral/Dialog/OpenFileDialog.qml</file>
|
||||
<file>imports/Spectral/Dialog/OpenFolderDialog.qml</file>
|
||||
<file>imports/Spectral/Component/Timeline/VideoDelegate.qml</file>
|
||||
<file>imports/Spectral/Component/AutoRectangle.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
10
spectral.pro
10
spectral.pro
|
@ -117,7 +117,6 @@ mac {
|
|||
HEADERS += \
|
||||
src/controller.h \
|
||||
src/roomlistmodel.h \
|
||||
src/imageprovider.h \
|
||||
src/messageeventmodel.h \
|
||||
src/emojimodel.h \
|
||||
src/spectralroom.h \
|
||||
|
@ -125,19 +124,22 @@ HEADERS += \
|
|||
src/accountlistmodel.h \
|
||||
src/spectraluser.h \
|
||||
src/notifications/manager.h \
|
||||
src/utils.h
|
||||
src/utils.h \
|
||||
src/imageclipboard.h \
|
||||
src/matriximageprovider.h
|
||||
|
||||
SOURCES += src/main.cpp \
|
||||
src/controller.cpp \
|
||||
src/roomlistmodel.cpp \
|
||||
src/imageprovider.cpp \
|
||||
src/messageeventmodel.cpp \
|
||||
src/emojimodel.cpp \
|
||||
src/spectralroom.cpp \
|
||||
src/userlistmodel.cpp \
|
||||
src/accountlistmodel.cpp \
|
||||
src/spectraluser.cpp \
|
||||
src/utils.cpp
|
||||
src/utils.cpp \
|
||||
src/imageclipboard.cpp \
|
||||
src/matriximageprovider.cpp
|
||||
|
||||
unix:!mac {
|
||||
SOURCES += src/notifications/managerlinux.cpp
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.9.0, 2019-05-19T18:51:54. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{7614c50b-52db-49bf-a585-31417a3c0f62}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
|
||||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 5.12.1 (System)</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 5.12.1 (System)</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{97a6fc6e-df2b-4272-9664-99a23fd81def}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/tanuj/code/spectral/build</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
||||
<value type="QString">cpu-cycles</value>
|
||||
</valuelist>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
||||
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
||||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">spectral</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/tanuj/code/spectral/spectral.pro</value>
|
||||
<value type="QString" key="RunConfiguration.Arguments"></value>
|
||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/tanuj/code/spectral/build</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">21</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">21</value>
|
||||
</data>
|
||||
</qtcreator>
|
|
@ -31,13 +31,9 @@
|
|||
#include <QtNetwork/QAuthenticator>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
Controller::Controller(QObject* parent)
|
||||
: QObject(parent), notificationsManager(this) {
|
||||
Controller::Controller(QObject* parent) : QObject(parent) {
|
||||
QApplication::setQuitOnLastWindowClosed(false);
|
||||
|
||||
connect(¬ificationsManager, &NotificationsManager::notificationClicked,
|
||||
this, &Controller::notificationClicked);
|
||||
|
||||
Connection::setRoomType<SpectralRoom>();
|
||||
Connection::setUserType<SpectralUser>();
|
||||
|
||||
|
@ -232,10 +228,6 @@ void Controller::createDirectChat(Connection* c, const QString& userID) {
|
|||
});
|
||||
}
|
||||
|
||||
void Controller::copyToClipboard(const QString& text) {
|
||||
m_clipboard->setText(text);
|
||||
}
|
||||
|
||||
void Controller::playAudio(QUrl localFile) {
|
||||
QMediaPlayer* player = new QMediaPlayer;
|
||||
player->setMedia(localFile);
|
||||
|
@ -243,16 +235,6 @@ void Controller::playAudio(QUrl localFile) {
|
|||
connect(player, &QMediaPlayer::stateChanged, [=] { player->deleteLater(); });
|
||||
}
|
||||
|
||||
void Controller::postNotification(const QString& roomId,
|
||||
const QString& eventId,
|
||||
const QString& roomName,
|
||||
const QString& senderName,
|
||||
const QString& text,
|
||||
const QImage& icon) {
|
||||
notificationsManager.postNotification(roomId, eventId, roomName, senderName,
|
||||
text, icon);
|
||||
}
|
||||
|
||||
int Controller::dpi() {
|
||||
return SettingsGroup("Interface").value("dpi", 100).toInt();
|
||||
}
|
||||
|
|
|
@ -67,8 +67,6 @@ class Controller : public QObject {
|
|||
}
|
||||
|
||||
private:
|
||||
QClipboard* m_clipboard = QApplication::clipboard();
|
||||
NotificationsManager notificationsManager;
|
||||
QVector<Connection*> m_connections;
|
||||
QPointer<Connection> m_connection;
|
||||
|
||||
|
@ -99,14 +97,7 @@ class Controller : public QObject {
|
|||
void joinRoom(Connection* c, const QString& alias);
|
||||
void createRoom(Connection* c, const QString& name, const QString& topic);
|
||||
void createDirectChat(Connection* c, const QString& userID);
|
||||
void copyToClipboard(const QString& text);
|
||||
void playAudio(QUrl localFile);
|
||||
void postNotification(const QString& roomId,
|
||||
const QString& eventId,
|
||||
const QString& roomName,
|
||||
const QString& senderName,
|
||||
const QString& text,
|
||||
const QImage& icon);
|
||||
};
|
||||
|
||||
#endif // CONTROLLER_H
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#include "imageclipboard.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QGuiApplication>
|
||||
#include <QUrl>
|
||||
#include <QtDebug>
|
||||
|
||||
ImageClipboard::ImageClipboard(QObject* parent)
|
||||
: QObject(parent), m_clipboard(QGuiApplication::clipboard()) {
|
||||
connect(m_clipboard, &QClipboard::changed, this,
|
||||
&ImageClipboard::imageChanged);
|
||||
}
|
||||
|
||||
bool ImageClipboard::hasImage() {
|
||||
return !image().isNull();
|
||||
}
|
||||
|
||||
QImage ImageClipboard::image() {
|
||||
return m_clipboard->image();
|
||||
}
|
||||
|
||||
bool ImageClipboard::saveImage(const QUrl& localPath) {
|
||||
if (!localPath.isLocalFile())
|
||||
return false;
|
||||
|
||||
auto i = image();
|
||||
|
||||
if (i.isNull())
|
||||
return false;
|
||||
|
||||
QString path = QFileInfo(localPath.toString()).absolutePath();
|
||||
QDir dir;
|
||||
if (!dir.exists(path))
|
||||
dir.mkpath(path);
|
||||
|
||||
i.save(localPath.toLocalFile());
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef IMAGECLIPBOARD_H
|
||||
#define IMAGECLIPBOARD_H
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QImage>
|
||||
#include <QObject>
|
||||
|
||||
class ImageClipboard : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool hasImage READ hasImage NOTIFY imageChanged)
|
||||
Q_PROPERTY(QImage image READ image NOTIFY imageChanged)
|
||||
|
||||
public:
|
||||
explicit ImageClipboard(QObject* parent = nullptr);
|
||||
|
||||
bool hasImage();
|
||||
QImage image();
|
||||
|
||||
Q_INVOKABLE bool saveImage(const QUrl& localPath);
|
||||
|
||||
private:
|
||||
QClipboard* m_clipboard;
|
||||
|
||||
signals:
|
||||
void imageChanged();
|
||||
};
|
||||
|
||||
#endif // IMAGECLIPBOARD_H
|
14
src/main.cpp
14
src/main.cpp
|
@ -8,8 +8,10 @@
|
|||
#include "accountlistmodel.h"
|
||||
#include "controller.h"
|
||||
#include "emojimodel.h"
|
||||
#include "imageprovider.h"
|
||||
#include "imageclipboard.h"
|
||||
#include "matriximageprovider.h"
|
||||
#include "messageeventmodel.h"
|
||||
#include "notifications/manager.h"
|
||||
#include "room.h"
|
||||
#include "roomlistmodel.h"
|
||||
#include "spectralroom.h"
|
||||
|
@ -55,6 +57,9 @@ int main(int argc, char* argv[]) {
|
|||
qmlRegisterType<UserListModel>("Spectral", 0, 1, "UserListModel");
|
||||
qmlRegisterType<MessageEventModel>("Spectral", 0, 1, "MessageEventModel");
|
||||
qmlRegisterType<EmojiModel>("Spectral", 0, 1, "EmojiModel");
|
||||
qmlRegisterType<NotificationsManager>("Spectral", 0, 1,
|
||||
"NotificationsManager");
|
||||
qmlRegisterType<ImageClipboard>("Spectral", 0, 1, "ImageClipboard");
|
||||
qmlRegisterUncreatableType<RoomMessageEvent>("Spectral", 0, 1,
|
||||
"RoomMessageEvent", "ENUM");
|
||||
qmlRegisterUncreatableType<RoomType>("Spectral", 0, 1, "RoomType", "ENUM");
|
||||
|
@ -72,9 +77,10 @@ int main(int argc, char* argv[]) {
|
|||
QQmlApplicationEngine engine;
|
||||
|
||||
engine.addImportPath("qrc:/imports");
|
||||
ImageProvider* m_provider = new ImageProvider();
|
||||
engine.rootContext()->setContextProperty("imageProvider", m_provider);
|
||||
engine.addImageProvider(QLatin1String("mxc"), m_provider);
|
||||
MatrixImageProvider* matrixImageProvider = new MatrixImageProvider();
|
||||
engine.rootContext()->setContextProperty("imageProvider",
|
||||
matrixImageProvider);
|
||||
engine.addImageProvider(QLatin1String("mxc"), matrixImageProvider);
|
||||
|
||||
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
|
||||
if (engine.rootObjects().isEmpty())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "imageprovider.h"
|
||||
#include "matriximageprovider.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
@ -108,7 +108,7 @@ void ThumbnailResponse::cancel() {
|
|||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
QQuickImageResponse* ImageProvider::requestImageResponse(
|
||||
QQuickImageResponse* MatrixImageProvider::requestImageResponse(
|
||||
const QString& id,
|
||||
const QSize& requestedSize) {
|
||||
return new ThumbnailResponse(m_connection.load(), id, requestedSize);
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef IMAGEPROVIDER_H
|
||||
#define IMAGEPROVIDER_H
|
||||
#ifndef MatrixImageProvider_H
|
||||
#define MatrixImageProvider_H
|
||||
#pragma once
|
||||
|
||||
#include <QtQuick/QQuickAsyncImageProvider>
|
||||
|
@ -43,12 +43,12 @@ class ThumbnailResponse : public QQuickImageResponse {
|
|||
void cancel() override;
|
||||
};
|
||||
|
||||
class ImageProvider : public QObject, public QQuickAsyncImageProvider {
|
||||
class MatrixImageProvider : public QObject, public QQuickAsyncImageProvider {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QMatrixClient::Connection* connection READ connection WRITE
|
||||
setConnection NOTIFY connectionChanged)
|
||||
public:
|
||||
explicit ImageProvider() = default;
|
||||
explicit MatrixImageProvider() = default;
|
||||
|
||||
QQuickImageResponse* requestImageResponse(
|
||||
const QString& id,
|
||||
|
@ -67,4 +67,4 @@ class ImageProvider : public QObject, public QQuickAsyncImageProvider {
|
|||
QAtomicPointer<QMatrixClient::Connection> m_connection;
|
||||
};
|
||||
|
||||
#endif // IMAGEPROVIDER_H
|
||||
#endif // MatrixImageProvider_H
|
|
@ -19,11 +19,7 @@ struct roomEventId {
|
|||
class NotificationsManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
NotificationsManager(QObject *parent = nullptr);
|
||||
|
||||
void postNotification(const QString &roomId, const QString &eventId,
|
||||
const QString &roomName, const QString &senderName,
|
||||
const QString &text, const QImage &icon);
|
||||
NotificationsManager(QObject* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void notificationClicked(const QString roomId, const QString eventId);
|
||||
|
@ -31,7 +27,8 @@ class NotificationsManager : public QObject {
|
|||
private:
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
|
||||
QDBusInterface dbus;
|
||||
uint showNotification(const QString summary, const QString text,
|
||||
uint showNotification(const QString summary,
|
||||
const QString text,
|
||||
const QImage image);
|
||||
#endif
|
||||
|
||||
|
@ -43,9 +40,16 @@ class NotificationsManager : public QObject {
|
|||
public slots:
|
||||
void actionInvoked(uint id, QString action);
|
||||
void notificationClosed(uint id, uint reason);
|
||||
|
||||
void postNotification(const QString& roomId,
|
||||
const QString& eventId,
|
||||
const QString& roomName,
|
||||
const QString& senderName,
|
||||
const QString& text,
|
||||
const QImage& icon);
|
||||
};
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
|
||||
QDBusArgument &operator<<(QDBusArgument &arg, const QImage &image);
|
||||
const QDBusArgument &operator>>(const QDBusArgument &arg, QImage &);
|
||||
QDBusArgument& operator<<(QDBusArgument& arg, const QImage& image);
|
||||
const QDBusArgument& operator>>(const QDBusArgument& arg, QImage&);
|
||||
#endif
|
||||
|
|
|
@ -44,33 +44,33 @@ inline QSize getImageSize(const QUrl& imageUrl) {
|
|||
return reader.size();
|
||||
}
|
||||
|
||||
void SpectralRoom::chooseAndUploadFile() {
|
||||
auto localFile = QFileDialog::getOpenFileUrl(Q_NULLPTR, tr("Save File as"));
|
||||
if (!localFile.isEmpty()) {
|
||||
QString txnID = postFile(localFile.fileName(), localFile, false);
|
||||
setHasFileUploading(true);
|
||||
connect(this, &Room::fileTransferCompleted,
|
||||
[=](QString id, QUrl localFile, QUrl mxcUrl) {
|
||||
if (id == txnID) {
|
||||
setFileUploadingProgress(0);
|
||||
setHasFileUploading(false);
|
||||
}
|
||||
});
|
||||
connect(this, &Room::fileTransferFailed, [=](QString id, QString error) {
|
||||
if (id == txnID) {
|
||||
setFileUploadingProgress(0);
|
||||
setHasFileUploading(false);
|
||||
}
|
||||
});
|
||||
connect(
|
||||
this, &Room::fileTransferProgress,
|
||||
[=](QString id, qint64 progress, qint64 total) {
|
||||
if (id == txnID) {
|
||||
qDebug() << "Progress:" << progress << total;
|
||||
setFileUploadingProgress(int(float(progress) / float(total) * 100));
|
||||
}
|
||||
});
|
||||
}
|
||||
void SpectralRoom::uploadFile(const QUrl& url, const QString& body) {
|
||||
if (url.isEmpty())
|
||||
return;
|
||||
|
||||
QString txnID = postFile(body.isEmpty() ? url.fileName() : body, url, false);
|
||||
setHasFileUploading(true);
|
||||
connect(this, &Room::fileTransferCompleted,
|
||||
[=](QString id, QUrl localFile, QUrl mxcUrl) {
|
||||
if (id == txnID) {
|
||||
setFileUploadingProgress(0);
|
||||
setHasFileUploading(false);
|
||||
}
|
||||
});
|
||||
connect(this, &Room::fileTransferFailed, [=](QString id, QString error) {
|
||||
if (id == txnID) {
|
||||
setFileUploadingProgress(0);
|
||||
setHasFileUploading(false);
|
||||
}
|
||||
});
|
||||
connect(
|
||||
this, &Room::fileTransferProgress,
|
||||
[=](QString id, qint64 progress, qint64 total) {
|
||||
if (id == txnID) {
|
||||
qDebug() << "Progress:" << progress << total;
|
||||
setFileUploadingProgress(int(float(progress) / float(total) * 100));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SpectralRoom::acceptInvitation() {
|
||||
|
|
|
@ -254,7 +254,7 @@ class SpectralRoom : public Room {
|
|||
void fileUploadingProgressChanged();
|
||||
|
||||
public slots:
|
||||
void chooseAndUploadFile();
|
||||
void uploadFile(const QUrl& url, const QString& body = "");
|
||||
void acceptInvitation();
|
||||
void forget();
|
||||
void sendTypingNotification(bool isTyping);
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
#include "spectraluser.h"
|
||||
|
||||
QColor SpectralUser::color() {
|
||||
return QColor::fromHslF(hueF(), 0.7, 0.5, 1);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,12 @@ using namespace QMatrixClient;
|
|||
|
||||
class SpectralUser : public User {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor color READ color CONSTANT)
|
||||
public:
|
||||
SpectralUser(QString userId, Connection* connection)
|
||||
: User(userId, connection) {}
|
||||
|
||||
QColor color();
|
||||
};
|
||||
|
||||
#endif // SpectralUser_H
|
||||
|
|
Loading…
Reference in New Issue