Commit e404149a authored by Alexandre Lision's avatar Alexandre Lision Committed by Alexandre Lision

preferences: add user oriented features

- notifications on incoming calls
- history limitation / deletion
- bring app to foreground

Refs #66840

Change-Id: I847d45337f438140904523d9306583c72a8f3625
parent 7837e4ff
......@@ -35,7 +35,7 @@
#import "RingWindowController.h"
#import "PreferencesWindowController.h"
@interface AppDelegate : NSObject <NSApplicationDelegate>
@interface AppDelegate : NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate>
@property RingWindowController* ringWindowController;
......
......@@ -29,14 +29,43 @@
*/
#import "AppDelegate.h"
#import <callmodel.h>
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
self.ringWindowController = [[RingWindowController alloc] initWithWindowNibName:@"RingWindow"];
[self.ringWindowController showWindow:nil];
[self connect];
}
- (void) connect
{
QObject::connect(CallModel::instance(),
&CallModel::incomingCall,
[=](Call* call) {
BOOL shouldComeToForeground = [[NSUserDefaults standardUserDefaults] boolForKey:@"window_behaviour"];
BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_notifications"];
if(shouldComeToForeground)
[NSApp activateIgnoringOtherApps:YES];
if(shouldNotify) {
[self showIncomingNotification:call];
}
});
}
- (void) showIncomingNotification:(Call*) call{
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = @"Incoming call", call->peerName();
//notification.informativeText = @"A notification";
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
@end
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1510" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6254"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="GeneralPrefsVC">
<connections>
<outlet property="historyChangedLabel" destination="Gyi-ID-Z3v" id="aoO-Fh-UCQ"/>
<outlet property="view" destination="c22-O7-iKe" id="kqH-6G-Ohq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="c22-O7-iKe">
<rect key="frame" x="0.0" y="0.0" width="562" height="272"/>
<rect key="frame" x="0.0" y="0.0" width="562" height="249"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kYQ-jU-skU">
<rect key="frame" x="57" y="226" width="143" height="17"/>
<rect key="frame" x="57" y="203" width="143" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Desktop Notifications:" id="xlz-zw-IJI">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dPI-8j-Y0b">
<rect key="frame" x="113" y="117" width="87" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Calls History:" id="ss6-63-XJO">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lIm-zX-RIV">
<rect key="frame" x="76" y="172" width="124" height="17"/>
<rect key="frame" x="76" y="167" width="124" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Window behaviour:" id="sog-Ok-Y0N">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
......@@ -41,63 +33,87 @@
</textFieldCell>
</textField>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Oth-up-2k2">
<rect key="frame" x="204" y="224" width="147" height="18"/>
<rect key="frame" x="204" y="201" width="147" height="18"/>
<buttonCell key="cell" type="check" title="Enable Notifications" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="uCL-ye-tsv">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="Sz0-vm-i3t" name="value" keyPath="values.enable_notifications" id="PuD-KZ-Zat"/>
</connections>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DgD-2y-4g5">
<rect key="frame" x="204" y="115" width="195" height="18"/>
<buttonCell key="cell" type="check" title="Keep my history for at least" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="3Pb-Ec-zl5">
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Is4-pD-LOT">
<rect key="frame" x="204" y="166" width="294" height="18"/>
<buttonCell key="cell" type="check" title="Bring Ring to foreground on incoming calls" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="uYI-hA-JHk">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="Sz0-vm-i3t" name="value" keyPath="values.window_behaviour" id="ZSW-he-LAz"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rF1-Fa-8rV">
<rect key="frame" x="83" y="63" width="121" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Instant Messaging:" id="afz-zn-9IW">
<font key="font" metaFont="system"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fC0-ce-Yiz">
<rect key="frame" x="38" y="127" width="54" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="History" id="DSD-yl-noX">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DgD-2y-4g5">
<rect key="frame" x="56" y="100" width="195" height="18"/>
<buttonCell key="cell" type="check" title="Keep my history for at least" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="3Pb-Ec-zl5">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QmA-ZI-ZL5">
<rect key="frame" x="450" y="110" width="19" height="27"/>
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="100" id="30B-YQ-Opa"/>
<rect key="frame" x="302" y="94" width="19" height="27"/>
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="100" doubleValue="30" id="30B-YQ-Opa"/>
<connections>
<binding destination="Sz0-vm-i3t" name="value" keyPath="values.history_limit" id="c2j-mK-kYa"/>
</connections>
</stepper>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tHZ-7Q-5iP">
<rect key="frame" x="405" y="113" width="40" height="22"/>
<rect key="frame" x="257" y="97" width="40" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="center" title="30" drawsBackground="YES" id="JvS-c4-OeT">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="Sz0-vm-i3t" name="value" keyPath="values.history_limit" id="O2j-lT-MbR"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nah-Jm-ZYB">
<rect key="frame" x="472" y="117" width="33" height="17"/>
<rect key="frame" x="324" y="101" width="33" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="days" id="e5K-l0-Nfw">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Is4-pD-LOT">
<rect key="frame" x="204" y="170" width="294" height="18"/>
<buttonCell key="cell" type="check" title="Bring Ring to foreground on incoming calls" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="uYI-hA-JHk">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LRd-Zc-tRd">
<rect key="frame" x="204" y="62" width="182" height="18"/>
<buttonCell key="cell" type="check" title="Enable instant messaging" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="6UW-Db-jnY">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="U84-le-Iy4">
<rect key="frame" x="58" y="63" width="122" height="19"/>
<buttonCell key="cell" type="roundRect" title="Clear History" bezelStyle="roundedRect" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="cd5-9L-Bbb">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<action selector="clearHistory:" target="-2" id="yN7-bB-7EY"/>
</connections>
</button>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Gyi-ID-Z3v">
<rect key="frame" x="361" y="97" width="167" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="(Applied on application restart)" id="OTl-vx-S43">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<point key="canvasLocation" x="374" y="349"/>
<point key="canvasLocation" x="383" y="124.5"/>
</customView>
<userDefaultsController representsSharedInstance="YES" id="Sz0-vm-i3t"/>
</objects>
</document>
......@@ -34,6 +34,7 @@
@interface GeneralPrefsVC : NSViewController {
NSTextField *historyChangedLabel;
}
@end
......
......@@ -29,12 +29,35 @@
*/
#import "GeneralPrefsVC.h"
#import <categorizedhistorymodel.h>
@interface GeneralPrefsVC ()
@property (assign) IBOutlet NSTextField *historyChangedLabel;
@end
@implementation GeneralPrefsVC {
}
@synthesize historyChangedLabel;
- (void)loadView
{
[super loadView];
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"history_limit" options:NSKeyValueObservingOptionNew context:NULL];
}
- (IBAction)clearHistory:(id)sender {
CategorizedHistoryModel::instance()->clearAllCollections();
[historyChangedLabel setHidden:NO];
}
// KVO handler
-(void)observeValueForKeyPath:(NSString *)aKeyPath ofObject:(id)anObject
change:(NSDictionary *)aChange context:(void *)aContext
{
NSLog(@"VALUE CHANGED");
[historyChangedLabel setHidden:NO];
}
@end
......@@ -42,7 +42,6 @@
#define COLUMNID_CONTACTMETHOD @"ContactMethodColumn" // the single column name in our outline view
#define COLUMNID_DATE @"DateColumn" // the single column name in our outline view
@interface HistoryViewController()
@property NSTreeController *treeController;
......@@ -81,10 +80,7 @@
[historyView setTarget:self];
[historyView setDoubleAction:@selector(placeCall:)];
NSInteger idx = [historyView columnWithIdentifier:COLUMNID_DAY];
CategorizedHistoryModel::instance()->addCollection<MinimalHistoryBackend>(LoadOptions::FORCE_ENABLED);
}
- (void)placeCall:(id)sender
......
......@@ -18,12 +18,16 @@
***********************************************************************************/
#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>
......@@ -38,6 +42,7 @@ 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;
......@@ -124,9 +129,15 @@ bool MinimalHistoryEditor::save(const Call* call)
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)
......@@ -190,6 +201,9 @@ bool MinimalHistoryBackend::isEnabled() const
bool MinimalHistoryBackend::load()
{
// get history limit from our preferences set
NSInteger historyLimit = [[NSUserDefaults standardUserDefaults] integerForKey:@"history_limit"];
QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') +"history.ini");
if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) {
QMap<QString,QString> hc;
......@@ -202,10 +216,13 @@ bool MinimalHistoryBackend::load()
if (pastCall->peerName().isEmpty()) {
pastCall->setPeerName(QObject::tr("Unknown"));
}
pastCall->setRecordingPath(hc[ Call::HistoryMapFields::RECORDING_PATH ]);
pastCall->setCollection(this);
editor<Call>()->addExisting(pastCall);
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
......@@ -222,6 +239,26 @@ bool MinimalHistoryBackend::load()
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;
......@@ -239,7 +276,11 @@ CollectionInterface::SupportedFeatures MinimalHistoryBackend::supportedFeatures(
bool MinimalHistoryBackend::clear()
{
QFile::remove(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + "history.ini");
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;
}
......
......@@ -32,6 +32,7 @@
#import <QuartzCore/QuartzCore.h>
#import <accountmodel.h>
#import <audio/codecmodel.h>
#import "AccountsVC.h"
#import "GeneralPrefsVC.h"
......@@ -82,7 +83,13 @@ static NSString* const kPowerSettingsIdentifer = @"PowerSettingsIdentifer";
- (void) close
{
// first save codecs for each account
for (int i = 0 ; i < AccountModel::instance()->rowCount(); ++i) {
QModelIndex qIdx = AccountModel::instance()->index(i);
AccountModel::instance()->getAccountByModelIndex(qIdx)->codecModel()->save();
}
// then save accounts
AccountModel::instance()->save();
CGRect frame = CGRectOffset(self.view.frame, 0, -self.view.frame.size.height);
......
......@@ -20,7 +20,6 @@
#define MINIMALHISTORYBACKEND_H
#import <collectioninterface.h>
#import <collectioneditor.h>
class Call;
......@@ -41,6 +40,8 @@ public:
virtual bool isEnabled() const override;
virtual QByteArray id () const override;
virtual SupportedFeatures supportedFeatures() const override;
int daysSince(time_t timestamp);
private:
CollectionMediator<Call>* m_pMediator;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment