~noskcaj/ubuntu/saucy/sflphone/merge-1.2.3-2

« back to all changes in this revision

Viewing changes to kde/src/widgets/HistoryDock.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2012-05-19 21:46:37 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20120519214637-la8rbrford5kj6m3
Tags: 1.1.0-1
* New upstream release 
  - Fixes "FTBFS with libccrtp-dev/2.0.2 from experimental" (Closes: #663282)
* NEW Maintainer: Debian VoIP Team - Thanks Francois for your work.
  - (Closes: #665789: O: sflphone -- SIP and IAX2 compatible VoIP phone)
* Added Build-Depends: libdbus-c++-bin
* Add gcc47-fixes.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
3
 
 *   Author : Emmanuel Lepage Valle <emmanuel.lepage@savoirfairelinux.com >*
4
 
 *                                                                         *
5
 
 *   This program is free software; you can redistribute it and/or modify  *
6
 
 *   it under the terms of the GNU General Public License as published by  *
7
 
 *   the Free Software Foundation; either version 3 of the License, or     *
8
 
 *   (at your option) any later version.                                   *
9
 
 *                                                                         *
10
 
 *   This program is distributed in the hope that it will be useful,       *
11
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 
 *   GNU General Public License for more details.                          *
14
 
 *                                                                         *
15
 
 *   You should have received a copy of the GNU General Public License     *
16
 
 *   along with this program; if not, write to the                         *
17
 
 *   Free Software Foundation, Inc.,                                       *
18
 
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 
 **************************************************************************/
20
 
 
21
 
//Parent
22
 
#include "HistoryDock.h"
23
 
 
24
 
//Qt
25
 
#include <QtCore/QString>
26
 
#include <QtCore/QDate>
27
 
#include <QtGui/QTreeWidget>
28
 
#include <QtGui/QComboBox>
29
 
#include <QtGui/QPushButton>
30
 
#include <QtGui/QLabel>
31
 
#include <QtGui/QTreeWidgetItem>
32
 
#include <QtGui/QCheckBox>
33
 
#include <QtGui/QGridLayout>
34
 
#include <QtGui/QHeaderView>
35
 
 
36
 
//KDE
37
 
#include <KDebug>
38
 
#include <KIcon>
39
 
#include <KLineEdit>
40
 
#include <KDateWidget>
41
 
 
42
 
//SFLPhone
43
 
#include "SFLPhone.h"
44
 
#include "widgets/HistoryTreeItem.h"
45
 
#include "AkonadiBackend.h"
46
 
#include "conf/ConfigurationSkeleton.h"
47
 
 
48
 
//SFLPhone library
49
 
#include "lib/sflphone_const.h"
50
 
 
51
 
///Qt lack official functional sorting algo, so this hack around it
52
 
class QNumericTreeWidgetItem : public QTreeWidgetItem {
53
 
   public:
54
 
      QNumericTreeWidgetItem(QTreeWidget* parent):QTreeWidgetItem(parent),widget(0),weight(-1){}
55
 
      QNumericTreeWidgetItem(QTreeWidgetItem* parent):QTreeWidgetItem(parent),widget(0),weight(-1){}
56
 
      HistoryTreeItem* widget;
57
 
      int weight;
58
 
   private:
59
 
      bool operator<(const QTreeWidgetItem & other) const {
60
 
         int column = treeWidget()->sortColumn();
61
 
         if (dynamic_cast<QNumericTreeWidgetItem*>((QTreeWidgetItem*)&other)) {
62
 
            if (widget !=0 && dynamic_cast<QNumericTreeWidgetItem*>((QTreeWidgetItem*)&other)->widget != 0)
63
 
               return widget->getTimeStamp() < dynamic_cast<QNumericTreeWidgetItem*>((QTreeWidgetItem*)&other)->widget->getTimeStamp();
64
 
            else if (weight > 0 && dynamic_cast<QNumericTreeWidgetItem*>((QTreeWidgetItem*)&other)->weight > 0)
65
 
               return weight > dynamic_cast<QNumericTreeWidgetItem*>((QTreeWidgetItem*)&other)->weight;
66
 
         }
67
 
         return text(column) < other.text(column);
68
 
      }
69
 
};
70
 
 
71
 
///Event filter allowing to write text on the Tree widget to filter it.
72
 
bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
73
 
{
74
 
   if (event->type() == QEvent::KeyPress) {
75
 
      m_pDock->keyPressEvent((QKeyEvent*)event);
76
 
      return true;
77
 
   } else {
78
 
      // standard event processing
79
 
      return QObject::eventFilter(obj, event);
80
 
   }
81
 
}
82
 
 
83
 
///Constructor
84
 
HistoryDock::HistoryDock(QWidget* parent) : QDockWidget(parent)
85
 
{
86
 
   setObjectName("historyDock");
87
 
   setMinimumSize(250,0);
88
 
   setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
89
 
   m_pFilterLE   = new KLineEdit();
90
 
   m_pItemView   = new HistoryTree(this);
91
 
   m_pSortByCBB  = new QComboBox();
92
 
   m_pSortByL    = new QLabel(i18n("Sort by:"));
93
 
   m_pFromL      = new QLabel(i18n("From:"));
94
 
   m_pToL        = new QLabel(i18n("To:"));
95
 
   m_pFromDW     = new KDateWidget();
96
 
   m_pToDW       = new KDateWidget();
97
 
   m_pAllTimeCB  = new QCheckBox(i18n("Display all"));
98
 
   m_pLinkPB     = new QPushButton(this);
99
 
 
100
 
   m_pAllTimeCB->setChecked(ConfigurationSkeleton::displayDataRange());
101
 
   enableDateRange(ConfigurationSkeleton::displayDataRange());
102
 
 
103
 
   m_pSortByL->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Preferred);
104
 
   m_pSortByCBB->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
105
 
   m_pLinkPB->setMaximumSize(20,9999999);
106
 
   m_pLinkPB->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding);
107
 
   m_pLinkPB->setCheckable(true);
108
 
 
109
 
   m_pItemView->headerItem()->setText(0,i18n("Calls")   );
110
 
   m_pItemView->header    ()->setClickable(true          );
111
 
   m_pItemView->header    ()->setSortIndicatorShown(true );
112
 
   m_pItemView->setAlternatingRowColors(true             );
113
 
   m_pItemView->setAcceptDrops( true                     );
114
 
   m_pItemView->setDragEnabled( true                     );
115
 
   KeyPressEater *keyPressEater = new KeyPressEater(this);
116
 
   m_pItemView->installEventFilter(keyPressEater);
117
 
 
118
 
   m_pFilterLE->setPlaceholderText(i18n("Filter"));
119
 
   m_pFilterLE->setClearButtonShown(true);
120
 
 
121
 
   QStringList sortBy;
122
 
   sortBy << "Date" << "Name" << "Popularity" << "Duration";
123
 
   m_pSortByCBB->addItems(sortBy);
124
 
 
125
 
   QWidget* mainWidget = new QWidget(this);
126
 
   setWidget(mainWidget);
127
 
 
128
 
   QGridLayout* mainLayout = new QGridLayout(mainWidget);
129
 
 
130
 
   mainLayout->addWidget(m_pSortByL   ,0,0     );
131
 
   mainLayout->addWidget(m_pSortByCBB ,0,1,1,2 );
132
 
   mainLayout->addWidget(m_pAllTimeCB ,1,0,1,3 );
133
 
   mainLayout->addWidget(m_pLinkPB    ,3,2,3,1 );
134
 
   mainLayout->addWidget(m_pFromL     ,2,0,1,2 );
135
 
   mainLayout->addWidget(m_pFromDW    ,3,0,1,2 );
136
 
   mainLayout->addWidget(m_pToL       ,4,0,1,2 );
137
 
   mainLayout->addWidget(m_pToDW      ,5,0,1,2 );
138
 
   mainLayout->addWidget(m_pItemView  ,6,0,1,3 );
139
 
   mainLayout->addWidget(m_pFilterLE  ,7,0,1,3 );
140
 
 
141
 
   setWindowTitle(i18n("History"));
142
 
 
143
 
   QDate date(2000,1,1);
144
 
   m_pFromDW->setDate(date);
145
 
 
146
 
   reload();
147
 
   m_CurrentFromDate = m_pFromDW->date();
148
 
   m_CurrentToDate   = m_pToDW->date();
149
 
 
150
 
   connect(m_pAllTimeCB,                  SIGNAL(toggled(bool)),            this, SLOT(enableDateRange(bool)       ));
151
 
   connect(m_pFilterLE,                   SIGNAL(textChanged(QString)),     this, SLOT(filter(QString)             ));
152
 
   connect(m_pFromDW  ,                   SIGNAL(changed(QDate)),           this, SLOT(updateLinkedFromDate(QDate) ));
153
 
   connect(m_pToDW    ,                   SIGNAL(changed(QDate)),           this, SLOT(updateLinkedToDate(QDate)   ));
154
 
   connect(m_pSortByCBB,                  SIGNAL(currentIndexChanged(int)), this, SLOT(reload()                    ));
155
 
   connect(AkonadiBackend::getInstance(), SIGNAL(collectionChanged()),      this, SLOT(updateContactInfo()         ));
156
 
}
157
 
 
158
 
///Destructor
159
 
HistoryDock::~HistoryDock()
160
 
{
161
 
}
162
 
 
163
 
 
164
 
/*****************************************************************************
165
 
 *                                                                           *
166
 
 *                                  Getters                                  *
167
 
 *                                                                           *
168
 
 ****************************************************************************/
169
 
 
170
 
///Return the identity of the call caller
171
 
QString HistoryDock::getIdentity(HistoryTreeItem* item)
172
 
{
173
 
   if (item->getName().trimmed().isEmpty())
174
 
      return item->getPhoneNumber();
175
 
   else
176
 
      return item->getName();
177
 
}
178
 
 
179
 
 
180
 
/*****************************************************************************
181
 
 *                                                                           *
182
 
 *                                  Mutator                                  *
183
 
 *                                                                           *
184
 
 ****************************************************************************/
185
 
 
186
 
///Update informations
187
 
void HistoryDock::updateContactInfo()
188
 
{
189
 
   foreach(HistoryTreeItem* hitem, m_History) {
190
 
      hitem->updated();
191
 
   }
192
 
}
193
 
 
194
 
///Reload the history list
195
 
void HistoryDock::reload()
196
 
{
197
 
   m_pItemView->clear();
198
 
   foreach(HistoryTreeItem* hitem, m_History) {
199
 
      delete hitem;
200
 
   }
201
 
   m_History.clear();
202
 
   foreach (Call* call, SFLPhone::app()->model()->getHistory()) {
203
 
      if (!m_pAllTimeCB->isChecked() || (QDateTime(m_pFromDW->date()).toTime_t() < call->getStartTimeStamp().toUInt() && QDateTime(m_pToDW->date().addDays(1)).toTime_t() > call->getStartTimeStamp().toUInt() )) {
204
 
         HistoryTreeItem* callItem = new HistoryTreeItem(m_pItemView);
205
 
         callItem->setCall(call);
206
 
         m_History << callItem;
207
 
      }
208
 
   }
209
 
   switch (m_pSortByCBB->currentIndex()) {
210
 
      case Date:
211
 
         foreach(HistoryTreeItem* hitem, m_History) {
212
 
            QNumericTreeWidgetItem* item = new QNumericTreeWidgetItem(m_pItemView);
213
 
            item->widget = hitem;
214
 
            hitem->setItem(item);
215
 
            m_pItemView->addTopLevelItem(item);
216
 
            m_pItemView->setItemWidget(item,0,hitem);
217
 
         }
218
 
         break;
219
 
      case Name: {
220
 
         QHash<QString,QTreeWidgetItem*> group;
221
 
         foreach(HistoryTreeItem* item, m_History) {
222
 
            if (!group[getIdentity(item)]) {
223
 
               group[getIdentity(item)] = new QTreeWidgetItem(m_pItemView);
224
 
               group[getIdentity(item)]->setText(0,getIdentity(item));
225
 
               m_pItemView->addTopLevelItem(group[getIdentity(item)]);
226
 
            }
227
 
            QNumericTreeWidgetItem* twItem = new QNumericTreeWidgetItem(group[getIdentity(item)]);
228
 
            item->setItem(twItem);
229
 
            twItem->widget = item;
230
 
            m_pItemView->setItemWidget(twItem,0,item);
231
 
         }
232
 
         break;
233
 
      }
234
 
      case Popularity: {
235
 
         QHash<QString,QNumericTreeWidgetItem*> group;
236
 
         foreach(HistoryTreeItem* item, m_History) {
237
 
            if (!group[getIdentity(item)]) {
238
 
               group[getIdentity(item)] = new QNumericTreeWidgetItem(m_pItemView);
239
 
               group[getIdentity(item)]->weight = 0;
240
 
               m_pItemView->addTopLevelItem(group[getIdentity(item)]);
241
 
            }
242
 
            group[getIdentity(item)]->weight++;
243
 
            group[getIdentity(item)]->setText(0,getIdentity(item)+" ("+QString::number(group[getIdentity(item)]->weight)+")");
244
 
            QNumericTreeWidgetItem* twItem = new QNumericTreeWidgetItem(group[getIdentity(item)]);
245
 
            item->setItem(twItem);
246
 
            twItem->widget = item;
247
 
            m_pItemView->setItemWidget(twItem,0,item);
248
 
         }
249
 
         break;
250
 
      }
251
 
      case Duration:
252
 
         foreach(HistoryTreeItem* hitem, m_History) {
253
 
            QNumericTreeWidgetItem* item = new QNumericTreeWidgetItem(m_pItemView);
254
 
            item->weight = hitem->getDuration();
255
 
            hitem->setItem(item);
256
 
            m_pItemView->addTopLevelItem(item);
257
 
            m_pItemView->setItemWidget(item,0,hitem);
258
 
         }
259
 
         break;
260
 
   }
261
 
   m_pItemView->sortItems(0,Qt::AscendingOrder);
262
 
}
263
 
 
264
 
///Enable the ability to set a date range like 1 month to limit history
265
 
void HistoryDock::enableDateRange(bool enable)
266
 
{
267
 
   m_pFromL->setVisible(enable);
268
 
   m_pToL->setVisible(enable);
269
 
   m_pFromDW->setVisible(enable);
270
 
   m_pToDW->setVisible(enable);
271
 
   m_pLinkPB->setVisible(enable);
272
 
 
273
 
   ConfigurationSkeleton::setDisplayDataRange(enable);
274
 
}
275
 
 
276
 
///Filter the history
277
 
void HistoryDock::filter(QString text)
278
 
{
279
 
   foreach(HistoryTreeItem* item, m_History) {
280
 
      bool visible = (item->getName().toLower().indexOf(text) != -1) || (item->getPhoneNumber().toLower().indexOf(text) != -1);
281
 
      item->getItem()-> setHidden(!visible);
282
 
   }
283
 
   m_pItemView->expandAll();
284
 
}
285
 
 
286
 
///When the data range is linked, change the opposite value when editing the first
287
 
void HistoryDock::updateLinkedDate(KDateWidget* item, QDate& prevDate, QDate& newDate)
288
 
{
289
 
   if (m_pLinkPB->isChecked()) {
290
 
      if (prevDate.day() != newDate.day()) {
291
 
         QDate tmp = item->date();
292
 
         tmp = tmp.addDays(newDate.day() - prevDate.day());
293
 
         item->setDate(tmp);
294
 
      }
295
 
      if (prevDate.month() != newDate.month()) {
296
 
         QDate tmp = item->date();
297
 
         tmp = tmp.addMonths(newDate.month() - prevDate.month());
298
 
         item->setDate(tmp);
299
 
      }
300
 
      if (prevDate.year() != newDate.year()) {
301
 
         QDate tmp = item->date();
302
 
         tmp = tmp.addYears(newDate.year() - prevDate.year());
303
 
         item->setDate(tmp);
304
 
      }
305
 
   }
306
 
   prevDate = newDate;
307
 
}
308
 
 
309
 
///The signals have to be disabled to prevent an ifinite loop
310
 
void HistoryDock::updateLinkedFromDate(QDate date)
311
 
{
312
 
   disconnect (m_pToDW  ,  SIGNAL(changed(QDate)),       this, SLOT(updateLinkedToDate(QDate)));
313
 
   updateLinkedDate(m_pToDW,m_CurrentFromDate,date);
314
 
   connect    (m_pToDW  ,  SIGNAL(changed(QDate)),       this, SLOT(updateLinkedToDate(QDate)));
315
 
}
316
 
 
317
 
///The signals have to be disabled to prevent an ifinite loop
318
 
void HistoryDock::updateLinkedToDate(QDate date)
319
 
{
320
 
   disconnect(m_pFromDW  ,  SIGNAL(changed(QDate)),       this, SLOT(updateLinkedFromDate(QDate)));
321
 
   updateLinkedDate(m_pFromDW,m_CurrentToDate,date);
322
 
   connect   (m_pFromDW  ,  SIGNAL(changed(QDate)),       this, SLOT(updateLinkedFromDate(QDate)));
323
 
}
324
 
 
325
 
 
326
 
/*****************************************************************************
327
 
 *                                                                           *
328
 
 *                             Drag and drop                                 *
329
 
 *                                                                           *
330
 
 ****************************************************************************/
331
 
 
332
 
///Generate serializerd version of the content
333
 
QMimeData* HistoryTree::mimeData( const QList<QTreeWidgetItem *> items) const
334
 
{
335
 
   kDebug() << "An history call is being dragged";
336
 
   if (items.size() < 1) {
337
 
      return NULL;
338
 
   }
339
 
 
340
 
   QMimeData *mimeData = new QMimeData();
341
 
 
342
 
   //Contact
343
 
   if (dynamic_cast<QNumericTreeWidgetItem*>(items[0])) {
344
 
      QNumericTreeWidgetItem* item = dynamic_cast<QNumericTreeWidgetItem*>(items[0]);
345
 
      if (item->widget != 0) {
346
 
         mimeData->setData(MIME_PHONENUMBER, item->widget->call()->getPeerPhoneNumber().toUtf8());
347
 
      }
348
 
   }
349
 
   else {
350
 
      kDebug() << "the item is not a call";
351
 
   }
352
 
   return mimeData;
353
 
}
354
 
 
355
 
///Handle what happen when serialized data is dropped
356
 
bool HistoryTree::dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action)
357
 
{
358
 
   Q_UNUSED(index)
359
 
   Q_UNUSED(action)
360
 
   Q_UNUSED(parent)
361
 
 
362
 
   QByteArray encodedData = data->data(MIME_CALLID);
363
 
 
364
 
   kDebug() << "In history import"<< QString(encodedData);
365
 
 
366
 
   return false;
367
 
}
368
 
 
369
 
 
370
 
/*****************************************************************************
371
 
 *                                                                           *
372
 
 *                              Keyboard handling                            *
373
 
 *                                                                           *
374
 
 ****************************************************************************/
375
 
 
376
 
///Handle keyboard input and redirect them to the filterbox
377
 
void HistoryDock::keyPressEvent(QKeyEvent* event) {
378
 
   int key = event->key();
379
 
   if(key == Qt::Key_Escape)
380
 
      m_pFilterLE->setText(QString());
381
 
   else if(key == Qt::Key_Return || key == Qt::Key_Enter) {}
382
 
   else if((key == Qt::Key_Backspace) && (m_pFilterLE->text().size()))
383
 
      m_pFilterLE->setText(m_pFilterLE->text().left( m_pFilterLE->text().size()-1 ));
384
 
   else if (!event->text().isEmpty() && !(key == Qt::Key_Backspace))
385
 
      m_pFilterLE->setText(m_pFilterLE->text()+event->text());
386
 
}
 
 
b'\\ No newline at end of file'