Commit 79ec2c5b authored by Andreas Traczyk's avatar Andreas Traczyk Committed by Ming Rui Zhang

ui: add contact picker widget

- this widget can be used to display a list of contacts for
  selecting a conferencee or transferee

Change-Id: Id65bf294bbf4d0e88721d3924a39b7dff69b0c64
parent bda30001
......@@ -644,6 +644,7 @@ void CallWidget::slotShowCallView(const std::string& accountId,
ui->callStackWidget->setCurrentWidget(ui->videoPage);
ui->videoWidget->showChatviewIfToggled();
hideMiniSpinner();
ui->videoWidget->pushRenderer(convInfo.callId);
}
void CallWidget::slotShowIncomingCallView(const std::string& accountId,
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ContactDialog</class>
<widget class="QDialog" name="ContactDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>398</width>
<height>154</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>New Contact</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nameLineEdit">
<property name="placeholderText">
<string>Enter a name...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="numberLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ContactDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ContactDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
/***************************************************************************
* Copyright (C) 2015-2019 by Savoir-faire Linux *
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
* Author: Andreas Traczyk <andreas.traczyk@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/>. *
**************************************************************************/
#include "contactpicker.h"
#include "ui_contactpicker.h"
#include <QMouseEvent>
#include "contactpickeritemdelegate.h"
ContactPicker::ContactPicker(QWidget *parent) :
QDialog(parent),
ui(new Ui::ContactPicker),
type_(Type::CONFERENCE)
{
ui->setupUi(this);
setWindowFlags(Qt::CustomizeWindowHint);
setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
ui->smartList->setItemDelegate(new ContactPickerItemDelegate());
selectableProxyModel_ = new SelectableProxyModel(smartListModel_.get());
ui->smartList->setModel(selectableProxyModel_);
}
ContactPicker::~ContactPicker()
{
delete ui;
}
void
ContactPicker::on_smartList_clicked(const QModelIndex &index)
{
Q_UNUSED(index);
this->accept();
}
void
ContactPicker::accept()
{
auto idx = ui->smartList->currentIndex();
if (idx.isValid()) {
// get current call id and peer uri
auto selectedConvUid = LRCInstance::getSelectedConvUid();
auto convModel = LRCInstance::getCurrentConversationModel();
auto conversation = Utils::getConversationFromUid(selectedConvUid, *convModel);
auto thisCallId = conversation->callId;
auto contactUri = idx.data(static_cast<int>(SmartListModel::Role::URI)).value<QString>().toStdString();
// let parent deal with this as this dialog will be destroyed
switch (type_) {
case Type::CONFERENCE:
emit contactWillJoinConference(thisCallId, contactUri);
break;
case Type::BLIND_TRANSFER:
case Type::ATTENDED_TRANSFER:
emit contactWillDoBlindTransfer(thisCallId, contactUri);
break;
default:
break;
}
}
QDialog::accept();
}
void
ContactPicker::on_ringContactLineEdit_textChanged(const QString &arg1)
{
selectableProxyModel_->setFilterRegExp(QRegExp(arg1, Qt::CaseInsensitive, QRegExp::FixedString));
}
void
ContactPicker::mousePressEvent(QMouseEvent *event)
{
auto contactPickerWidgetRect = ui->contactPickerWidget->rect();
if (!contactPickerWidgetRect.contains(event->pos())) {
//close();
emit willClose(event);
}
}
void
ContactPicker::setTitle(const std::string& title)
{
ui->title->setText(QString::fromStdString(title));
}
void
ContactPicker::setType(const Type& type)
{
type_ = type;
smartListModel_.reset(new SmartListModel(LRCInstance::getCurrAccId(), this, true));
selectableProxyModel_->setSourceModel(smartListModel_.get());
// adjust filter
switch (type_) {
case Type::CONFERENCE:
selectableProxyModel_->setPredicate(
[this](const QModelIndex& index, const QRegExp& regexp) {
bool match = regexp.indexIn(index.data(Qt::DisplayRole).toString()) != -1;
auto convUid = index.data(static_cast<int>(SmartListModel::Role::UID)).value<QString>().toStdString();
auto convModel = LRCInstance::getCurrentConversationModel();
auto conversation = Utils::getConversationFromUid(convUid, *convModel);
if (conversation == convModel->allFilteredConversations().end()) {
return false;
}
auto callModel = LRCInstance::getCurrentCallModel();
return match &&
!(callModel->hasCall(conversation->callId) || callModel->hasCall(conversation->confId)) &&
!index.parent().isValid();
});
break;
case Type::BLIND_TRANSFER:
case Type::ATTENDED_TRANSFER:
selectableProxyModel_->setPredicate(
[this](const QModelIndex& index, const QRegExp& regexp) {
return true;
});
break;
default:
break;
}
selectableProxyModel_->invalidate();
}
/***************************************************************************
* Copyright (C) 2015-2019 by Savoir-faire Linux *
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
* Author: Andreas Traczyk <andreas.traczyk@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/>. *
**************************************************************************/
#pragma once
#include <QDialog>
#include <QSortFilterProxyModel>
#include "smartlistmodel.h"
#include "utils.h"
#include "lrcinstance.h"
namespace Ui {
class ContactPicker;
}
class SelectableProxyModel : public QSortFilterProxyModel
{
public:
using FilterPredicate = std::function<bool(const QModelIndex&, const QRegExp&)>;
explicit SelectableProxyModel(QAbstractItemModel* parent) : QSortFilterProxyModel(parent) {
setSourceModel(parent);
}
void setPredicate(FilterPredicate filterPredicate) {
filterPredicate_ = filterPredicate;
}
virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const {
// Accept all contacts in conversation list filtered with account type, except those in a call
auto index = sourceModel()->index(source_row, 0, source_parent);
if (filterPredicate_) {
return filterPredicate_(index, filterRegExp());
}
}
private:
std::function<bool(const QModelIndex&, const QRegExp&)> filterPredicate_;
};
class ContactPicker : public QDialog
{
Q_OBJECT;
public:
enum class Type {
CONFERENCE,
BLIND_TRANSFER,
ATTENDED_TRANSFER,
COUNT__
};
explicit ContactPicker(QWidget *parent = 0);
~ContactPicker();
void setTitle(const std::string& title);
void setType(const Type& type);
protected:
void mousePressEvent(QMouseEvent *event);
signals:
void contactWillJoinConference(const std::string& callId, const std::string& contactUri);
void contactWillDoBlindTransfer(const std::string& callId, const std::string& contactUri);
void willClose(QMouseEvent *event);
protected slots:
void accept();
private slots:
void on_smartList_clicked(const QModelIndex &index);
void on_ringContactLineEdit_textChanged(const QString &arg1);
private:
Ui::ContactPicker *ui;
std::unique_ptr<SmartListModel> smartListModel_;
SelectableProxyModel* selectableProxyModel_;
Type type_;
};
This diff is collapsed.
/***************************************************************************
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Andreas Traczyk <andreas.traczyk@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/>. *
**************************************************************************/
#include "contactpickeritemdelegate.h"
#include <QApplication>
#include <QPainter>
#include <QPixmap>
// Client
#include "smartlistmodel.h"
#include "ringthemeutils.h"
#include "utils.h"
#include "lrcinstance.h"
#include "mainwindow.h"
#include <ciso646>
ContactPickerItemDelegate::ContactPickerItemDelegate(QObject* parent)
: QItemDelegate(parent)
{
}
void
ContactPickerItemDelegate::paint(QPainter* painter
, const QStyleOptionViewItem& option
, const QModelIndex& index
) const
{
QStyleOptionViewItem opt(option);
painter->setRenderHint(QPainter::Antialiasing, true);
// Not having focus removes dotted lines around the item
if (opt.state & QStyle::State_HasFocus)
opt.state ^= QStyle::State_HasFocus;
bool selected = false;
if (option.state & QStyle::State_Selected) {
selected = true;
opt.state ^= QStyle::State_Selected;
} else {
highlightMap_[index.row()] = option.state & QStyle::State_MouseOver;
}
QColor presenceBorderColor = Qt::white;
auto rowHighlight = highlightMap_.find(index.row());
if (selected) {
painter->fillRect(option.rect, RingTheme::smartlistSelection_);
presenceBorderColor = RingTheme::smartlistSelection_;
} else if (rowHighlight != highlightMap_.end() && (*rowHighlight).second) {
painter->fillRect(option.rect, RingTheme::smartlistHighlight_);
presenceBorderColor = RingTheme::smartlistHighlight_;
}
QRect &rect = opt.rect;
// Avatar drawing
opt.decorationSize = QSize(sizeImage_, sizeImage_);
opt.decorationPosition = QStyleOptionViewItem::Left;
opt.decorationAlignment = Qt::AlignCenter;
QRect rectAvatar(dx_ + rect.left(), rect.top() + dy_, sizeImage_, sizeImage_);
drawDecoration(painter, opt, rectAvatar,
QPixmap::fromImage(index.data(Qt::DecorationRole).value<QImage>())
.scaled(sizeImage_, sizeImage_, Qt::KeepAspectRatio, Qt::SmoothTransformation));
QFont font(painter->font());
// Presence indicator
if (index.data(static_cast<int>(SmartListModel::Role::Presence)).value<bool>()) {
qreal radius = sizeImage_ / 6;
QPainterPath outerCircle, innerCircle;
QPointF center(rectAvatar.right() - radius + 2, (rectAvatar.bottom() - radius) + 1 + 2);
qreal outerCRadius = radius;
qreal innerCRadius = outerCRadius * 0.75;
outerCircle.addEllipse(center, outerCRadius, outerCRadius);
innerCircle.addEllipse(center, innerCRadius, innerCRadius);
painter->fillPath(outerCircle, presenceBorderColor);
painter->fillPath(innerCircle, RingTheme::presenceGreen_);
}
using namespace lrc::api;
auto type = Utils::toEnum<profile::Type>(
index.data(static_cast<int>(SmartListModel::Role::ContactType)).value<int>()
);
switch (type) {
case profile::Type::RING:
case profile::Type::TEMPORARY:
paintRingContactItem(painter, option, rect, index);
break;
case profile::Type::SIP:
break;
default:
paintRingContactItem(painter, option, rect, index);
break;
}
}
QSize
ContactPickerItemDelegate::sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
Q_UNUSED(option);
Q_UNUSED(index);
return QSize(0, cellHeight_);
}
void
ContactPickerItemDelegate::paintRingContactItem(QPainter* painter,
const QStyleOptionViewItem& option,
const QRect& rect,
const QModelIndex& index) const
{
Q_UNUSED(option);
QFont font(painter->font());
QPen pen(painter->pen());
painter->setPen(pen);
auto scalingRatio = MainWindow::instance().getCurrentScalingRatio();
if (scalingRatio > 1.0) {
font.setPointSize(fontSize_ - 2);
} else {
font.setPointSize(fontSize_);
}
auto leftMargin = dx_ + sizeImage_ + dx_;
auto rightMargin = dx_;
auto topMargin = 4;
auto bottomMargin = 8;
QRect rectName1(rect.left() + leftMargin,
rect.top() + topMargin,
rect.width() - leftMargin * 2,
rect.height() / 2 - 2);
QRect rectName2(rectName1.left(),
rectName1.top() + rectName1.height(),
rectName1.width(),
rectName1.height() - bottomMargin);
QFontMetrics fontMetrics(font);
// The name is displayed at the avatar's right
QString nameStr = index.data(static_cast<int>(SmartListModel::Role::DisplayName)).value<QString>();
if (!nameStr.isNull()) {
font.setItalic(false);
font.setBold(false);
pen.setColor(RingTheme::lightBlack_);
painter->setPen(pen);
painter->setFont(font);
QString elidedNameStr = fontMetrics.elidedText(nameStr, Qt::ElideRight, rectName1.width());
painter->drawText(rectName1, Qt::AlignVCenter | Qt::AlignLeft, elidedNameStr);
}
// Display the ID under the name
QString idStr = index.data(static_cast<int>(SmartListModel::Role::DisplayID)).value<QString>();
if (idStr != nameStr && !idStr.isNull()) {
font.setItalic(false);
font.setBold(false);
pen.setColor(RingTheme::grey_);
painter->setPen(pen);
painter->setFont(font);
idStr = fontMetrics.elidedText(idStr, Qt::ElideRight, rectName2.width());
painter->drawText(rectName2, Qt::AlignVCenter | Qt::AlignLeft, idStr);
}
}
void
ContactPickerItemDelegate::paintSIPContactItem(QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
Q_UNUSED(painter);
Q_UNUSED(option);
Q_UNUSED(index);
}
/***************************************************************************
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Andreas Traczyk <andreas.traczyk@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/>. *
**************************************************************************/
#pragma once
#include <QObject>
#include <QItemDelegate>
class QPainter;
class ContactPickerItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit ContactPickerItemDelegate(QObject* parent = 0);
protected:
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
private:
void paintRingContactItem(QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect, const QModelIndex& index) const;
void paintSIPContactItem(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
constexpr static int sizeImage_ = 48;
constexpr static int cellHeight_ = 60;
constexpr static int dy_ = 6;
constexpr static int dx_ = 12;
constexpr static int fontSize_ = 11;
mutable std::map<int, bool> highlightMap_;
};
......@@ -136,5 +136,6 @@ FORMS += ./aboutdialog.ui \
./videooverlay.ui \
./videoview.ui \
./downloadbar.ui \
./updateconfirmdialog.ui
./updateconfirmdialog.ui \
./contactpicker.ui
RESOURCES += ressources.qrc
......@@ -15,6 +15,7 @@
<file>images/qrcode.png</file>
<file>images/jami.ico</file>
<file>images/jami.png</file>
<file>images/spike.png</file>
<file>images/waiting.gif</file>
<file>images/icons/ic_add_black_18dp_2x.png</file>
<file>images/icons/ic_arrow_back_24px.svg</file>
......
......@@ -230,6 +230,8 @@
<ClCompile Include="banneditemwidget.cpp" />
<ClCompile Include="bannedlistmodel.cpp" />
<ClCompile Include="animationhelpers.cpp" />
<ClCompile Include="contactpicker.cpp" />
<ClCompile Include="contactpickeritemdelegate.cpp" />
<ClCompile Include="currentaccountcombobox.cpp" />
<ClCompile Include="aboutdialog.cpp" />
<ClCompile Include="updatedownloaddialog.cpp" />
......@@ -430,6 +432,14 @@
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='ReleaseCompile|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
</QtMoc>
<QtMoc Include="contactpicker.h">
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='ReleaseCompile|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
</QtMoc>
<QtMoc Include="contactpickeritemdelegate.h">
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='ReleaseCompile|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
</QtMoc>
<ClInclude Include="pixbufmanipulator.h" />
<QtMoc Include="ringbutton.h">
</QtMoc>
......@@ -607,6 +617,7 @@
<SubType>Designer</SubType>
</QtUic>
<QtUic Include="updatedownloaddialog.ui" />
<QtUic Include="contactpicker.ui" />
<QtUic Include="deleteaccountdialog.ui">
<SubType>Designer</SubType>
</QtUic>
......
......@@ -207,6 +207,12 @@
<ClCompile Include="downloadmanager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="contactpicker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="contactpickeritemdelegate.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="aboutdialog.h">
......@@ -356,6 +362,12 @@
<QtMoc Include="runguard.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="contactpicker.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="contactpickeritemdelegate.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
......@@ -638,6 +650,9 @@
<QtUic Include="updatedownloaddialog.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="contactpicker.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
<ItemGroup>
<None Include="images\FontAwesome.otf">
......
......@@ -32,9 +32,10 @@
#include "utils.h"
#include "lrcinstance.h"
SmartListModel::SmartListModel(const std::string& accId, QObject *parent)
SmartListModel::SmartListModel(const std::string& accId, QObject *parent, bool contactList)
: QAbstractItemModel(parent),
accId_(accId)
accId_(accId),
contactList_(contactList)
{
}
......@@ -42,6 +43,10 @@ int SmartListModel::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid()) {
auto& accInfo = LRCInstance::accountModel().getAccountInfo(accId_);
if (contactList_) {
auto filterType = accInfo.profileInfo.type;
return accInfo.conversationModel->getFilteredConversations(filterType).size();
}
return accInfo.conversationModel->allFilteredConversations().size();
}
return 0; // A valid QModelIndex returns 0 as no entry has sub-elements
......@@ -60,7 +65,15 @@ QVariant SmartListModel::data(const QModelIndex &index, int role) const
}
auto& accInfo = LRCInstance::accountModel().getAccountInfo(accId_);
const auto& item = accInfo.conversationModel->filteredConversation(index.row());
lrc::api::conversation::Info item;
if (contactList_) {
auto filterType = accInfo.profileInfo.type;
item = accInfo.conversationModel->getFilteredConversations(filterType).at(index.row());
} else {
item = accInfo.conversationModel->filteredConversation(index.row());
}
if (item.participants.size() > 0) {
try {
switch (role) {
......
......@@ -35,7 +35,6 @@ public:
using ConversationInfo = lrc::api::conversation::Info;
using ContactInfo = lrc::api::contact::Info;
enum Role {