Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-client-windows
Commits
ae95e721
Commit
ae95e721
authored
Jan 02, 2020
by
Ming Rui Zhang
Committed by
Sébastien Blin
Jan 10, 2020
Browse files
qml: add user profile page
Change-Id: If2404505a4b8d45b3d3498ff71b8dbfbebe928c3
parent
f86db31f
Changes
11
Hide whitespace changes
Inline
Side-by-side
jami-qt.pro
View file @
ae95e721
...
@@ -171,7 +171,9 @@ HEADERS += ./src/aboutdialog.h \
...
@@ -171,7 +171,9 @@ HEADERS += ./src/aboutdialog.h \
.
/
src
/
widgethelpers
.
h
\
.
/
src
/
widgethelpers
.
h
\
.
/
src
/
recordwidget
.
h
\
.
/
src
/
recordwidget
.
h
\
.
/
src
/
networkmanager
.
h
\
.
/
src
/
networkmanager
.
h
\
.
/
src
/
connectivitymonitor
.
h
.
/
src
/
connectivitymonitor
.
h
\
.
/
src
/
userprofile
.
h
\
.
/
src
/
qmlclipboardadapter
.
h
SOURCES
+=
.
/
src
/
aboutdialog
.
cpp
\
SOURCES
+=
.
/
src
/
aboutdialog
.
cpp
\
.
/
src
/
banneditemwidget
.
cpp
\
.
/
src
/
banneditemwidget
.
cpp
\
.
/
src
/
conversationsfilterwidget
.
cpp
\
.
/
src
/
conversationsfilterwidget
.
cpp
\
...
@@ -237,7 +239,8 @@ SOURCES += ./src/aboutdialog.cpp \
...
@@ -237,7 +239,8 @@ SOURCES += ./src/aboutdialog.cpp \
.
/
src
/
widgethelpers
.
cpp
\
.
/
src
/
widgethelpers
.
cpp
\
.
/
src
/
recordwidget
.
cpp
\
.
/
src
/
recordwidget
.
cpp
\
.
/
src
/
networkmanager
.
cpp
\
.
/
src
/
networkmanager
.
cpp
\
.
/
src
/
connectivitymonitor
.
cpp
.
/
src
/
connectivitymonitor
.
cpp
\
.
/
src
/
userprofile
.
cpp
FORMS
+=
.
/
src
/
aboutdialog
.
ui
\
FORMS
+=
.
/
src
/
aboutdialog
.
ui
\
.
/
src
/
advancedsipsettingwidget
.
ui
\
.
/
src
/
advancedsipsettingwidget
.
ui
\
.
/
src
/
callwidget
.
ui
\
.
/
src
/
callwidget
.
ui
\
...
...
qml.qrc
View file @
ae95e721
...
@@ -2,5 +2,6 @@
...
@@ -2,5 +2,6 @@
<qresource prefix="/">
<qresource prefix="/">
<file>src/KeyBoardShortcutTable.qml</file>
<file>src/KeyBoardShortcutTable.qml</file>
<file>src/KeyBoardShortcutKey.qml</file>
<file>src/KeyBoardShortcutKey.qml</file>
<file>src/UserProfileCard.qml</file>
</qresource>
</qresource>
</RCC>
</RCC>
src/UserProfileCard.qml
0 → 100644
View file @
ae95e721
import
QtQuick
2.9
import
QtQuick
.
Controls
2.2
import
QtQuick
.
Controls
.
Styles
1.4
import
QtQuick
.
Layouts
1.3
import
MyQClipboard
1.0
/*
* Every QML object can be assigned an id and an objectName that other objects can use to refer to the object.
* The difference between the two is that the id is for referencing the object within QML,
* while the objectName is required for referencing the object from C++
*/
ColumnLayout
{
id
:
mainColumnLayout
property
int
minWidth
:
560
property
int
minHeight
:
600
property
int
textFontSize
:
10
property
string
userImageSource
:
"
qrc:/qtquickplugin/images/template_image.png
"
property
string
qrImageSource
:
"
qrc:/qtquickplugin/images/template_image.png
"
property
string
userNameText
:
"
Text
"
property
string
registeredNameText
:
"
Text
"
property
string
uriText
:
"
Text
"
spacing
:
2
Rectangle
{
id
:
profileRectangle
Layout.alignment
:
Qt
.
AlignCenter
Layout.minimumWidth
:
minWidth
Layout.minimumHeight
:
minHeight
Layout.maximumWidth
:
minWidth
*
2
Layout.maximumHeight
:
minHeight
*
2
color
:
"
white
"
radius
:
30
MouseArea
{
// trick: in future qt version, use popup() instead of open()
// for menu item (will not auto close)
anchors.fill
:
parent
propagateComposedEvents
:
true
onClicked
:
{
if
(
Qt
.
platform
.
os
==
"
windows
"
)
{
registeredNameContextMenu
.
close
()
idContextMenu
.
close
()
}
}
}
QClipboard
{
id
:
clipboard
}
ColumnLayout
{
id
:
profileRectColumnLayout
anchors.fill
:
parent
anchors.centerIn
:
parent
Rectangle
{
id
:
userRectangle
Layout.alignment
:
Qt
.
AlignHCenter
|
Qt
.
AlignVCenter
Layout.minimumWidth
:
500
Layout.minimumHeight
:
200
Layout.maximumHeight
:
1000
Layout.maximumWidth
:
1000
color
:
"
#ffffff
"
RowLayout
{
id
:
userRectRowLayout
anchors.fill
:
parent
Image
{
id
:
userImage
anchors.verticalCenter
:
userRectangle
.
verticalCenter
anchors.left
:
userRectangle
.
left
Layout.fillWidth
:
true
Layout.fillHeight
:
true
Layout.maximumWidth
:
150
Layout.maximumHeight
:
150
fillMode
:
Image
.
PreserveAspectFit
source
:
userImageSource
cache
:
false
}
Text
{
id
:
userName
anchors.verticalCenter
:
userRectangle
.
verticalCenter
anchors.left
:
userImage
.
right
anchors.leftMargin
:
25
Layout.fillWidth
:
true
Layout.fillHeight
:
true
Layout.maximumWidth
:
300
Layout.maximumHeight
:
t_metrics_userName
.
tightBoundingRect
.
height
text
:
userNameText
verticalAlignment
:
Text
.
AlignVCenter
horizontalAlignment
:
Text
.
AlignLeft
wrapMode
:
Text
.
WordWrap
font.pointSize
:
20
elide
:
Text
.
ElideRight
TextMetrics
{
id
:
t_metrics_userName
font
:
userName
.
font
text
:
userName
.
text
}
}
}
}
Rectangle
{
id
:
informationRectangle
anchors.top
:
userRectangle
.
bottom
anchors.topMargin
:
10
Layout.minimumWidth
:
500
Layout.minimumHeight
:
300
Layout.alignment
:
Qt
.
AlignHCenter
|
Qt
.
AlignVCenter
color
:
"
#ffffff
"
Text
{
id
:
inforElement
anchors.left
:
informationRectangle
.
left
anchors.top
:
informationRectangle
.
top
anchors.topMargin
:
30
anchors.leftMargin
:
20
width
:
t_metrics_info
.
tightBoundingRect
.
width
height
:
t_metrics_info
.
tightBoundingRect
.
height
text
:
qsTr
(
"
Information
"
)
font.pointSize
:
textFontSize
TextMetrics
{
id
:
t_metrics_info
font
:
inforElement
.
font
text
:
inforElement
.
text
}
}
ColumnLayout
{
id
:
infoRectColumnLayout
anchors.top
:
informationRectangle
.
top
anchors.topMargin
:
70
anchors.left
:
informationRectangle
.
left
anchors.leftMargin
:
60
Rectangle
{
id
:
subInfoRect
Layout.minimumWidth
:
400
Layout.minimumHeight
:
200
Layout.alignment
:
Qt
.
AlignHCenter
|
Qt
.
AlignVCenter
RowLayout
{
id
:
registerNameRowLayout
Rectangle
{
id
:
registerNameRect
Layout.minimumWidth
:
subInfoRect
.
width
Layout.minimumHeight
:
Math
.
max
(
registeredNameElement
.
height
,
registeredName
.
height
)
Label
{
id
:
registeredNameElement
anchors.left
:
parent
.
left
anchors.verticalCenter
:
parent
.
verticalCenter
text
:
"
Username
"
fontSizeMode
:
Text
.
Fit
font.pointSize
:
textFontSize
minimumPointSize
:
textFontSize
-
2
color
:
"
#828282
"
MouseArea
{
anchors.fill
:
parent
cursorShape
:
Qt
.
IBeamCursor
acceptedButtons
:
Qt
.
NoButton
}
background
:
Rectangle
{
border.width
:
0
}
}
TextArea
{
id
:
registeredName
anchors.left
:
registeredNameElement
.
right
anchors.leftMargin
:
10
text
:
registeredNameText
verticalAlignment
:
Text
.
AlignVCenter
font.pointSize
:
textFontSize
color
:
"
black
"
readOnly
:
true
selectByMouse
:
true
MouseArea
{
anchors.fill
:
parent
propagateComposedEvents
:
true
cursorShape
:
Qt
.
IBeamCursor
acceptedButtons
:
Qt
.
RightButton
onClicked
:
{
if
(
mouse
.
button
===
Qt
.
RightButton
&&
Qt
.
platform
.
os
==
"
windows
"
)
{
// make menu pos at mouse
var
relativeMousePos
=
mapToItem
(
registeredName
,
mouse
.
x
,
mouse
.
y
)
registeredNameContextMenu
.
x
=
relativeMousePos
.
x
registeredNameContextMenu
.
y
=
relativeMousePos
.
y
registeredNameContextMenu
.
open
()
}
}
}
Menu
{
id
:
registeredNameContextMenu
MenuItem
{
id
:
registeredNameItem
text
:
qsTr
(
"
Copy
"
)
background
:
Rectangle
{
id
:
registeredNameContextMenuBackRect
implicitWidth
:
150
implicitHeight
:
30
border.width
:
1
border.color
:
"
black
"
color
:
registeredNameItem
.
down
?
"
#e0e0e0
"
:
"
#fdfdfd
"
MouseArea
{
anchors.fill
:
parent
;
hoverEnabled
:
true
;
onPressed
:
{
registeredNameContextMenuBackRect
.
color
=
"
#c0c0c0
"
;
}
onReleased
:
{
registeredNameContextMenuBackRect
.
color
=
"
#e0e0e0
"
;
clipboard
.
setText
(
registeredName
.
selectedText
);
reset
();}
onEntered
:
{
registeredNameContextMenuBackRect
.
color
=
"
#c7c7c7
"
;
}
onExited
:
{
registeredNameContextMenuBackRect
.
color
=
Qt
.
binding
(
function
()
{
return
registeredNameItem
.
down
?
"
#e0e0e0
"
:
"
#fdfdfd
"
});
}
function
reset
(){
registeredName
.
deselect
()
registeredNameContextMenu
.
close
()
}
}
}
}
background
:
Rectangle
{
implicitWidth
:
150
implicitHeight
:
30
}
}
background
:
Rectangle
{
border.width
:
0
color
:
"
transparent
"
}
}
}
}
RowLayout
{
id
:
idRowLayout
anchors.top
:
registerNameRowLayout
.
bottom
Rectangle
{
id
:
idRect
Layout.minimumWidth
:
subInfoRect
.
width
Layout.minimumHeight
:
Math
.
max
(
idElement
.
height
,
idText
.
height
)
Label
{
id
:
idElement
anchors.left
:
parent
.
left
anchors.leftMargin
:
registeredNameElement
.
width
-
idElement
.
width
anchors.verticalCenter
:
parent
.
verticalCenter
text
:
"
ID
"
fontSizeMode
:
Text
.
Fit
font.pointSize
:
textFontSize
minimumPointSize
:
textFontSize
-
2
color
:
"
#828282
"
MouseArea
{
anchors.fill
:
parent
cursorShape
:
Qt
.
IBeamCursor
acceptedButtons
:
Qt
.
NoButton
}
background
:
Rectangle
{
border.width
:
0
}
}
TextField
{
id
:
idText
anchors.left
:
idElement
.
right
anchors.leftMargin
:
10
text
:
uriText
verticalAlignment
:
Text
.
AlignVCenter
font.pointSize
:
textFontSize
color
:
"
black
"
readOnly
:
true
selectByMouse
:
true
MouseArea
{
anchors.fill
:
parent
propagateComposedEvents
:
true
cursorShape
:
Qt
.
IBeamCursor
acceptedButtons
:
Qt
.
RightButton
onClicked
:
{
if
(
mouse
.
button
===
Qt
.
RightButton
&&
Qt
.
platform
.
os
==
"
windows
"
)
{
// make menu pos at mouse
var
relativeMousePos
=
mapToItem
(
idText
,
mouse
.
x
,
mouse
.
y
)
idContextMenu
.
x
=
relativeMousePos
.
x
idContextMenu
.
y
=
relativeMousePos
.
y
idContextMenu
.
open
()
}
}
}
Menu
{
id
:
idContextMenu
MenuItem
{
id
:
idItem
text
:
qsTr
(
"
Copy
"
)
background
:
Rectangle
{
id
:
idBackRect
implicitWidth
:
150
implicitHeight
:
30
color
:
idItem
.
down
?
"
#e0e0e0
"
:
"
#fdfdfd
"
border.width
:
1
border.color
:
"
black
"
MouseArea
{
anchors.fill
:
parent
;
hoverEnabled
:
true
;
onPressed
:
{
idBackRect
.
color
=
"
#c0c0c0
"
;
}
onReleased
:
{
idBackRect
.
color
=
"
#e0e0e0
"
;
clipboard
.
setText
(
idText
.
selectedText
);
reset
();}
onEntered
:
{
idBackRect
.
color
=
"
#c7c7c7
"
;
}
onExited
:
{
idBackRect
.
color
=
Qt
.
binding
(
function
()
{
return
idItem
.
down
?
"
#e0e0e0
"
:
"
#fdfdfd
"
});
}
function
reset
(){
idText
.
deselect
()
idContextMenu
.
close
()
}
}
}
}
background
:
Rectangle
{
implicitWidth
:
150
implicitHeight
:
30
}
}
background
:
Rectangle
{
border.width
:
0
}
}
}
}
RowLayout
{
id
:
qrRowLayout
anchors.top
:
idRowLayout
.
bottom
anchors.topMargin
:
6
Rectangle
{
id
:
qrRect
Layout.minimumWidth
:
subInfoRect
.
width
Layout.minimumHeight
:
qrElement
.
height
Label
{
id
:
qrElement
anchors.left
:
parent
.
left
anchors.leftMargin
:
registeredNameElement
.
width
-
qrElement
.
width
anchors.verticalCenter
:
parent
.
verticalCenter
text
:
"
QR Code
"
fontSizeMode
:
Text
.
Fit
font.pointSize
:
textFontSize
minimumPointSize
:
textFontSize
-
2
color
:
"
#828282
"
MouseArea
{
anchors.fill
:
parent
cursorShape
:
Qt
.
IBeamCursor
acceptedButtons
:
Qt
.
NoButton
}
background
:
Rectangle
{
border.width
:
0
}
}
Image
{
id
:
qrImage
anchors.left
:
qrElement
.
right
anchors.leftMargin
:
20
fillMode
:
Image
.
PreserveAspectFit
source
:
qrImageSource
sourceSize.width
:
150
sourceSize.height
:
150
cache
:
false
}
}
}
}
}
}
}
}
}
src/callwidget.cpp
View file @
ae95e721
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
#include
"ringthemeutils.h"
#include
"ringthemeutils.h"
#include
"settingskey.h"
#include
"settingskey.h"
#include
"aboutdialog.h"
#include
"aboutdialog.h"
#include
"userprofile.h"
#include
"globalinstances.h"
#include
"globalinstances.h"
...
@@ -415,14 +416,13 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos)
...
@@ -415,14 +416,13 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos)
// separator
// separator
menu
.
addSeparator
();
menu
.
addSeparator
();
// copy number(infohash)
// show user profile
auto
copyNumberAction
=
new
QAction
(
tr
(
"Copy number"
),
this
);
auto
profileShowingAction
=
new
QAction
(
tr
(
"Profile"
),
this
);
menu
.
addAction
(
copyNumberAction
);
menu
.
addAction
(
profileShowingAction
);
connect
(
copyNumberAction
,
&
QAction
::
triggered
,
connect
(
profileShowingAction
,
&
QAction
::
triggered
,
[
contact
]()
{
[
conversation
,
this
]()
{
QApplication
::
clipboard
()
->
setText
(
UserProfile
userProfile
(
conversation
,
qobject_cast
<
MainWindow
*>
(
this
->
parent
()
->
parent
()
->
parent
()));
QString
::
fromStdString
(
contact
.
profileInfo
.
uri
)
userProfile
.
getContainer
()
->
exec
();
);
});
});
}
}
smartListModel_
->
isContextMenuOpen
=
true
;
smartListModel_
->
isContextMenuOpen
=
true
;
...
@@ -430,45 +430,6 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos)
...
@@ -430,45 +430,6 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos)
smartListModel_
->
isContextMenuOpen
=
false
;
smartListModel_
->
isContextMenuOpen
=
false
;
}
}
void
CallWidget
::
setupQRCode
(
QString
ringID
)
{
auto
rcode
=
QRcode_encodeString
(
ringID
.
toStdString
().
c_str
(),
0
,
//Let the version be decided by libqrencode
QR_ECLEVEL_L
,
// Lowest level of error correction
QR_MODE_8
,
// 8-bit data mode
1
);
if
(
not
rcode
)
{
qWarning
()
<<
"Failed to generate QR code: "
<<
strerror
(
errno
);
return
;
}
auto
margin
=
5
;
int
qrwidth
=
rcode
->
width
+
margin
*
2
;
QImage
result
(
QSize
(
qrwidth
,
qrwidth
),
QImage
::
Format_Mono
);
QPainter
painter
;
painter
.
begin
(
&
result
);
painter
.
setClipRect
(
QRect
(
0
,
0
,
qrwidth
,
qrwidth
));
painter
.
setPen
(
QPen
(
Qt
::
black
,
0.1
,
Qt
::
SolidLine
,
Qt
::
FlatCap
,
Qt
::
MiterJoin
));
painter
.
setBrush
(
Qt
::
black
);
painter
.
fillRect
(
QRect
(
0
,
0
,
qrwidth
,
qrwidth
),
Qt
::
white
);
unsigned
char
*
p
;
p
=
rcode
->
data
;
for
(
int
y
=
0
;
y
<
rcode
->
width
;
y
++
)
{
unsigned
char
*
row
=
(
p
+
(
y
*
rcode
->
width
));
for
(
int
x
=
0
;
x
<
rcode
->
width
;
x
++
)
{
if
(
*
(
row
+
x
)
&
0x1
)
{
painter
.
drawRect
(
margin
+
x
,
margin
+
y
,
1
,
1
);
}
}
}
painter
.
end
();
QRcode_free
(
rcode
);
ui
->
qrLabel
->
setPixmap
(
QPixmap
::
fromImage
(
result
.
scaled
(
QSize
(
qrSize_
,
qrSize_
),
Qt
::
KeepAspectRatio
)));
}
void
void
CallWidget
::
on_smartList_clicked
(
const
QModelIndex
&
index
)
CallWidget
::
on_smartList_clicked
(
const
QModelIndex
&
index
)
{
{
...
@@ -864,7 +825,8 @@ CallWidget::setSelectedAccount(const std::string& accountId)
...
@@ -864,7 +825,8 @@ CallWidget::setSelectedAccount(const std::string& accountId)
auto
isRingAccount
=
accountInfo
.
profileInfo
.
type
==
lrc
::
api
::
profile
::
Type
::
RING
;
auto
isRingAccount
=
accountInfo
.
profileInfo
.
type
==
lrc
::
api
::
profile
::
Type
::
RING
;
if
(
isRingAccount
)
{
if
(
isRingAccount
)
{
ui
->
ringIdLabel
->
setText
(
QString
::
fromStdString
(
id
));
ui
->
ringIdLabel
->
setText
(
QString
::
fromStdString
(
id
));
setupQRCode
(
QString
::
fromStdString
(
accountInfo
.
profileInfo
.
uri
));
ui
->
qrLabel
->
setPixmap
(
QPixmap
::
fromImage
(
Utils
::
setupQRCode
(
QString
::
fromStdString
(
accountInfo
.
profileInfo
.
uri
),
5
).
scaled
(
QSize
(
qrSize_
,
qrSize_
),
Qt
::
KeepAspectRatio
)));
}
}
updateSmartList
();
updateSmartList
();
...
...
src/callwidget.h
View file @
ae95e721
...
@@ -110,7 +110,6 @@ private:
...
@@ -110,7 +110,6 @@ private:
void
conversationsButtonClicked
();
void
conversationsButtonClicked
();
void
invitationsButtonClicked
();
void
invitationsButtonClicked
();
void
setupSmartListContextMenu
(
const
QPoint
&
pos
);
void
setupSmartListContextMenu
(
const
QPoint
&
pos
);
void
setupQRCode
(
QString
ringID
);
void
backToWelcomePage
();
void
backToWelcomePage
();
void
selectConversation
(
const
QModelIndex
&
index
);
void
selectConversation
(
const
QModelIndex
&
index
);
...
...
src/main.cpp
View file @
ae95e721
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include
"utils.h"
#include
"utils.h"
#include
"splashscreen.h"
#include
"splashscreen.h"
#include
"aboutdialog.h"
#include
"aboutdialog.h"
#include
"qmlclipboardadapter.h"
#include
<QApplication>
#include
<QApplication>
#include
<QFile>
#include
<QFile>
...
@@ -296,9 +297,12 @@ main(int argc, char* argv[])
...
@@ -296,9 +297,12 @@ main(int argc, char* argv[])
QObject
::
connect
(
&
a
,
&
QApplication
::
aboutToQuit
,
[
&
guard
]
{
exitApp
(
guard
);
});
QObject
::
connect
(
&
a
,
&
QApplication
::
aboutToQuit
,
[
&
guard
]
{
exitApp
(
guard
);
});
// for deployment only
// for deployment and register types
qmlRegisterType
<
QmlClipboardAdapter
>
(
"MyQClipboard"
,
1
,
0
,
"QClipboard"
);
QQmlApplicationEngine
engine
;
QQmlApplicationEngine
engine
;
engine
.
load
(
QUrl
(
QStringLiteral
(
"qrc:/src/KeyBoardShortcutTable.qml"
)));
engine
.
load
(
QUrl
(
QStringLiteral
(
"qrc:/src/KeyBoardShortcutTable.qml"
)));
engine
.
load
(
QUrl
(
QStringLiteral
(
"qrc:/src/UserProfileCard.qml"
)));
auto
ret
=
a
.
exec
();
auto
ret
=
a
.
exec
();
...
...
src/qmlclipboardadapter.h
0 → 100644
View file @
ae95e721
/***************************************************************************
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
//https://ruedigergad.com/2011/08/06/qml-and-clipboard-interaction/
#pragma once
#include
<QApplication>