diff --git a/CMakeLists.txt b/CMakeLists.txt index 788d2e4fc2bd7105bff43574076c6166eec7f011..c619bc2748f9c789132934b174efef4448a054d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,9 +72,7 @@ SET(ringclient_CONTROLLERS SET(ringclient_BACKENDS src/backends/AddressBookBackend.mm - src/backends/MinimalHistoryBackend.mm - src/backends/AddressBookBackend.h - src/backends/MinimalHistoryBackend.h) + src/backends/AddressBookBackend.h) SET(ringclient_VIEWS src/views/CallView.mm diff --git a/src/AudioPrefsVC.mm b/src/AudioPrefsVC.mm index cd18ed062e821b2be25e7640df73342723a10849..124893229ab311bfd18b437d3a323ae9b68a537a 100644 --- a/src/AudioPrefsVC.mm +++ b/src/AudioPrefsVC.mm @@ -30,6 +30,7 @@ #import "AudioPrefsVC.h" #import <audio/settings.h> +#import <media/recordingmodel.h> #import <QUrl> #import <audio/inputdevicemodel.h> #import <audio/outputdevicemodel.h> @@ -65,16 +66,16 @@ [self.inputDeviceList addItemWithTitle: Audio::Settings::instance()->inputDeviceModel()->data(qInputIdx, Qt::DisplayRole).toString().toNSString()]; [self.alwaysRecordingButton setState: - Audio::Settings::instance()->isAlwaysRecording()?NSOnState:NSOffState]; + Media::RecordingModel::instance()->isAlwaysRecording() ? NSOnState:NSOffState]; [self.muteDTMFButton setState: Audio::Settings::instance()->areDTMFMuted()?NSOnState:NSOffState]; - if([[Audio::Settings::instance()->recordPath().toNSURL() absoluteString] isEqualToString:@""]) { + if([[Media::RecordingModel::instance()->recordPath().toNSURL() absoluteString] isEqualToString:@""]) { NSArray * pathComponentArray = [self pathComponentArray]; [recordingsPathControl setPathComponentCells:pathComponentArray]; } else { - [recordingsPathControl setURL:Audio::Settings::instance()->recordPath().toNSURL()]; + [recordingsPathControl setURL:Media::RecordingModel::instance()->recordPath().toNSURL()]; } } @@ -85,13 +86,13 @@ - (IBAction)toggleAlwaysRecording:(NSButton *)sender { - Audio::Settings::instance()->setAlwaysRecording([sender state] == NSOnState); + Media::RecordingModel::instance()->setAlwaysRecording([sender state] == NSOnState); } - (IBAction)pathControlSingleClick:(id)sender { // Select that chosen component of the path. [self.recordingsPathControl setURL:[[self.recordingsPathControl clickedPathComponentCell] URL]]; - Audio::Settings::instance()->setRecordPath(QUrl::fromNSURL(self.recordingsPathControl.URL)); + Media::RecordingModel::instance()->setRecordPath(QUrl::fromNSURL(self.recordingsPathControl.URL)); } - (IBAction)chooseOutput:(id)sender { diff --git a/src/CurrentCallVC.mm b/src/CurrentCallVC.mm index ba9d59f8b586cfa150b7bdc02ea83ffe77a50e59..aa853cbfea684293ff8fd6a9ef51b1495b35f603 100644 --- a/src/CurrentCallVC.mm +++ b/src/CurrentCallVC.mm @@ -464,7 +464,7 @@ } - (IBAction)toggleRecording:(id)sender { - CallModel::instance()->getCall(CallModel::instance()->selectionModel()->currentIndex()) << Call::Action::RECORD; + CallModel::instance()->getCall(CallModel::instance()->selectionModel()->currentIndex()) << Call::Action::RECORD_AUDIO; } - (IBAction)toggleHold:(id)sender { diff --git a/src/HistoryVC.mm b/src/HistoryVC.mm index 4073320b4cda1e2a0d11b2672566766bacce4f94..fbdd78eb57943b3fd001b8dd4d7e28d692098e93 100644 --- a/src/HistoryVC.mm +++ b/src/HistoryVC.mm @@ -34,8 +34,8 @@ #import <callmodel.h> #import <call.h> #import <contactmethod.h> +#import <localhistorycollection.h> -#import "backends/MinimalHistoryBackend.h" #import "QNSTreeController.h" #define COLUMNID_DAY @"DayColumn" // the single column name in our outline view @@ -80,7 +80,7 @@ [historyView setTarget:self]; [historyView setDoubleAction:@selector(placeHistoryCall:)]; - CategorizedHistoryModel::instance()->addCollection<MinimalHistoryBackend>(LoadOptions::FORCE_ENABLED); + CategorizedHistoryModel::instance()->addCollection<LocalHistoryCollection>(LoadOptions::FORCE_ENABLED); } - (void)placeHistoryCall:(id)sender diff --git a/src/backends/MinimalHistoryBackend.h b/src/backends/MinimalHistoryBackend.h deleted file mode 100644 index 3e5f8899ba6c8317e19d6cf3836ae93407c8fc11..0000000000000000000000000000000000000000 --- a/src/backends/MinimalHistoryBackend.h +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************************ - * Copyright (C) 2014-2015 by Savoir-Faire Linux * - * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> * - * * - * 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 Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***********************************************************************************/ -#ifndef MINIMALHISTORYBACKEND_H -#define MINIMALHISTORYBACKEND_H - -#import <collectioninterface.h> - -class Call; - -template<typename T> class CollectionMediator; - -class LIB_EXPORT MinimalHistoryBackend : public CollectionInterface -{ -public: - explicit MinimalHistoryBackend(CollectionMediator<Call>* mediator); - virtual ~MinimalHistoryBackend(); - - virtual bool load() override; - virtual bool reload() override; - virtual bool clear() override; - virtual QString name () const override; - virtual QString category () const override; - virtual QVariant icon () const override; - virtual bool isEnabled() const override; - virtual QByteArray id () const override; - virtual FlagPack<SupportedFeatures> supportedFeatures() const override; - int daysSince(time_t timestamp); - - -private: - CollectionMediator<Call>* m_pMediator; -}; - -#endif diff --git a/src/backends/MinimalHistoryBackend.mm b/src/backends/MinimalHistoryBackend.mm deleted file mode 100644 index 915094ca76e2ac30d8fb3ecde46c50c5ea8adb4a..0000000000000000000000000000000000000000 --- a/src/backends/MinimalHistoryBackend.mm +++ /dev/null @@ -1,292 +0,0 @@ -/************************************************************************************ - * Copyright (C) 2014-2015 by Savoir-Faire Linux * - * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> * - * * - * 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 Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***********************************************************************************/ -#import "minimalhistorybackend.h" - -#import <Cocoa/Cocoa.h> - -//Qt -#import <QtCore/QFile> -#import <QtCore/QDir> -#import <QtCore/qlist.h> -#import <QtCore/QHash> -#import <QtWidgets/QApplication> -#import <QtCore/QStandardPaths> -#import <collectioneditor.h> - -//Ring -#import <call.h> -#import <account.h> -#import <person.h> -#import <contactmethod.h> -#import <categorizedhistorymodel.h> - -#import "../Constants.h" - -class MinimalHistoryEditor : public CollectionEditor<Call> -{ -public: - MinimalHistoryEditor(CollectionMediator<Call>* m, MinimalHistoryBackend* parent); - virtual bool save ( const Call* item ) override; - virtual bool remove ( const Call* item ) override; - virtual bool batchRemove(const QList<Call*> contacts) override; - virtual bool edit ( Call* item ) override; - virtual bool addNew ( const Call* item ) override; - virtual bool addExisting( const Call* item ) override; - -private: - virtual QVector<Call*> items() const override; - - //Helpers - void saveCall(QTextStream& stream, const Call* call); - bool regenFile(const Call* toIgnore); - - //Attributes - QVector<Call*> m_lItems; - MinimalHistoryBackend* m_pCollection; -}; - -MinimalHistoryEditor::MinimalHistoryEditor(CollectionMediator<Call>* m, MinimalHistoryBackend* parent) : -CollectionEditor<Call>(m),m_pCollection(parent) -{ - -} - -MinimalHistoryBackend::MinimalHistoryBackend(CollectionMediator<Call>* mediator) : -CollectionInterface(new MinimalHistoryEditor(mediator,this)),m_pMediator(mediator) -{ - -} - -MinimalHistoryBackend::~MinimalHistoryBackend() -{ - -} - -void MinimalHistoryEditor::saveCall(QTextStream& stream, const Call* call) -{ - const QString direction = (call->direction()==Call::Direction::INCOMING)? - Call::HistoryStateName::INCOMING : Call::HistoryStateName::OUTGOING; - - const Account* a = call->account(); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::CALLID ).arg(call->historyId() ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::TIMESTAMP_START ).arg(call->startTimeStamp() ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::TIMESTAMP_STOP ).arg(call->stopTimeStamp() ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::ACCOUNT_ID ).arg(a?QString(a->id()):"" ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::DISPLAY_NAME ).arg(call->peerName() ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::PEER_NUMBER ).arg(call->peerContactMethod()->uri() ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::DIRECTION ).arg(direction ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::MISSED ).arg(call->isMissed() ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::RECORDING_PATH ).arg(call->recordingPath() ); - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::CONTACT_USED ).arg(false );//TODO - if (call->peerContactMethod()->contact()) { - stream << QString("%1=%2\n").arg(Call::HistoryMapFields::CONTACT_UID ).arg( - QString(call->peerContactMethod()->contact()->uid()) - ); - } - stream << "\n"; - stream.flush(); -} - -bool MinimalHistoryEditor::regenFile(const Call* toIgnore) -{ - QDir dir(QString('/')); - dir.mkpath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + QString()); - - QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') +"history.ini"); - if ( file.open(QIODevice::WriteOnly | QIODevice::Text) ) { - QTextStream stream(&file); - for (const Call* c : CategorizedHistoryModel::instance()->getHistoryCalls()) { - if (c != toIgnore) - saveCall(stream, c); - } - file.close(); - return true; - } - return false; -} - -bool MinimalHistoryEditor::save(const Call* call) -{ - if (call->collection()->editor<Call>() != this) - return addNew(call); - - return regenFile(nullptr); -} - -bool MinimalHistoryEditor::remove(const Call* item) -{ - mediator()->removeItem(item); - return regenFile(item); -} - -bool MinimalHistoryEditor::batchRemove(const QList<Call*> calls) { - QFile::remove(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + "history.ini"); - return YES; -} - -bool MinimalHistoryEditor::edit( Call* item) -{ - Q_UNUSED(item) - return false; -} - -bool MinimalHistoryEditor::addNew(const Call* call) -{ - QDir dir(QString('/')); - dir.mkpath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + QString()); - - if ((call->collection() && call->collection()->editor<Call>() == this) || call->historyId().isEmpty()) return false; - //TODO support \r and \n\r end of line - QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/')+"history.ini"); - - if ( file.open(QIODevice::Append | QIODevice::Text) ) { - QTextStream streamFileOut(&file); - saveCall(streamFileOut, call); - file.close(); - - const_cast<Call*>(call)->setCollection(m_pCollection); - addExisting(call); - return true; - } - else - qWarning() << "Unable to save history"; - return false; -} - -bool MinimalHistoryEditor::addExisting(const Call* item) -{ - m_lItems << const_cast<Call*>(item); - mediator()->addItem(item); - return true; -} - -QVector<Call*> MinimalHistoryEditor::items() const -{ - return m_lItems; -} - -QString MinimalHistoryBackend::name () const -{ - return QObject::tr("Minimal history backend"); -} - -QString MinimalHistoryBackend::category () const -{ - return QObject::tr("History"); -} - -QVariant MinimalHistoryBackend::icon() const -{ - return QVariant(); -} - -bool MinimalHistoryBackend::isEnabled() const -{ - return true; -} - -bool MinimalHistoryBackend::load() -{ - // get history limit from our preferences set - NSInteger historyLimit = [[NSUserDefaults standardUserDefaults] integerForKey:Preferences::HistoryLimit]; - - QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') +"history.ini"); - if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) { - QMap<QString,QString> hc; - while (!file.atEnd()) { - QByteArray line = file.readLine().trimmed(); - - //The item is complete - if ((line.isEmpty() || !line.size()) && hc.size()) { - Call* pastCall = Call::buildHistoryCall(hc); - if (pastCall->peerName().isEmpty()) { - pastCall->setPeerName(QObject::tr("Unknown")); - } - - if(daysSince(pastCall->startTimeStamp()) < historyLimit) { - pastCall->setRecordingPath(hc[ Call::HistoryMapFields::RECORDING_PATH ]); - pastCall->setCollection(this); - - editor<Call>()->addExisting(pastCall); - } - hc.clear(); - } - // Add to the current set - else { - const int idx = line.indexOf("="); - if (idx >= 0) - hc[line.left(idx)] = line.right(line.size()-idx-1); - } - } - return true; - } - else - qWarning() << "History doesn't exist or is not readable"; - return false; -} - -int MinimalHistoryBackend::daysSince(time_t timestamp) -{ - NSDate *fromDate; - NSDate *toDate; - - NSDate* fromDateTime = [NSDate dateWithTimeIntervalSince1970:timestamp]; - - NSCalendar *calendar = [NSCalendar currentCalendar]; - - [calendar rangeOfUnit:NSCalendarUnitDay startDate:&fromDate - interval:NULL forDate:fromDateTime]; - [calendar rangeOfUnit:NSCalendarUnitDay startDate:&toDate - interval:NULL forDate:[NSDate date]]; - - NSDateComponents *difference = [calendar components:NSCalendarUnitDay - fromDate:fromDate toDate:toDate options:0]; - - return [difference day]; -} - -bool MinimalHistoryBackend::reload() -{ - return false; -} - -FlagPack<CollectionInterface::SupportedFeatures> MinimalHistoryBackend::supportedFeatures() const -{ - return (FlagPack<SupportedFeatures>) ( - CollectionInterface::SupportedFeatures::NONE | - CollectionInterface::SupportedFeatures::LOAD | - CollectionInterface::SupportedFeatures::CLEAR | - CollectionInterface::SupportedFeatures::REMOVE| - CollectionInterface::SupportedFeatures::ADD ); -} - -bool MinimalHistoryBackend::clear() -{ - editor<Call>()->batchRemove(items<Call>().toList()); - QList<Call*> calls = items<Call>().toList(); - for(int i = 0 ; i < calls.count() ; ++i) { - CategorizedHistoryModel::instance()->deleteItem(calls[i]); - } - return true; -} - -QByteArray MinimalHistoryBackend::id() const -{ - return "mhb"; -}