Commit 3a099cd3 authored by Emmanuel Lepage Vallee's avatar Emmanuel Lepage Vallee
Browse files

[ #13811 ] Use rounded conference

parent 0f09ab56
...@@ -52,6 +52,7 @@ SET( ...@@ -52,6 +52,7 @@ SET(
widgets/BookmarkDock.cpp widgets/BookmarkDock.cpp
widgets/TranslucentButtons.cpp widgets/TranslucentButtons.cpp
widgets/CategoryDrawer.cpp widgets/CategoryDrawer.cpp
widgets/ConferenceBox.cpp
widgets/CategorizedTreeWidget.cpp widgets/CategorizedTreeWidget.cpp
widgets/VideoDock.cpp widgets/VideoDock.cpp
widgets/VideoWidget.cpp widgets/VideoWidget.cpp
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "widgets/CallTreeItem.h" #include "widgets/CallTreeItem.h"
#include "SFLPhone.h" #include "SFLPhone.h"
#include "SFLPhoneAccessibility.h" #include "SFLPhoneAccessibility.h"
#include "widgets/ConferenceBox.h"
///CallTreeItemDelegate: Delegates for CallTreeItem ///CallTreeItemDelegate: Delegates for CallTreeItem
class CallTreeItemDelegate : public QStyledItemDelegate class CallTreeItemDelegate : public QStyledItemDelegate
...@@ -56,6 +57,7 @@ public: ...@@ -56,6 +57,7 @@ public:
CallTreeItemDelegate(CallView* widget) CallTreeItemDelegate(CallView* widget)
: QStyledItemDelegate(widget) : QStyledItemDelegate(widget)
, m_tree(widget) , m_tree(widget)
, m_ConferenceDrawer()
{ {
} }
...@@ -65,13 +67,133 @@ CallTreeItemDelegate(CallView* widget) ...@@ -65,13 +67,133 @@ CallTreeItemDelegate(CallView* widget)
if (item) { if (item) {
CallTreeItem* widget = (CallTreeItem*)m_tree->itemWidget(item,0); CallTreeItem* widget = (CallTreeItem*)m_tree->itemWidget(item,0);
if (widget) if (widget)
sh.rheight() = widget->sizeHint().height()+4; sh.rheight() = widget->sizeHint().height()+11; //Equal top and bottom padding
if (index.parent().isValid() && !index.parent().child(index.row()+1,0).isValid())
sh.rheight() += 15;
} }
return sh; return sh;
} }
QRect fullCategoryRect(const QStyleOptionViewItem& option, const QModelIndex& index) const {
QModelIndex i(index),old(index);
//BEGIN real sizeHint()
//Otherwise it would be called too often (thanks to valgrind)
((CallTreeItemDelegate*)this)->m_SH = QStyledItemDelegate::sizeHint(option, index);
((CallTreeItemDelegate*)this)->m_LeftMargin = m_ConferenceDrawer.leftMargin();
((CallTreeItemDelegate*)this)->m_RightMargin = m_ConferenceDrawer.rightMargin();
if (!index.parent().isValid() && index.child(0,0).isValid()) {
((QSize)m_SH).rheight() += 2 * m_ConferenceDrawer.leftMargin();
} else {
((QSize)m_SH).rheight() += m_ConferenceDrawer.leftMargin();
}
((QSize)m_SH).rwidth() += m_ConferenceDrawer.leftMargin();
//END real sizeHint()
if (i.parent().isValid()) {
i = i.parent();
}
//Avoid repainting the category over and over (optimization)
//note: 0,0,0,0 is actually wrong, but it wont change anything for this use case
if (i != old && old.row()>2)
return QRect(0,0,0,0);
QTreeWidgetItem* item = m_tree->itemFromIndex(i);
QRect r = m_tree->visualItemRect(item);
// adapt width
r.setLeft(m_ConferenceDrawer.leftMargin());
r.setWidth(m_tree->viewport()->width() - m_ConferenceDrawer.leftMargin() - m_ConferenceDrawer.rightMargin());
// adapt height
if (item->isExpanded() && item->childCount() > 0) {
const int childCount = item->childCount();
//There is a massive implact on CPU usage to have massive rect
for (int i =0;i < childCount;i++) {
r.setHeight(r.height() + sizeHint(option,index).height());
}
// qDebug() << "\n\nFINAL SIZE" << r;
}
r.setTop(r.top() + m_ConferenceDrawer.leftMargin());
return r;
}
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
Q_ASSERT(index.isValid());
QStyleOptionViewItem opt(option);
//BEGIN: draw toplevel items
if (!index.parent().isValid() && index.child(0,0).isValid()) {
const QRegion cl = painter->clipRegion();
painter->setClipRect(opt.rect);
opt.rect = fullCategoryRect(option, index);
m_ConferenceDrawer.drawCategory(index, 0, opt, painter);
painter->setClipRegion(cl);
return;
}
if (!index.parent().parent().isValid()) {
opt.rect = fullCategoryRect(option, index);
const QRegion cl = painter->clipRegion();
QRect cr = option.rect;
if (index.column() == 0) {
if (m_tree->layoutDirection() == Qt::LeftToRight) {
cr.setLeft(5);
} else {
cr.setRight(opt.rect.right());
}
}
painter->setClipRect(cr);
if (index.parent().isValid())
m_ConferenceDrawer.drawCategory(index, 0, opt, painter);
painter->setClipRegion(cl);
painter->setRenderHint(QPainter::Antialiasing, false);
}
//END: draw background of category for all other items
int max = 9999;
painter->setClipRect(option.rect);
if (option.state & QStyle::State_Selected) {
QStyleOptionViewItem opt2(option);
opt2.rect.setWidth(opt2.rect.width()-15);
if (index.parent().isValid() && !index.parent().child(index.row()+1,0).isValid()) {
opt2.rect.setHeight(opt2.rect.height()-15);
QStyledItemDelegate::paint(painter,opt2,index);
max = opt2.rect.height();
}
else {
QStyledItemDelegate::paint(painter,index.parent().isValid()?opt2:option,index);
}
}
QTreeWidgetItem* item = m_tree->itemFromIndex(index);
if (item) {
QWidget* widget = m_tree->itemWidget(item,0);
if (widget) {
widget->setMinimumSize((m_tree->viewport()->width() - m_ConferenceDrawer.leftMargin() - m_ConferenceDrawer.rightMargin())-m_ConferenceDrawer.leftMargin(),10);
widget->setMaximumSize((m_tree->viewport()->width() - m_ConferenceDrawer.leftMargin() - m_ConferenceDrawer.rightMargin())-m_ConferenceDrawer.leftMargin(),max);
}
}
if (index.parent().isValid() && !index.parent().child(index.row()+1,0).isValid()) {
m_ConferenceDrawer.drawBoxBottom(index, 0, option, painter);
}
}
private: private:
CallView* m_tree; CallView* m_tree;
ConferenceBox m_ConferenceDrawer;
QSize m_SH;
int m_LeftMargin;
int m_RightMargin;
}; };
...@@ -79,10 +201,12 @@ private: ...@@ -79,10 +201,12 @@ private:
CallView::CallView(QWidget* parent) : QTreeWidget(parent),m_pActiveOverlay(0),m_pCallPendingTransfer(0) CallView::CallView(QWidget* parent) : QTreeWidget(parent),m_pActiveOverlay(0),m_pCallPendingTransfer(0)
{ {
//Widget part //Widget part
setAcceptDrops(true); setAcceptDrops (true );
setDragEnabled(true); setDragEnabled (true );
setAnimated (true); setAnimated (false);
setUniformRowHeights(false); setUniformRowHeights(false);
setRootIsDecorated (false);
setIndentation(15);
CallTreeItemDelegate *delegate = new CallTreeItemDelegate(this); CallTreeItemDelegate *delegate = new CallTreeItemDelegate(this);
setItemDelegate(delegate); setItemDelegate(delegate);
...@@ -142,6 +266,15 @@ CallView::~CallView() ...@@ -142,6 +266,15 @@ CallView::~CallView()
if (m_pActiveOverlay) delete m_pActiveOverlay; if (m_pActiveOverlay) delete m_pActiveOverlay;
} }
///A tree is not a good representation, remove branch and skin everything
void CallView::drawBranches(QPainter* painter, const QRect& rect, const QModelIndex& index) const
{
Q_UNUSED(painter)
Q_UNUSED(rect)
Q_UNUSED(index)
}
/***************************************************************************** /*****************************************************************************
* * * *
......
...@@ -117,6 +117,7 @@ class CallView : public QTreeWidget { ...@@ -117,6 +117,7 @@ class CallView : public QTreeWidget {
virtual void dragMoveEvent ( QDragMoveEvent *e ); virtual void dragMoveEvent ( QDragMoveEvent *e );
virtual void dragLeaveEvent ( QDragLeaveEvent *e ); virtual void dragLeaveEvent ( QDragLeaveEvent *e );
virtual void resizeEvent ( QResizeEvent *e ); virtual void resizeEvent ( QResizeEvent *e );
virtual void drawBranches(QPainter* painter, const QRect& rect, const QModelIndex& index) const;
public slots: public slots:
void destroyCall ( Call* toDestroy); void destroyCall ( Call* toDestroy);
......
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
#include <QtGui/QPushButton> #include <QtGui/QPushButton>
#include <QtGui/QTreeWidgetItem> #include <QtGui/QTreeWidgetItem>
#include <QtGui/QFontMetrics> #include <QtGui/QFontMetrics>
#include <QtGui/QPalette>
#include <QtGui/QBitmap>
//KDE //KDE
#include <KLocale> #include <KLocale>
...@@ -131,11 +133,14 @@ QSize CallTreeItem::sizeHint () const ...@@ -131,11 +133,14 @@ QSize CallTreeItem::sizeHint () const
height += fm.height(); height += fm.height();
} }
} }
else if (m_pItemCall && m_pItemCall->isConference()) {
height = 32;
}
else { else {
height = 32; height = 32;
} }
if (ConfigurationSkeleton::limitMinimumRowHeight() && height < (uint)ConfigurationSkeleton::minimumRowHeight()) { if (ConfigurationSkeleton::limitMinimumRowHeight() && height < (uint)ConfigurationSkeleton::minimumRowHeight() && !(m_pItemCall && m_pItemCall->isConference())) {
height = (uint)ConfigurationSkeleton::minimumRowHeight(); height = (uint)ConfigurationSkeleton::minimumRowHeight();
} }
...@@ -157,6 +162,21 @@ QSize CallTreeItem::sizeHint () const ...@@ -157,6 +162,21 @@ QSize CallTreeItem::sizeHint () const
* * * *
****************************************************************************/ ****************************************************************************/
///Apply rounder mask
QPixmap& CallTreeItem::applyMask(QPixmap& pxm)
{
QRect pxRect = pxm.rect();
QBitmap mask(pxRect.size());
QPainter customPainter(&mask);
customPainter.setRenderHint(QPainter::Antialiasing, true);
customPainter.fillRect(pxRect,"white");
customPainter.setBackground(QColor("black"));
customPainter.setBrush(QColor("black"));
customPainter.drawRoundedRect(pxRect,5,5);
pxm.setMask(mask);
return pxm;
}
///Set the call item ///Set the call item
void CallTreeItem::setCall(Call *call) void CallTreeItem::setCall(Call *call)
{ {
...@@ -168,7 +188,14 @@ void CallTreeItem::setCall(Call *call) ...@@ -168,7 +188,14 @@ void CallTreeItem::setCall(Call *call)
if (m_pItemCall->isConference()) { if (m_pItemCall->isConference()) {
if (!m_Init) { if (!m_Init) {
m_pHistoryPeerL = new QLabel(i18n("Conference"),this); QColor textColor = palette().text().color();
QColor baseColor = palette().base().color().name();
baseColor.setBlue (baseColor.blue() + (textColor.blue() -baseColor.blue()) *0.6);
baseColor.setRed (baseColor.red() + (textColor.red() -baseColor.red()) *0.6);
baseColor.setGreen(baseColor.green()+ (textColor.green()-baseColor.green())*0.6);
m_pHistoryPeerL = new QLabel(i18n("<b>Conference</b>"),this);
m_pHistoryPeerL->setStyleSheet("color:"+baseColor.name());
m_pIconL = new QLabel(" ",this); m_pIconL = new QLabel(" ",this);
QHBoxLayout* mainLayout = new QHBoxLayout(); QHBoxLayout* mainLayout = new QHBoxLayout();
mainLayout->addWidget(m_pIconL); mainLayout->addWidget(m_pIconL);
...@@ -177,7 +204,7 @@ void CallTreeItem::setCall(Call *call) ...@@ -177,7 +204,7 @@ void CallTreeItem::setCall(Call *call)
m_Init = true; m_Init = true;
} }
m_pIconL->setVisible(true); m_pIconL->setVisible(true);
m_pIconL->setStyleSheet("margin-top:"+(height()-32)/2); m_pIconL->setStyleSheet("margin-left:7px;");
m_pHistoryPeerL->setVisible(true); m_pHistoryPeerL->setVisible(true);
return; return;
} }
...@@ -268,7 +295,10 @@ void CallTreeItem::setCall(Call *call) ...@@ -268,7 +295,10 @@ void CallTreeItem::setCall(Call *call)
mainLayout->addLayout(descr); mainLayout->addLayout(descr);
mainLayout->addWidget(m_pElapsedL); mainLayout->addWidget(m_pElapsedL);
setLayout(mainLayout); QVBoxLayout* mainLayout2 = new QVBoxLayout();
mainLayout2->addItem(mainLayout);
mainLayout2->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding));
setLayout(mainLayout2);
connect(m_pItemCall, SIGNAL(changed()), this, SLOT(updated())); connect(m_pItemCall, SIGNAL(changed()), this, SLOT(updated()));
sizeHint(); sizeHint();
...@@ -317,6 +347,7 @@ void CallTreeItem::updated() ...@@ -317,6 +347,7 @@ void CallTreeItem::updated()
if(m_pIconL && state == CALL_STATE_CURRENT && recording) { if(m_pIconL && state == CALL_STATE_CURRENT && recording) {
if (m_pContact && !m_pItemCall->isConference()) { if (m_pContact && !m_pItemCall->isConference()) {
QPixmap pxm = (*m_pContact->getPhoto()).scaled(QSize(m_Height,m_Height)); QPixmap pxm = (*m_pContact->getPhoto()).scaled(QSize(m_Height,m_Height));
applyMask(pxm);
QPainter painter(&pxm); QPainter painter(&pxm);
QPixmap status(ICON_CURRENT_REC); QPixmap status(ICON_CURRENT_REC);
painter.drawPixmap(pxm.width()-status.width(),pxm.height()-status.height(),status); painter.drawPixmap(pxm.width()-status.width(),pxm.height()-status.height(),status);
...@@ -330,6 +361,7 @@ void CallTreeItem::updated() ...@@ -330,6 +361,7 @@ void CallTreeItem::updated()
QString str = QString(callStateIcons[state]); QString str = QString(callStateIcons[state]);
if (m_pContact && !m_pItemCall->isConference() && m_pContact->getPhoto()) { if (m_pContact && !m_pItemCall->isConference() && m_pContact->getPhoto()) {
QPixmap pxm = (*m_pContact->getPhoto()).scaled(QSize(m_Height,m_Height)); QPixmap pxm = (*m_pContact->getPhoto()).scaled(QSize(m_Height,m_Height));
applyMask(pxm);
QPainter painter(&pxm); QPainter painter(&pxm);
QPixmap status(str); QPixmap status(str);
painter.drawPixmap(pxm.width()-status.width(),pxm.height()-status.height(),status); painter.drawPixmap(pxm.width()-status.width(),pxm.height()-status.height(),status);
...@@ -341,7 +373,7 @@ void CallTreeItem::updated() ...@@ -341,7 +373,7 @@ void CallTreeItem::updated()
} }
if (m_pIconL && m_pItemCall->isConference()) { if (m_pIconL && m_pItemCall->isConference()) {
m_pIconL->setPixmap(QPixmap(ICON_CONFERENCE).scaled(QSize(m_Height,m_Height))); m_pIconL->setPixmap(QPixmap(ICON_CONFERENCE).scaled(QSize(24,24)));
} }
bool transfer = state == CALL_STATE_TRANSFER || state == CALL_STATE_TRANSF_HOLD; bool transfer = state == CALL_STATE_TRANSFER || state == CALL_STATE_TRANSF_HOLD;
......
...@@ -32,6 +32,7 @@ class QLabel; ...@@ -32,6 +32,7 @@ class QLabel;
class QPushButton; class QPushButton;
class QMimeData; class QMimeData;
class QTimer; class QTimer;
class QPixmap;
//KDE //KDE
class KIcon; class KIcon;
...@@ -85,6 +86,9 @@ class CallTreeItem : public QWidget ...@@ -85,6 +86,9 @@ class CallTreeItem : public QWidget
TranslucentButtons* m_pBtnConf ; TranslucentButtons* m_pBtnConf ;
TranslucentButtons* m_pBtnTrans; TranslucentButtons* m_pBtnTrans;
//Helper
QPixmap& applyMask(QPixmap& pxm);
protected: protected:
//Reimplementation //Reimplementation
virtual void dragEnterEvent ( QDragEnterEvent *e ); virtual void dragEnterEvent ( QDragEnterEvent *e );
......
/***************************************************************************
* Copyright (C) 2009 by Rafael Fernández López <ereslibre@kde.org> *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License version 2 as published by the Free Software Foundation. *
* *
* This library 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 *
* Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to *
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301, USA. *
**************************************************************************/
// this code is taken from SystemSettings/icons/CategoryDrawer.{h,cpp}
// Rafael agreet to relicense it under LGPLv2 or LGPLv3, just as we need it,
// see: http://lists.kde.org/?l=kwrite-devel&m=133061943317199&w=2
#include "ConferenceBox.h"
#include <QPainter>
#include <QApplication>
#include <QStyleOption>
#include <QModelIndex>
#include <QDebug>
ConferenceBox::ConferenceBox()
{
setLeftMargin ( 7 );
setRightMargin( 7 );
}
void ConferenceBox::drawCategory(const QModelIndex &index,
int sortRole,
const QStyleOption &option,
QPainter *painter) const
{
Q_UNUSED( sortRole )
Q_UNUSED( index )
painter->setRenderHint(QPainter::Antialiasing);
const QRect optRect = option.rect;
const bool leftToRight = painter->layoutDirection() == Qt::LeftToRight;
//BEGIN: decoration gradient
{
QPainterPath path(optRect.bottomLeft());
path.lineTo(QPoint(optRect.topLeft().x(), optRect.topLeft().y() - 3));
const QPointF topLeft(optRect.topLeft());
QRectF arc(topLeft, QSizeF(4, 4));
path.arcTo(arc, 180, -90);
path.lineTo(optRect.topRight());
path.lineTo(optRect.bottomRight());
path.lineTo(optRect.bottomLeft());
QColor window(option.palette.window().color());
const QColor base(option.palette.base().color());
window.setAlphaF(0.7);
QColor window2(window);
window2.setAlphaF(0.2);
QLinearGradient decoGradient1;
if (leftToRight) {
decoGradient1.setStart(optRect.topLeft());
decoGradient1.setFinalStop(optRect.bottomLeft());
} else {
decoGradient1.setStart(optRect.topRight());
decoGradient1.setFinalStop(optRect.bottomRight());
}
decoGradient1.setColorAt(0, window);
decoGradient1.setColorAt(1, Qt::transparent);
QLinearGradient decoGradient2;
if (leftToRight) {
decoGradient2.setStart(optRect.topLeft());
decoGradient2.setFinalStop(optRect.topRight());
} else {
decoGradient2.setStart(optRect.topRight());
decoGradient2.setFinalStop(optRect.topLeft());
}
decoGradient2.setColorAt(0, window2);
decoGradient2.setColorAt(1, Qt::transparent);
painter->fillPath(path, decoGradient1);
painter->fillRect(optRect, decoGradient2);
}
//END: decoration gradient
{
QRect newOptRect(optRect);
if (leftToRight) {
newOptRect.translate(1, 1);
} else {
newOptRect.translate(-1, 1);
}
//BEGIN: inner top left corner
{
painter->save();
painter->setPen(option.palette.base().color());
QRectF arc;
if (leftToRight) {
const QPointF topLeft(newOptRect.topLeft());
arc = QRectF(topLeft, QSizeF(4, 4));
arc.translate(0.5, 0.5);
painter->drawArc(arc, 1440, 1440);
} else {
QPointF topRight(newOptRect.topRight());
topRight.rx() -= 4;
arc = QRectF(topRight, QSizeF(4, 4));
arc.translate(-0.5, 0.5);
painter->drawArc(arc, 0, 1440);
}
painter->restore();
}
//END: inner top left corner
//BEGIN: inner left vertical line
{
QPoint start;
QPoint verticalGradBottom;
if (leftToRight) {
start = newOptRect.topLeft();
verticalGradBottom = newOptRect.topLeft();
} else {
start = newOptRect.topRight();
verticalGradBottom = newOptRect.topRight();
}
start.ry() += 3;
verticalGradBottom.ry() += newOptRect.height() - 3;
QLinearGradient gradient(start, verticalGradBottom);
gradient.setColorAt(0, option.palette.base().color());
gradient.setColorAt(1, Qt::transparent);
painter->fillRect(QRect(start, QSize(1, newOptRect.height() - 3)), gradient);
}
//END: inner left vertical line
//BEGIN: top inner horizontal line
{
QPoint start;
QPoint horizontalGradTop;
if (leftToRight) {
start = newOptRect.topLeft();
horizontalGradTop = newOptRect.topLeft();
start.rx() += 3;
horizontalGradTop.rx() += newOptRect.width() - 3;
} else {
start = newOptRect.topRight();
horizontalGradTop = newOptRect.topRight();
start.rx() -= 3;
horizontalGradTop.rx() -= newOptRect.width() - 3;
}
QLinearGradient gradient(start, horizontalGradTop);
gradient.setColorAt(0, option.palette.base().color());
gradient.setColorAt(1, Qt::transparent);
QSize rectSize;
if (leftToRight) {
rectSize = QSize(newOptRect.width() - 3, 1);
} else {
rectSize = QSize(-newOptRect.width() + 3, 1);
}
painter->fillRect(QRect(start, rectSize), gradient);
}
//END: top inner horizontal line
}
QColor outlineColor = option.palette.text().color();
outlineColor.setAlphaF(0.35);
//BEGIN: top left corner
{
painter->save();
painter->setPen(outlineColor);
QRectF arc;
if (leftToRight) {
const QPointF topLeft(optRect.topLeft());
arc = QRectF(topLeft, QSizeF(4, 4));
arc.translate(0.5, 0.5);
painter->drawArc(arc, 1440, 1440);
} else {