Git commit 451cbc1404dc1461dd39eb86898da65ed2b7cd46 by Emmanuel Lepage Vall= ee. Committed on 30/04/2015 at 22:01. Pushed by lepagevalleeemmanuel into branch 'master'. ux: Fix the bookmarks serialization And make the AutoCompletion widget nicer Refs #71995 M +2 -0 src/CMakeLists.txt M +2 -1 src/actioncollection.cpp M +1 -1 src/conf/dlgaccountsbase.ui A +129 -0 src/delegates/autocompletiondelegate2.cpp [License: LGPL= (v2.1+)] A +33 -0 src/delegates/autocompletiondelegate2.h [License: LGPL (= v2.1+)] M +55 -79 src/klib/bookmarkbackend.cpp M +4 -2 src/klib/bookmarkbackend.h M +1 -1 src/ring.cpp M +2 -2 src/widgets/autocompletion.cpp M +2 -2 src/widgets/autocompletion.h http://commits.kde.org/ring-kde/451cbc1404dc1461dd39eb86898da65ed2b7cd46 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce192c6..12d011e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -153,6 +153,7 @@ SET( delegates/dialpaddelegate.cpp delegates/imdelegate.cpp delegates/autocompletiondelegate.cpp + delegates/autocompletiondelegate2.cpp delegates/ringtonedelegate.cpp delegates/toolbardelegate.cpp delegates/kdepixmapmanipulation.cpp @@ -368,6 +369,7 @@ INSTALL( FILES icons/overlay_left_corner.svg DESTIN= ATION ${DATA_INSTALL_DIR INSTALL( FILES icons/call.svg DESTINATION ${DATA_INSTA= LL_DIR}/ring-kde ) INSTALL( FILES icons/hold.svg DESTINATION ${DATA_INSTA= LL_DIR}/ring-kde ) INSTALL( FILES icons/transfert.svg DESTINATION ${DATA_INSTA= LL_DIR}/ring-kde ) +INSTALL( FILES icons/mailbox.svg DESTINATION ${DATA_INSTA= LL_DIR}/ring-kde ) INSTALL( FILES icons/confBlackWhite.png DESTINATION ${DATA_INSTA= LL_DIR}/ring-kde ) INSTALL( FILES icons/voicemail.png DESTINATION ${DATA_INSTA= LL_DIR}/ring-kde ) INSTALL( FILES icons/presence-icon.png DESTINATION ${DATA_INSTA= LL_DIR}/ring-kde ) diff --git a/src/actioncollection.cpp b/src/actioncollection.cpp index 0f5f560..5ee62c3 100644 --- a/src/actioncollection.cpp +++ b/src/actioncollection.cpp @@ -77,6 +77,7 @@ action_editToolBar(nullptr), action_addPerson(nullptr), a= ction_screen(nullptr), action_mute_capture =3D new ExtendedAction(this); action_mute_playback =3D new ExtendedAction(this); action_hangup =3D new ExtendedAction(this); + action_mailBox =3D new QAction(Ring::app()); = action_transfer->setAltIcon(QStandardPaths::locate(QStandardPaths::Gene= ricDataLocation, "ring-kde/light/transfert.svg" )); action_record ->setAltIcon(QStandardPaths::locate(QStandardPaths::Gene= ricDataLocation, "ring-kde/light/rec_call.svg" )); @@ -89,6 +90,7 @@ action_editToolBar(nullptr), action_addPerson(nullptr), a= ction_screen(nullptr), action_new_call->setIcon(QIcon(QStandardPaths::locate(QStandardPaths::G= enericDataLocation, "ring-kde/call.svg" ))); action_hold->setIcon(QIcon(QStandardPaths::locate(QStandardPaths::Gener= icDataLocation, "ring-kde/hold.svg" ))); action_transfer->setIcon(QIcon(QStandardPaths::locate(QStandardPaths::G= enericDataLocation, "ring-kde/transfert.svg" ))); + action_mailBox->setIcon(QIcon(QStandardPaths::locate(QStandardPaths::Ge= nericDataLocation, "ring-kde/mailbox.svg" ))); = action_transfer->setText ( i18n( "Transfer" ) ); action_record ->setText ( i18n( "Record" ) ); @@ -174,7 +176,6 @@ void ActionCollection::setupAction() { qDebug() << "setupActions"; = - action_mailBox =3D new QAction(Ring::app()); action_accept->setShortcut ( Qt::CTRL + Qt::Key_A ); action_new_call->setShortcut ( Qt::CTRL + Qt::Key_N ); action_hold->setShortcut ( Qt::CTRL + Qt::Key_H ); diff --git a/src/conf/dlgaccountsbase.ui b/src/conf/dlgaccountsbase.ui index e295cd7..25e9acd 100644 --- a/src/conf/dlgaccountsbase.ui +++ b/src/conf/dlgaccountsbase.ui @@ -234,7 +234,7 @@ - 6 + 0 diff --git a/src/delegates/autocompletiondelegate2.cpp b/src/delegates/auto= completiondelegate2.cpp new file mode 100644 index 0000000..f4f9246 --- /dev/null +++ b/src/delegates/autocompletiondelegate2.cpp @@ -0,0 +1,129 @@ +/*************************************************************************= *** + * Copyright (C) 2013-2015 by Savoir-Faire Linux = * + * Author : Emmanuel Lepage Vallee * + * = * + * This library is free software; you can redistribute it and/or = * + * modify it under the terms of the GNU Lesser General Public = * + * License as published by the Free Software Foundation; either = * + * version 2.1 of the License, or (at your option) any later version. = * + * = * + * 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 = * + * Lesser 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 .= * + *************************************************************************= **/ +#include "autocompletiondelegate2.h" + +#include +#include +#include + +#include + +static const int RIGHT_MARGIN =3D 2; + +AutoCompletionDelegate2::AutoCompletionDelegate2() : QStyledItemDelegate() +{ + +} + +void AutoCompletionDelegate2::paint(QPainter* painter, const QStyleOptionV= iewItem& option, const QModelIndex& index) const +{ + //Paint the background + QStyledItemDelegate::paint(painter,option,QModelIndex()); + + //Draw the icon + const QRect pixmapRect(option.rect.x()+2,option.rect.y()+2,option.rect.= height()/2-4,option.rect.height()/2-4); + if (index.data(Qt::DecorationRole).canConvert()) { + const QIcon icn =3D index.data(Qt::DecorationRole).value(); + const QList sizes =3D icn.availableSizes(); + if (sizes.size()) { + const QRect r =3D (sizes[0].height() > pixmapRect.size().height()= ) ? pixmapRect : QRect(0,0,sizes[0].width(),sizes[0].height()); + painter->drawPixmap(r, icn.pixmap(r.size())); + } + } + else if(index.data(Qt::DecorationRole).canConvert()) { + const QPixmap pm =3D index.data(Qt::DecorationRole).value(); + painter->drawPixmap(pm.rect().height() > pixmapRect.height() ? + pixmapRect : QRect(option.rect.x()+2, option.rect.y()+2, pm.rect(= ).width(), pm.rect().height()), pm + ); + } + + //Draw the contact method number + painter->drawText( + QRect(pixmapRect.x()+pixmapRect.width()+2,option.rect.y()+2,option.r= ect.width()-pixmapRect.x()+pixmapRect.width()+2,option.rect.height()/2), + index.data(Qt::DisplayRole).toString() + ); + + //Draw the peer name + painter->save(); + painter->setPen((option.state & QStyle::State_Selected)?Qt::white:QAppl= ication::palette().color(QPalette::Disabled,QPalette::Text)); + painter->drawText( + QRect(pixmapRect.x()+pixmapRect.width()+2,option.rect.y()+2+option.r= ect.height()/2,option.rect.width()-pixmapRect.x()+pixmapRect.width()+2,opti= on.rect.height()/2), + index.data(NumberCompletionModel::Role::PEER_NAME).toString() + ); + painter->restore(); + + const QString tag =3D index.data(Qt::UserRole).toString(); + if (!tag.isEmpty()) { + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setClipRect(option.rect); + static bool init =3D false; + static QFont f; + static QLinearGradient g; + if (!init) { + f =3D painter->font(); + f.setBold(true); + f.setPointSize(f.pointSize()-1); + g =3D QLinearGradient(QPointF(0, 0), QPointF(0, option.rect.heigh= t()-4)); + QColor col =3D QApplication::palette().color(QPalette::Highlight); + col.setAlpha(125); + g.setColorAt(0, col); + col.setAlpha(175); + g.setColorAt(1, col); + init =3D true; + } + static QFontMetrics m(f); + static int height =3D m.height(); + int rectHeight =3D option.rect.height(); + int leftOver =3D (rectHeight-height); + int padding =3D leftOver/2 >=3D 4 ? 2: 0; + int topMargin =3D (leftOver-2*padding)/2; + painter->setFont(f); + const int width =3D m.width(tag); + const int x =3D option.rect.x()+option.rect.width()-width-RIGHT_MARG= IN-rectHeight/2; + painter->setBrush(g); + painter->setPen(Qt::NoPen); + QRect rect(x, + option.rect.y()+topMargin, + width, + height+2*padding); + painter->drawRect(rect); + painter->setClipRect(x-rectHeight/2,option.rect.y(),rectHeight/2,rec= tHeight); + painter->drawEllipse(QRect( + x-(height+2*padding)/2, + option.rect.y()+topMargin, + (height+2*padding), + (height+2*padding))); + painter->setClipRect(x+width,option.rect.y(),option.rect.height(),op= tion.rect.height()); + painter->drawEllipse(QRect( + x+width-(height+2*padding)/2, + option.rect.y()+topMargin, + (height+2*padding), + (height+2*padding))); + painter->setPen(QApplication::palette().base().color()); + painter->setClipping(false); + painter->drawText(rect,Qt::AlignHCenter|Qt::AlignVCenter,tag); + painter->restore(); + } +} + +QSize AutoCompletionDelegate2::sizeHint(const QStyleOptionViewItem& option= , const QModelIndex& index) const +{ + const QSize s =3D QStyledItemDelegate::sizeHint(option, index); + return QSize(s.width(),s.height()*2); +} diff --git a/src/delegates/autocompletiondelegate2.h b/src/delegates/autoco= mpletiondelegate2.h new file mode 100644 index 0000000..c4b5fe5 --- /dev/null +++ b/src/delegates/autocompletiondelegate2.h @@ -0,0 +1,33 @@ +/*************************************************************************= *** + * Copyright (C) 2013-2015 by Savoir-Faire Linux = * + * Author : Emmanuel Lepage Vallee * + * = * + * This library is free software; you can redistribute it and/or = * + * modify it under the terms of the GNU Lesser General Public = * + * License as published by the Free Software Foundation; either = * + * version 2.1 of the License, or (at your option) any later version. = * + * = * + * 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 = * + * Lesser 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 .= * + *************************************************************************= **/ +#ifndef AUTOCOMPLETIONDELEGATE2_H +#define AUTOCOMPLETIONDELEGATE2_H + +#include + +class AutoCompletionDelegate2 : public QStyledItemDelegate +{ + Q_OBJECT +public: + AutoCompletionDelegate2(); + + virtual void paint(QPainter* painter, const QStyleOptionViewItem& optio= n, const QModelIndex& index) const; + virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModel= Index& index) const override; +}; + +#endif diff --git a/src/klib/bookmarkbackend.cpp b/src/klib/bookmarkbackend.cpp index 3a9d4db..38c276c 100644 --- a/src/klib/bookmarkbackend.cpp +++ b/src/klib/bookmarkbackend.cpp @@ -44,15 +44,37 @@ BookmarkBackend::~BookmarkBackend() = } = -bool BookmarkEditor::save(const ContactMethod* item) +bool BookmarkEditor::save(const ContactMethod* number) { - Q_UNUSED(item) +// if (call->backend() !=3D this) +// append(call); + + QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocatio= n) + QLatin1Char('/')+"bookmark.ini"); + if ( file.open(QIODevice::WriteOnly | QIODevice::Text) ) { + QTextStream streamFileOut(&file); + foreach(const ContactMethod* n, m_lNumbers) { + saveHelper(streamFileOut,n); + } + streamFileOut << "\n"; + streamFileOut.flush(); + file.close(); + return true; + } + else + qWarning() << "Unable to save bookmarks"; + return false; } = bool BookmarkEditor::remove(const ContactMethod* item) { Q_UNUSED(item) + + if (m_lNumbers.indexOf(const_cast(item)) !=3D -1) { + m_lNumbers.removeAt(m_lNumbers.indexOf(const_cast(it= em))); + mediator()->removeItem(item); + return save(nullptr); + } return false; } = @@ -65,18 +87,20 @@ bool BookmarkEditor::edit( ContactMethod* item) bool BookmarkEditor::addNew(const ContactMethod* item) { Q_UNUSED(item) - return false; + addExisting(item); + return save(item); } = bool BookmarkEditor::addExisting(const ContactMethod* item) { - Q_UNUSED(item) + m_lNumbers << const_cast(item); + mediator()->addItem(item); return false; } = QVector BookmarkEditor::items() const { - return QVector(); + return m_lNumbers; } = QString BookmarkBackend::name () const @@ -116,8 +140,7 @@ bool BookmarkBackend::load() ContactMethod* n =3D PhoneDirectoryModel::instance()->g= etNumber(uri,c,a); = //Add the number - m_lNumbers << n; - m_pMediator->addItem(n); + editor()->addExisting(n); = //Reset hc.clear(); @@ -144,7 +167,7 @@ bool BookmarkBackend::reload() } = ///Save a single item -void BookmarkBackend::saveHelper(QTextStream& streamFileOut, const Contact= Method* number) +void BookmarkEditor::saveHelper(QTextStream& streamFileOut, const ContactM= ethod* number) { const Account* a =3D number->account(); streamFileOut << QString("%1=3D%2\n").arg(Call::HistoryMapFields::ACCOU= NT_ID ).arg(a?QString(a->id()):"" ); @@ -154,67 +177,33 @@ void BookmarkBackend::saveHelper(QTextStream& streamF= ileOut, const ContactMethod QString(number->contact()->uid()) ); } + streamFileOut << QString('\n'); } = -// bool BookmarkBackend::append(const ContactMethod* number) -// { -// if (!number->isBookmarked()) { -// const_cast(number)->setTracked(true); -// const_cast(number)->setBookmarked(true); -// = -// //TODO support \r and \n\r end of line -// QFile file(QStandardPaths::writableLocation(QStandardPaths::DataL= ocation) + QLatin1Char('/') + "")+"bookmark.ini"; -// if ( file.open(QIODevice::Append | QIODevice::Text) ) { -// QTextStream streamFileOut(&file); -// saveHelper(streamFileOut,number); -// m_lNumbers << const_cast(number); -// streamFileOut << "\n"; -// streamFileOut.flush(); -// file.close(); -// emit newBookmarkAdded(const_cast(number)); -// return true; -// } -// else -// qWarning() << "Unable to save bookmarks"; -// } -// else -// qDebug() << number->uri() << "is already bookmarked"; -// return false; -// } - -/** Rewrite the file from scratch - * @todo Eventually check if it is necessary, it will be faster - */ -// bool BookmarkBackend::save(const ContactMethod* number) -// { -// Q_UNUSED(number) -// // if (call->backend() !=3D this) -// // append(call); -// = -// QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLoca= tion) + QLatin1Char('/') + "")+"bookmark.ini"; -// if ( file.open(QIODevice::WriteOnly | QIODevice::Text) ) { -// QTextStream streamFileOut(&file); -// foreach(const ContactMethod* n, m_lNumbers) { -// saveHelper(streamFileOut,n); -// } -// streamFileOut << "\n"; -// streamFileOut.flush(); -// file.close(); -// return true; -// } -// else -// qWarning() << "Unable to save bookmarks"; -// = -// return false; -// } +bool BookmarkEditor::append(const ContactMethod* number) +{ + if (!number->isBookmarked()) { + const_cast(number)->setTracked(true); + const_cast(number)->setBookmarked(true); = -///Remove a bookmark and rewrite the file -// bool BookmarkBackend::remove(ContactMethod* number) -// { -// m_lNumbers.removeAll(number); -// save(number); -// return true; -// } + //TODO support \r and \n\r end of line + QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLoca= tion) + QLatin1Char('/')+"bookmark.ini"); + if ( file.open(QIODevice::Append | QIODevice::Text) ) { + QTextStream streamFileOut(&file); + saveHelper(streamFileOut,number); + m_lNumbers << const_cast(number); + streamFileOut << "\n"; + streamFileOut.flush(); + file.close(); + return true; + } + else + qWarning() << "Unable to save bookmarks"; + } + else + qDebug() << number->uri() << "is already bookmarked"; + return false; +} = FlagPack BookmarkBackend::supporte= dFeatures() const { @@ -226,19 +215,6 @@ FlagPack Bookm= arkBackend::supportedFeatu CollectionInterface::SupportedFeatures::REMOVE ; } = -///Edit 'item', the implementation may be a GUI or somehting else -// bool BookmarkBackend::edit( ContactMethod* number) -// { -// Q_UNUSED(number) -// return false; -// } -///Add a new item to the backend -// bool BookmarkBackend::addNew( ContactMethod* number) -// { -// Q_UNUSED(number) -// return true; -// } - bool BookmarkBackend::clear() { const int ret =3D KMessageBox::questionYesNo(static_cast= (QApplication::instance())->activeWindow(), i18n("Are you sure you want to = clear history?"), i18n("Clear history")); diff --git a/src/klib/bookmarkbackend.h b/src/klib/bookmarkbackend.h index c112094..ab7d074 100644 --- a/src/klib/bookmarkbackend.h +++ b/src/klib/bookmarkbackend.h @@ -47,8 +47,6 @@ public: virtual FlagPack supportedFeatures() const override; = private: - //Attributes - QList m_lNumbers; CollectionMediator* m_pMediator; = //Helpers @@ -65,9 +63,13 @@ public: virtual bool edit ( ContactMethod* item ) override; virtual bool addNew ( const ContactMethod* item ) override; virtual bool addExisting( const ContactMethod* item ) override; + bool append(const ContactMethod* number); + void saveHelper(QTextStream& streamFileOut, const ContactMethod* number= ); = private: virtual QVector items() const override; + //Attributes + QVector m_lNumbers; }; = template diff --git a/src/ring.cpp b/src/ring.cpp index 7180ac3..0e6ac3d 100644 --- a/src/ring.cpp +++ b/src/ring.cpp @@ -223,8 +223,8 @@ Ring::Ring(QWidget* parent) = addDockWidget( Qt::BottomDockWidgetArea, m_pCentralDW ); = - tabifyDockWidget(m_pBookmarkDW,m_pContactCD ); tabifyDockWidget(m_pBookmarkDW,m_pHistoryDW ); + tabifyDockWidget(m_pBookmarkDW,m_pContactCD ); = //Force the dock widget aspect ratio, doing this is an hack m_pHistoryDW ->setMinimumSize(350,0); diff --git a/src/widgets/autocompletion.cpp b/src/widgets/autocompletion.cpp index 35ad1bd..f09ccbd 100644 --- a/src/widgets/autocompletion.cpp +++ b/src/widgets/autocompletion.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include "klib/kcfg_settings.h" = static const int TOOLBAR_HEIGHT =3D 72; @@ -138,7 +138,7 @@ AutoCompletion::AutoCompletion(QTreeView* parent) : QWi= dget(parent),m_Height(125 eventFilter(nullptr,&r); } setMinimumSize(0,m_Height); - m_pDelegate =3D new AutoCompletionDelegate(); + m_pDelegate =3D new AutoCompletionDelegate2(); m_pView->setItemDelegate(m_pDelegate); selectionChanged(CallModel::instance()->selectionModel()->currentIndex(= )); } diff --git a/src/widgets/autocompletion.h b/src/widgets/autocompletion.h index a0f7f17..e04f629 100644 --- a/src/widgets/autocompletion.h +++ b/src/widgets/autocompletion.h @@ -30,7 +30,7 @@ class QModelIndex; //Ring class Call; class NumberCompletionModel; -class AutoCompletionDelegate; +class AutoCompletionDelegate2; class ContactMethod; = class AutoCompletion : public QWidget { @@ -61,7 +61,7 @@ private: QListView* m_pView; QLabel* m_pLabel; NumberCompletionModel* m_pModel; - AutoCompletionDelegate* m_pDelegate; + AutoCompletionDelegate2* m_pDelegate; = //Helpers bool brightOrDarkBase();