blob: 77377f441fabdb081239d88c5049a92cf34d59f9 [file] [log] [blame]
Alexandre Lision4a7b95e2015-02-20 10:06:43 -05001/************************************************************************************
2 * Copyright (C) 2014-2015 by Savoir-Faire Linux *
3 * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
4 * *
5 * This library is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU Lesser General Public *
7 * License as published by the Free Software Foundation; either *
8 * version 2.1 of the License, or (at your option) any later version. *
9 * *
10 * This library 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 GNU *
13 * Lesser General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU Lesser General Public *
16 * License along with this library; if not, write to the Free Software *
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***********************************************************************************/
19#include "minimalhistorybackend.h"
20
21//Qt
22#include <QtCore/QFile>
Alexandre Lision6e817142015-03-13 11:07:53 -040023#include <QtCore/QDir>
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050024#include <QtCore/QHash>
Alexandre Lision6e817142015-03-13 11:07:53 -040025#include <QtWidgets/QApplication>
26#include <QtCore/QStandardPaths>
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050027
28//Ring
Alexandre Lision6e817142015-03-13 11:07:53 -040029#include <call.h>
30#include <account.h>
31#include <person.h>
32#include <contactmethod.h>
33#include <historymodel.h>
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050034
Alexandre Lision6e817142015-03-13 11:07:53 -040035class MinimalHistoryEditor : public CollectionEditor<Call>
36{
37public:
38 MinimalHistoryEditor(CollectionMediator<Call>* m, MinimalHistoryBackend* parent);
39 virtual bool save ( const Call* item ) override;
40 virtual bool remove ( const Call* item ) override;
41 virtual bool edit ( Call* item ) override;
42 virtual bool addNew ( const Call* item ) override;
43 virtual bool addExisting( const Call* item ) override;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050044
Alexandre Lision6e817142015-03-13 11:07:53 -040045private:
46 virtual QVector<Call*> items() const override;
47
48 //Helpers
49 void saveCall(QTextStream& stream, const Call* call);
50 bool regenFile(const Call* toIgnore);
51
52 //Attributes
53 QVector<Call*> m_lItems;
54 MinimalHistoryBackend* m_pCollection;
55};
56
57MinimalHistoryEditor::MinimalHistoryEditor(CollectionMediator<Call>* m, MinimalHistoryBackend* parent) :
58CollectionEditor<Call>(m),m_pCollection(parent)
59{
60
61}
62
63MinimalHistoryBackend::MinimalHistoryBackend(CollectionMediator<Call>* mediator) :
64CollectionInterface(new MinimalHistoryEditor(mediator,this)),m_pMediator(mediator)
65{
66
67}
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050068
69MinimalHistoryBackend::~MinimalHistoryBackend()
70{
71
72}
73
Alexandre Lision6e817142015-03-13 11:07:53 -040074void MinimalHistoryEditor::saveCall(QTextStream& stream, const Call* call)
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050075{
Alexandre Lision6e817142015-03-13 11:07:53 -040076 const QString direction = (call->direction()==Call::Direction::INCOMING)?
77 Call::HistoryStateName::INCOMING : Call::HistoryStateName::OUTGOING;
78
79 const Account* a = call->account();
80 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::CALLID ).arg(call->historyId() );
81 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::TIMESTAMP_START ).arg(call->startTimeStamp() );
82 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::TIMESTAMP_STOP ).arg(call->stopTimeStamp() );
83 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::ACCOUNT_ID ).arg(a?QString(a->id()):"" );
84 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::DISPLAY_NAME ).arg(call->peerName() );
85 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::PEER_NUMBER ).arg(call->peerContactMethod()->uri() );
86 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::DIRECTION ).arg(direction );
87 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::MISSED ).arg(call->isMissed() );
88 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::RECORDING_PATH ).arg(call->recordingPath() );
89 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::CONTACT_USED ).arg(false );//TODO
90 if (call->peerContactMethod()->contact()) {
91 stream << QString("%1=%2\n").arg(Call::HistoryMapFields::CONTACT_UID ).arg(
92 QString(call->peerContactMethod()->contact()->uid())
93 );
94 }
95 stream << "\n";
96 stream.flush();
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050097}
98
Alexandre Lision6e817142015-03-13 11:07:53 -040099bool MinimalHistoryEditor::regenFile(const Call* toIgnore)
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500100{
Alexandre Lision6e817142015-03-13 11:07:53 -0400101 QDir dir(QString('/'));
102 dir.mkpath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + QString());
103
104 QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') +"history.ini");
105 if ( file.open(QIODevice::WriteOnly | QIODevice::Text) ) {
106 QTextStream stream(&file);
107 for (const Call* c : HistoryModel::instance()->getHistoryCalls()) {
108 if (c != toIgnore)
109 saveCall(stream, c);
110 }
111 file.close();
112 return true;
113 }
114 return false;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500115}
116
Alexandre Lision6e817142015-03-13 11:07:53 -0400117bool MinimalHistoryEditor::save(const Call* call)
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500118{
Alexandre Lision6e817142015-03-13 11:07:53 -0400119 if (call->collection()->editor<Call>() != this)
120 return addNew(call);
121
122 return regenFile(nullptr);
123}
124
125bool MinimalHistoryEditor::remove(const Call* item)
126{
127 return regenFile(item);
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500128}
129
130bool MinimalHistoryEditor::edit( Call* item)
131{
Alexandre Lision6e817142015-03-13 11:07:53 -0400132 Q_UNUSED(item)
133 return false;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500134}
135
Alexandre Lision6e817142015-03-13 11:07:53 -0400136bool MinimalHistoryEditor::addNew(const Call* call)
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500137{
Alexandre Lision6e817142015-03-13 11:07:53 -0400138 QDir dir(QString('/'));
139 dir.mkpath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + QString());
140
141 if ((call->collection() && call->collection()->editor<Call>() == this) || call->historyId().isEmpty()) return false;
142 //TODO support \r and \n\r end of line
143 QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/')+"history.ini");
144
145 if ( file.open(QIODevice::Append | QIODevice::Text) ) {
146 QTextStream streamFileOut(&file);
147 saveCall(streamFileOut, call);
148 file.close();
149
150 const_cast<Call*>(call)->setCollection(m_pCollection);
151 addExisting(call);
152 return true;
153 }
154 else
155 qWarning() << "Unable to save history";
156 return false;
157}
158
159bool MinimalHistoryEditor::addExisting(const Call* item)
160{
161 m_lItems << const_cast<Call*>(item);
162 mediator()->addItem(item);
163 return true;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500164}
165
166QVector<Call*> MinimalHistoryEditor::items() const
167{
Alexandre Lision6e817142015-03-13 11:07:53 -0400168 return m_lItems;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500169}
170
171QString MinimalHistoryBackend::name () const
172{
Alexandre Lision6e817142015-03-13 11:07:53 -0400173 return QObject::tr("Minimal history backend");
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500174}
175
176QString MinimalHistoryBackend::category () const
177{
Alexandre Lision6e817142015-03-13 11:07:53 -0400178 return QObject::tr("History");
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500179}
180
181QVariant MinimalHistoryBackend::icon() const
182{
Alexandre Lision6e817142015-03-13 11:07:53 -0400183 return QVariant();
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500184}
185
186bool MinimalHistoryBackend::isEnabled() const
187{
Alexandre Lision6e817142015-03-13 11:07:53 -0400188 return true;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500189}
190
191bool MinimalHistoryBackend::load()
192{
Alexandre Lision6e817142015-03-13 11:07:53 -0400193 QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') +"history.ini");
194 if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) {
195 QMap<QString,QString> hc;
196 while (!file.atEnd()) {
197 QByteArray line = file.readLine().trimmed();
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500198
Alexandre Lision6e817142015-03-13 11:07:53 -0400199 //The item is complete
200 if ((line.isEmpty() || !line.size()) && hc.size()) {
201 Call* pastCall = Call::buildHistoryCall(hc);
202 if (pastCall->peerName().isEmpty()) {
203 pastCall->setPeerName(QObject::tr("Unknown"));
204 }
205 pastCall->setRecordingPath(hc[ Call::HistoryMapFields::RECORDING_PATH ]);
206 pastCall->setCollection(this);
207
208 editor<Call>()->addExisting(pastCall);
209 hc.clear();
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500210 }
Alexandre Lision6e817142015-03-13 11:07:53 -0400211 // Add to the current set
212 else {
213 const int idx = line.indexOf("=");
214 if (idx >= 0)
215 hc[line.left(idx)] = line.right(line.size()-idx-1);
216 }
217 }
218 return true;
219 }
220 else
221 qWarning() << "History doesn't exist or is not readable";
222 return false;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500223}
224
225bool MinimalHistoryBackend::reload()
226{
Alexandre Lision6e817142015-03-13 11:07:53 -0400227 return false;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500228}
229
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500230CollectionInterface::SupportedFeatures MinimalHistoryBackend::supportedFeatures() const
231{
Alexandre Lision6e817142015-03-13 11:07:53 -0400232 return (CollectionInterface::SupportedFeatures) (
233 CollectionInterface::SupportedFeatures::NONE |
234 CollectionInterface::SupportedFeatures::LOAD |
235 CollectionInterface::SupportedFeatures::CLEAR |
236 CollectionInterface::SupportedFeatures::REMOVE|
237 CollectionInterface::SupportedFeatures::ADD );
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500238}
239
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500240bool MinimalHistoryBackend::clear()
241{
Alexandre Lision6e817142015-03-13 11:07:53 -0400242 /* TODO: insert confirm dialog? */
243 QFile::remove(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + "history.ini");
244 return true;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500245}
246
247QByteArray MinimalHistoryBackend::id() const
248{
Alexandre Lision6e817142015-03-13 11:07:53 -0400249 return "mhb";
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500250}