Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linphone-desktop
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
linphone-desktop
Commits
05b99bf1
Commit
05b99bf1
authored
Dec 21, 2016
by
Ronan Abhamon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(app): smart search can display contacts & unregistered contacts (unstable)
parent
bed7cddf
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
259 additions
and
45 deletions
+259
-45
CMakeLists.txt
tests/CMakeLists.txt
+3
-1
App.cpp
tests/src/app/App.cpp
+7
-2
ContactsListProxyModel.cpp
tests/src/components/contacts/ContactsListProxyModel.cpp
+1
-6
ContactsListProxyModel.hpp
tests/src/components/contacts/ContactsListProxyModel.hpp
+1
-1
UnregisteredSipAddressesModel.cpp
...omponents/sip-addresses/UnregisteredSipAddressesModel.cpp
+1
-1
UnregisteredSipAddressesProxyModel.cpp
...ents/sip-addresses/UnregisteredSipAddressesProxyModel.cpp
+54
-0
UnregisteredSipAddressesProxyModel.hpp
...ents/sip-addresses/UnregisteredSipAddressesProxyModel.hpp
+19
-0
SmartSearchBarModel.cpp
...s/src/components/smart-search-bar/SmartSearchBarModel.cpp
+31
-0
SmartSearchBarModel.hpp
...s/src/components/smart-search-bar/SmartSearchBarModel.hpp
+29
-0
utils.hpp
tests/src/utils.hpp
+1
-1
DropDownDynamicMenu.qml
tests/ui/modules/Common/Popup/DropDownDynamicMenu.qml
+3
-6
SearchBox.qml
tests/ui/modules/Common/SearchBox.qml
+9
-13
SmartSearchBar.qml
tests/ui/modules/Linphone/SmartSearchBar.qml
+99
-12
MainWindow.qml
tests/ui/views/App/MainWindow/MainWindow.qml
+1
-2
No files found.
tests/CMakeLists.txt
View file @
05b99bf1
...
...
@@ -68,7 +68,8 @@ set(SOURCES
src/components/settings/SettingsModel.cpp
src/components/sip-addresses/SipAddressesModel.cpp
src/components/sip-addresses/UnregisteredSipAddressesModel.cpp
src/components/sip-addresses/UnregisteredSipAddressesProxyModel.hpp
src/components/sip-addresses/UnregisteredSipAddressesProxyModel.cpp
src/components/smart-search-bar/SmartSearchBarModel.cpp
src/components/timeline/TimelineModel.cpp
src/main.cpp
)
...
...
@@ -94,6 +95,7 @@ set(HEADERS
src/components/sip-addresses/SipAddressesModel.hpp
src/components/sip-addresses/UnregisteredSipAddressesModel.hpp
src/components/sip-addresses/UnregisteredSipAddressesProxyModel.hpp
src/components/smart-search-bar/SmartSearchBarModel.hpp
src/components/timeline/TimelineModel.hpp
src/utils.hpp
)
...
...
tests/src/app/App.cpp
View file @
05b99bf1
...
...
@@ -6,14 +6,13 @@
#include "../components/camera/Camera.hpp"
#include "../components/chat/ChatProxyModel.hpp"
#include "../components/contacts/ContactsListModel.hpp"
#include "../components/contacts/ContactsListProxyModel.hpp"
#include "../components/core/CoreManager.hpp"
#include "../components/notifier/Notifier.hpp"
#include "../components/settings/AccountSettingsModel.hpp"
#include "../components/sip-addresses/SipAddressesModel.hpp"
#include "../components/sip-addresses/UnregisteredSipAddressesProxyModel.hpp"
#include "../components/timeline/TimelineModel.hpp"
#include "../components/smart-search-bar/SmartSearchBarModel.hpp"
#include "App.hpp"
...
...
@@ -140,6 +139,12 @@ void App::registerTypes () {
}
);
qmlRegisterSingletonType
<
SmartSearchBarModel
>
(
"Linphone"
,
1
,
0
,
"SmartSearchBarModel"
,
[](
QQmlEngine
*
,
QJSEngine
*
)
->
QObject
*
{
return
new
SmartSearchBarModel
();
}
);
qmlRegisterType
<
Camera
>
(
"Linphone"
,
1
,
0
,
"Camera"
);
qmlRegisterType
<
ContactsListProxyModel
>
(
"Linphone"
,
1
,
0
,
"ContactsListProxyModel"
);
qmlRegisterType
<
ChatModel
>
(
"Linphone"
,
1
,
0
,
"ChatModel"
);
...
...
tests/src/components/contacts/ContactsListProxyModel.cpp
View file @
05b99bf1
...
...
@@ -35,7 +35,6 @@ ContactsListProxyModel::ContactsListProxyModel (QObject *parent) : QSortFilterPr
m_list
=
CoreManager
::
getInstance
()
->
getContactsListModel
();
setSourceModel
(
m_list
);
setFilterCaseSensitivity
(
Qt
::
CaseInsensitive
);
setDynamicSortFilter
(
false
);
for
(
const
ContactModel
*
contact
:
m_list
->
m_list
)
...
...
@@ -88,12 +87,8 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float
if
((
offset
=
tmp_offset
)
==
0
)
break
;
}
// No weight.
if
(
offset
==
-
1
)
return
0
;
// Weight & offset.
switch
(
offset
)
{
case
-
1
:
return
0
;
case
0
:
return
percentage
*
FACTOR_POS_0
;
case
1
:
return
percentage
*
FACTOR_POS_1
;
case
2
:
return
percentage
*
FACTOR_POS_2
;
...
...
tests/src/components/contacts/ContactsListProxyModel.hpp
View file @
05b99bf1
...
...
@@ -25,7 +25,7 @@ public:
public
slots
:
void
setFilter
(
const
QString
&
pattern
)
{
setFilterFixedString
(
pattern
);
invalidate
Filter
();
invalidate
();
}
protected:
...
...
tests/src/components/sip-addresses/UnregisteredSipAddressesModel.cpp
View file @
05b99bf1
...
...
@@ -10,5 +10,5 @@ UnregisteredSipAddressesModel::UnregisteredSipAddressesModel (QObject *parent) :
bool
UnregisteredSipAddressesModel
::
filterAcceptsRow
(
int
source_row
,
const
QModelIndex
&
source_parent
)
const
{
QModelIndex
index
=
sourceModel
()
->
index
(
source_row
,
0
,
source_parent
);
return
index
.
data
().
toMap
().
contains
(
"contact"
);
return
!
index
.
data
().
toMap
().
contains
(
"contact"
);
}
tests/src/components/sip-addresses/UnregisteredSipAddressesProxyModel.cpp
View file @
05b99bf1
#include "../core/CoreManager.hpp"
#include "UnregisteredSipAddressesProxyModel.hpp"
#define WEIGHT_POS_0 5
#define WEIGHT_POS_1 4
#define WEIGHT_POS_2 3
#define WEIGHT_POS_3 2
#define WEIGHT_POS_OTHER 1
// =============================================================================
const
QRegExp
UnregisteredSipAddressesProxyModel
::
m_search_separators
(
"^[^_.-;@ ][_.-;@ ]"
);
// -----------------------------------------------------------------------------
UnregisteredSipAddressesProxyModel
::
UnregisteredSipAddressesProxyModel
(
QObject
*
parent
)
:
QSortFilterProxyModel
(
parent
)
{
setSourceModel
(
CoreManager
::
getInstance
()
->
getUnregisteredSipAddressesModel
());
setDynamicSortFilter
(
false
);
sort
(
0
);
}
bool
UnregisteredSipAddressesProxyModel
::
filterAcceptsRow
(
int
source_row
,
const
QModelIndex
&
source_parent
)
const
{
QModelIndex
index
=
sourceModel
()
->
index
(
source_row
,
0
,
source_parent
);
return
computeStringWeight
(
index
.
data
().
toMap
()[
"sipAddress"
].
toString
())
>
0
;
}
bool
UnregisteredSipAddressesProxyModel
::
lessThan
(
const
QModelIndex
&
left
,
const
QModelIndex
&
right
)
const
{
return
computeStringWeight
(
sourceModel
()
->
data
(
left
).
toMap
()[
"sipAddress"
].
toString
()
)
>
computeStringWeight
(
sourceModel
()
->
data
(
right
).
toMap
()[
"sipAddress"
].
toString
()
);
}
int
UnregisteredSipAddressesProxyModel
::
computeStringWeight
(
const
QString
&
string
)
const
{
int
index
=
-
1
;
int
offset
=
-
1
;
while
((
index
=
filterRegExp
().
indexIn
(
string
,
index
+
1
))
!=
-
1
)
{
int
tmp_offset
=
index
-
string
.
lastIndexOf
(
m_search_separators
,
index
)
-
1
;
if
((
tmp_offset
!=
-
1
&&
tmp_offset
<
offset
)
||
offset
==
-
1
)
if
((
offset
=
tmp_offset
)
==
0
)
break
;
}
switch
(
offset
)
{
case
-
1
:
return
0
;
case
0
:
return
WEIGHT_POS_0
;
case
1
:
return
WEIGHT_POS_1
;
case
2
:
return
WEIGHT_POS_2
;
case
3
:
return
WEIGHT_POS_3
;
default:
break
;
}
return
WEIGHT_POS_OTHER
;
}
tests/src/components/sip-addresses/UnregisteredSipAddressesProxyModel.hpp
View file @
05b99bf1
...
...
@@ -7,6 +7,25 @@
class
UnregisteredSipAddressesProxyModel
:
public
QSortFilterProxyModel
{
Q_OBJECT
;
public:
UnregisteredSipAddressesProxyModel
(
QObject
*
parent
=
Q_NULLPTR
);
~
UnregisteredSipAddressesProxyModel
()
=
default
;
public
slots
:
void
setFilter
(
const
QString
&
pattern
)
{
setFilterFixedString
(
pattern
);
invalidate
();
}
protected:
bool
filterAcceptsRow
(
int
source_row
,
const
QModelIndex
&
source_parent
)
const
override
;
bool
lessThan
(
const
QModelIndex
&
left
,
const
QModelIndex
&
right
)
const
override
;
private:
int
computeStringWeight
(
const
QString
&
string
)
const
;
static
const
QRegExp
m_search_separators
;
};
#endif // UNREGISTERED_SIP_ADDRESSES_PROXY_MODEL_H_
tests/src/components/smart-search-bar/SmartSearchBarModel.cpp
0 → 100644
View file @
05b99bf1
#include "SmartSearchBarModel.hpp"
// =============================================================================
int
SmartSearchBarModel
::
rowCount
(
const
QModelIndex
&
)
const
{
return
m_contacts
.
rowCount
()
+
m_sip_addresses
.
rowCount
();
}
QHash
<
int
,
QByteArray
>
SmartSearchBarModel
::
roleNames
()
const
{
QHash
<
int
,
QByteArray
>
roles
;
roles
[
Qt
::
DisplayRole
]
=
"$entry"
;
return
roles
;
}
QVariant
SmartSearchBarModel
::
data
(
const
QModelIndex
&
index
,
int
role
)
const
{
int
row
=
index
.
row
();
int
n_contacts
=
m_contacts
.
rowCount
();
int
n_sip_addresses
=
m_sip_addresses
.
rowCount
();
if
(
row
<
0
||
row
>=
n_contacts
+
n_sip_addresses
)
return
QVariant
();
if
(
role
==
Qt
::
DisplayRole
)
{
if
(
row
<
n_contacts
)
return
QVariant
::
fromValue
(
m_contacts
.
data
(
m_contacts
.
index
(
row
,
0
),
role
));
return
QVariant
::
fromValue
(
m_sip_addresses
.
data
(
m_sip_addresses
.
index
(
row
-
n_contacts
,
0
),
role
));
}
return
QVariant
();
}
tests/src/components/smart-search-bar/SmartSearchBarModel.hpp
0 → 100644
View file @
05b99bf1
#ifndef SMART_SEARCH_BAR_MODEL_H_
#define SMART_SEARCH_BAR_MODEL_H_
#include <QAbstractListModel>
#include "../contacts/ContactsListProxyModel.hpp"
#include "../sip-addresses/UnregisteredSipAddressesProxyModel.hpp"
// =============================================================================
class
SmartSearchBarModel
:
public
QAbstractListModel
{
Q_OBJECT
;
public:
SmartSearchBarModel
(
QObject
*
parent
=
Q_NULLPTR
)
:
QAbstractListModel
(
parent
)
{}
~
SmartSearchBarModel
()
=
default
;
int
rowCount
(
const
QModelIndex
&
index
=
QModelIndex
())
const
override
;
QHash
<
int
,
QByteArray
>
roleNames
()
const
override
;
QVariant
data
(
const
QModelIndex
&
index
,
int
role
)
const
override
;
private:
ContactsListProxyModel
m_contacts
;
UnregisteredSipAddressesProxyModel
m_sip_addresses
;
};
#endif // SMART_SEARCH_BAR_MODEL_H_
tests/src/utils.hpp
View file @
05b99bf1
...
...
@@ -3,7 +3,7 @@
#include <QString>
// ===================================================================
// ===================================================================
==========
namespace
Utils
{
inline
QString
linphoneStringToQString
(
const
std
::
string
&
string
)
{
...
...
tests/ui/modules/Common/Popup/DropDownDynamicMenu.qml
View file @
05b99bf1
import
Utils
1.0
// ===================================================================
// ===================================================================
==========
// Menu which supports `ListView`.
// ===================================================================
// ===================================================================
==========
AbstractDropDownMenu
{
// Can be computed, but for performance usage, it must be given
...
...
@@ -14,10 +14,7 @@ AbstractDropDownMenu {
var
list
=
_content
[
0
]
Utils
.
assert
(
list
!=
null
,
'
No list found.
'
)
Utils
.
assert
(
Utils
.
qmlTypeof
(
list
,
'
QQuickListView
'
),
'
No list view parameter.
'
)
Utils
.
assert
(
Utils
.
qmlTypeof
(
list
,
'
QQuickListView
'
),
'
No list view parameter.
'
)
var
height
=
list
.
count
*
entryHeight
...
...
tests/ui/modules/Common/SearchBox.qml
View file @
05b99bf1
...
...
@@ -4,10 +4,10 @@ import Common 1.0
import
Common
.
Styles
1.0
import
Utils
1.0
// ===================================================================
// ===================================================================
==========
// A reusable search input which display a entries model in a menu.
// Each entry can be filtered with the search input.
// ===================================================================
// ===================================================================
==========
Item
{
id
:
searchBox
...
...
@@ -16,8 +16,7 @@ Item {
property
alias
entryHeight
:
menu
.
entryHeight
property
alias
maxMenuHeight
:
menu
.
maxMenuHeight
// This property must implement `setFilterFixedString` and/or
// `invalidate` functions.
// This property must implement `setFilter` function.
property
alias
model
:
list
.
model
property
alias
placeholderText
:
searchField
.
placeholderText
...
...
@@ -27,7 +26,7 @@ Item {
signal
menuClosed
signal
menuOpened
// -----------------------------------------------------------------
// -----------------------------------------------------------------
----------
function
hideMenu
()
{
if
(
!
_isOpen
)
{
...
...
@@ -47,17 +46,14 @@ Item {
function
_filter
(
text
)
{
Utils
.
assert
(
model
.
setFilter
FixedString
!=
null
,
'
`model.setFilter
FixedString
` must be defined.
'
model
.
setFilter
!=
null
,
'
`model.setFilter` must be defined.
'
)
model
.
setFilterFixedString
(
text
)
if
(
model
.
invalidate
)
{
model
.
invalidate
()
}
model
.
setFilter
(
text
)
}
// -----------------------------------------------------------------
// -----------------------------------------------------------------
----------
implicitHeight
:
searchField
.
height
...
...
@@ -112,7 +108,7 @@ Item {
}
}
// -----------------------------------------------------------------
// -----------------------------------------------------------------
----------
states
:
State
{
name
:
'
opened
'
...
...
tests/ui/modules/Linphone/SmartSearchBar.qml
View file @
05b99bf1
import
QtQuick
2.7
import
QtQuick
.
Layouts
1.3
import
Common
1.0
import
Linphone
1.0
import
LinphoneUtils
1.0
// ===================================================================
// ===================================================================
==========
SearchBox
{
id
:
searchBox
delegate
:
Contact
{
// contact: $contact
delegate
:
Rectangle
{
id
:
searchBoxEntry
width
:
parent
.
width
height
:
searchBox
.
entryHeight
color
:
'
#FFFFFF
'
Rectangle
{
id
:
indicator
anchors.left
:
parent
.
left
color
:
'
transparent
'
height
:
parent
.
height
width
:
5
}
MouseArea
{
id
:
mouseArea
anchors.fill
:
parent
hoverEnabled
:
true
RowLayout
{
anchors
{
fill
:
parent
leftMargin
:
22
rightMargin
:
10
}
spacing
:
15
// ---------------------------------------------------------------------
// Contact or address info
// ---------------------------------------------------------------------
Avatar
{
id
:
avatar
Layout.preferredHeight
:
30
Layout.preferredWidth
:
30
image
:
$entry
.
vcard
&&
$entry
.
vcard
.
avatar
presenceLevel
:
$entry
.
presenceLevel
!=
null
?
$entry
.
presenceLevel
:
-
1
username
:
LinphoneUtils
.
getContactUsername
(
$entry
.
sipAddress
||
$entry
)
}
Text
{
Layout.fillWidth
:
true
color
:
'
#4B5964
'
elide
:
Text
.
ElideRight
font
{
bold
:
true
pointSize
:
9
}
actions
:
[
ActionButton
{
icon
:
'
call
'
onClicked
:
CallsWindow
.
show
()
},
text
:
$entry
.
vcard
?
$entry
.
vcard
.
username
:
$entry
.
sipAddress
}
// ---------------------------------------------------------------------
// Actions
// ---------------------------------------------------------------------
ActionBar
{
iconSize
:
36
ActionButton
{
icon
:
'
video_call
'
onClicked
:
CallsWindow
.
show
()
}
ActionButton
{
icon
:
'
call
'
onClicked
:
CallsWindow
.
show
()
}
ActionButton
{
icon
:
'
chat
'
onClicked
:
window
.
setView
(
'
Conversation
'
,
{
sipAddress
:
$entry
.
sipAddress
||
$entry
.
vcard
.
sipAddresses
[
0
]
// FIXME: Display menu if many addresses.
})
}
}
}
}
// -------------------------------------------------------------------------
states
:
State
{
when
:
mouseArea
.
containsMouse
PropertyChanges
{
color
:
'
#D0D8DE
'
target
:
searchBoxEntry
}
ActionButton
{
icon
:
'
video_call
'
onClicked
:
CallsWindow
.
show
()
PropertyChanges
{
color
:
'
#FF5E00
'
target
:
indicator
}
]
}
}
}
tests/ui/views/App/MainWindow/MainWindow.qml
View file @
05b99bf1
...
...
@@ -89,8 +89,7 @@ ApplicationWindow {
maxMenuHeight
:
MainWindowStyle
.
searchBox
.
maxHeight
placeholderText
:
qsTr
(
'
mainSearchBarPlaceholder
'
)
contactsModel
:
ContactsListProxyModel
{}
othersSipAddresses
:
UnregisteredSipAddressesProxyModel
{}
model
:
SmartSearchBarModel
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment