audio: add ringtone support

Each account can now
- enable/disable ringtones (enable by default)
- choose a ringtone in the pre-packaged list

Change-Id: Id3b41b84b01566bf979f74114c8eb3e58d7b3f55
Tuleap: #338
diff --git a/src/AccAudioVC.mm b/src/AccAudioVC.mm
index b386247..7e8ba1f 100644
--- a/src/AccAudioVC.mm
+++ b/src/AccAudioVC.mm
@@ -23,21 +23,30 @@
 
 #import "AccAudioVC.h"
 
+///Qt
 #import <QSortFilterProxyModel>
+#import <qitemselectionmodel.h>
+
+///LRC
 #import <audio/codecmodel.h>
 #import <accountmodel.h>
-#import <qitemselectionmodel.h>
+#import <ringtonemodel.h>
+#import <ringtone.h>
 
 @interface AccAudioVC ()
 
-@property QNSTreeController *treeController;
-@property (assign) IBOutlet NSOutlineView *codecsView;
+@property QNSTreeController* treeController;
+@property (assign) IBOutlet NSOutlineView* codecsView;
+@property (unsafe_unretained) IBOutlet NSPopUpButton* ringtonePopUpButton;
+@property (unsafe_unretained) IBOutlet NSButton* enableRingtone;
+@property (unsafe_unretained) IBOutlet NSButton* playRingtone;
 
 @end
 
 @implementation AccAudioVC
 @synthesize treeController;
 @synthesize codecsView;
+@synthesize ringtonePopUpButton, enableRingtone, playRingtone;
 
 - (void)awakeFromNib
 {
@@ -49,6 +58,21 @@
                              return;
                          [self loadAccount];
                      });
+
+    QObject::connect(&RingtoneModel::instance(),
+                     &QAbstractItemModel::dataChanged,
+                     [=](const QModelIndex &current, const QModelIndex &previous) {
+                         if(!current.isValid())
+                             return;
+
+                         NSString* label;
+                         if (!RingtoneModel::instance().isPlaying()) {
+                             label = NSLocalizedString(@"Play", @"Button label");
+                         } else {
+                             label = NSLocalizedString(@"Pause", @"Button label");
+                         }
+                         [playRingtone setTitle:label];
+                     });
 }
 
 - (Account*) currentAccount
@@ -68,6 +92,29 @@
     [codecsView bind:@"content" toObject:treeController withKeyPath:@"arrangedObjects" options:nil];
     [codecsView bind:@"sortDescriptors" toObject:treeController withKeyPath:@"sortDescriptors" options:nil];
     [codecsView bind:@"selectionIndexPaths" toObject:treeController withKeyPath:@"selectionIndexPaths" options:nil];
+
+    QModelIndex qIdx = RingtoneModel::instance().selectionModel(account)->currentIndex();
+    [ringtonePopUpButton removeAllItems];
+    [ringtonePopUpButton addItemWithTitle:RingtoneModel::instance().data(qIdx, Qt::DisplayRole).toString().toNSString()];
+
+    [enableRingtone setState:account->isRingtoneEnabled()];
+    [ringtonePopUpButton setEnabled:account->isRingtoneEnabled()];
+}
+
+- (IBAction)startStopRingtone:(id)sender {
+    auto qIdx = RingtoneModel::instance().selectionModel([self currentAccount])->currentIndex();
+    RingtoneModel::instance().play(qIdx);
+}
+
+- (IBAction)toggleRingtoneEnabled:(id)sender {
+    [self currentAccount]->setRingtoneEnabled([sender state]);
+    [ringtonePopUpButton setEnabled:[sender state]];
+}
+
+- (IBAction)chooseRingtone:(id)sender {
+    int index = [sender indexOfSelectedItem];
+    QModelIndex qIdx = RingtoneModel::instance().index(index, 0);
+    RingtoneModel::instance().selectionModel([self currentAccount])->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
 }
 
 - (IBAction)moveUp:(id)sender {
@@ -171,12 +218,23 @@
     }
 }
 
-// -------------------------------------------------------------------------------
-//	outlineViewSelectionDidChange:notification
-// -------------------------------------------------------------------------------
-- (void)outlineViewSelectionDidChange:(NSNotification *)notification
-{
+#pragma mark - NSMenuDelegate methods
 
+- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
+{
+    QModelIndex qIdx;
+    qIdx = RingtoneModel::instance().index(index, 0);
+    [item setTitle:RingtoneModel::instance().data(qIdx, Qt::DisplayRole).toString().toNSString()];
+
+    if (qIdx == RingtoneModel::instance().selectionModel([self currentAccount])->currentIndex()) {
+        [ringtonePopUpButton selectItem:item];
+    }
+    return YES;
+}
+
+- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
+{
+    return RingtoneModel::instance().rowCount();
 }
 
 @end
diff --git a/ui/Base.lproj/AccAudio.xib b/ui/Base.lproj/AccAudio.xib
index 90a13ea..7eea814 100644
--- a/ui/Base.lproj/AccAudio.xib
+++ b/ui/Base.lproj/AccAudio.xib
@@ -1,29 +1,32 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14F27" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9532"/>
     </dependencies>
     <objects>
         <customObject id="-2" userLabel="File's Owner" customClass="AccAudioVC">
             <connections>
                 <outlet property="codecsView" destination="qUo-eR-iuq" id="gyu-3z-rNc"/>
+                <outlet property="enableRingtone" destination="Hmk-UR-N3c" id="mlo-Rs-aK3"/>
+                <outlet property="playRingtone" destination="RJm-Of-PRG" id="Fb9-J2-bA2"/>
+                <outlet property="ringtonePopUpButton" destination="eWp-24-n2G" id="hyf-7f-sbH"/>
                 <outlet property="view" destination="c22-O7-iKe" id="PBG-fI-bZm"/>
             </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="385" height="356"/>
+            <rect key="frame" x="0.0" y="0.0" width="385" height="352"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
             <subviews>
                 <scrollView focusRingType="none" fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yLX-W9-gcE">
-                    <rect key="frame" x="32" y="122" width="317" height="189"/>
-                    <clipView key="contentView" misplaced="YES" id="ttA-YT-HQA">
-                        <rect key="frame" x="1" y="17" width="238" height="117"/>
+                    <rect key="frame" x="32" y="46" width="317" height="189"/>
+                    <clipView key="contentView" ambiguous="YES" id="ttA-YT-HQA">
+                        <rect key="frame" x="1" y="0.0" width="315" height="188"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <outlineView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" autosaveColumns="NO" headerView="WuO-RU-Dfb" indentationPerLevel="16" outlineTableColumn="PGV-RF-f13" id="qUo-eR-iuq">
-                                <rect key="frame" x="0.0" y="0.0" width="315" height="19"/>
+                                <rect key="frame" x="0.0" y="0.0" width="315" height="165"/>
                                 <autoresizingMask key="autoresizingMask"/>
                                 <size key="intercellSpacing" width="3" height="2"/>
                                 <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -92,20 +95,20 @@
                         <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
                     </clipView>
                     <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="tAn-XY-KM0">
-                        <rect key="frame" x="1" y="119" width="223" height="15"/>
+                        <rect key="frame" x="1" y="7" width="0.0" height="16"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </scroller>
-                    <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="e9m-eK-gwP">
-                        <rect key="frame" x="224" y="17" width="15" height="102"/>
+                    <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="e9m-eK-gwP">
+                        <rect key="frame" x="-15" y="23" width="16" height="0.0"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </scroller>
                     <tableHeaderView key="headerView" id="WuO-RU-Dfb">
-                        <rect key="frame" x="0.0" y="0.0" width="238" height="17"/>
+                        <rect key="frame" x="0.0" y="0.0" width="315" height="23"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </tableHeaderView>
                 </scrollView>
                 <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zaU-3l-OYA">
-                    <rect key="frame" x="26" y="89" width="58" height="32"/>
+                    <rect key="frame" x="26" y="13" width="58" height="32"/>
                     <buttonCell key="cell" type="push" title="Up" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="MbZ-7X-K5I">
                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                         <font key="font" metaFont="system"/>
@@ -115,43 +118,15 @@
                     </connections>
                 </button>
                 <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qs3-sN-wPV">
-                    <rect key="frame" x="18" y="319" width="53" height="17"/>
+                    <rect key="frame" x="18" y="243" width="53" height="17"/>
                     <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Codecs" id="biN-bX-qM1">
                         <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>
-                <textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ipf-oU-a70">
-                    <rect key="frame" x="18" y="63" width="72" height="17"/>
-                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Ringtones" id="aMg-uJ-Krx">
-                        <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>
-                <pathControl hidden="YES" verticalHuggingPriority="750" fixedFrame="YES" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8cX-0X-us7">
-                    <rect key="frame" x="161" y="25" width="207" height="26"/>
-                    <pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="SGo-Cl-DoP">
-                        <font key="font" metaFont="system"/>
-                        <url key="url" string="file://localhost/Applications/"/>
-                        <allowedTypes>
-                            <string>public.folder</string>
-                        </allowedTypes>
-                    </pathCell>
-                    <connections>
-                        <outlet property="delegate" destination="-2" id="X9a-9D-s9f"/>
-                    </connections>
-                </pathControl>
-                <button hidden="YES" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Hmk-UR-N3c">
-                    <rect key="frame" x="30" y="29" width="128" height="18"/>
-                    <buttonCell key="cell" type="check" title="Enable ringtones" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="KkI-i1-mfY">
-                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
-                        <font key="font" metaFont="system"/>
-                    </buttonCell>
-                </button>
                 <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xN7-EP-314">
-                    <rect key="frame" x="77" y="89" width="76" height="32"/>
+                    <rect key="frame" x="77" y="13" width="76" height="32"/>
                     <buttonCell key="cell" type="push" title="Down" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Bbz-hd-1CE">
                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                         <font key="font" metaFont="system"/>
@@ -160,8 +135,51 @@
                         <action selector="moveDown:" target="-2" id="mQQ-dj-CAq"/>
                     </connections>
                 </button>
+                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ipf-oU-a70">
+                    <rect key="frame" x="18" y="315" width="72" height="17"/>
+                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Ringtones" id="aMg-uJ-Krx">
+                        <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="Hmk-UR-N3c">
+                    <rect key="frame" x="30" y="281" width="128" height="18"/>
+                    <buttonCell key="cell" type="check" title="Enable ringtones" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="KkI-i1-mfY">
+                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                        <font key="font" metaFont="system"/>
+                    </buttonCell>
+                    <connections>
+                        <action selector="toggleRingtoneEnabled:" target="-2" id="f96-LJ-xp0"/>
+                    </connections>
+                </button>
+                <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eWp-24-n2G">
+                    <rect key="frame" x="162" y="276" width="125" height="26"/>
+                    <popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="Gqo-nO-EkC">
+                        <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
+                        <font key="font" metaFont="menu"/>
+                        <menu key="menu" id="Zb8-jY-Oso">
+                            <connections>
+                                <outlet property="delegate" destination="-2" id="tuo-Ys-8vs"/>
+                            </connections>
+                        </menu>
+                    </popUpButtonCell>
+                    <connections>
+                        <action selector="chooseRingtone:" target="-2" id="5OO-Kz-xvM"/>
+                    </connections>
+                </popUpButton>
+                <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RJm-Of-PRG">
+                    <rect key="frame" x="294" y="272" width="66" height="32"/>
+                    <buttonCell key="cell" type="push" title="Play" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8jq-XH-nJV">
+                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                        <font key="font" metaFont="system"/>
+                    </buttonCell>
+                    <connections>
+                        <action selector="startStopRingtone:" target="-2" id="5tI-Wm-Jpz"/>
+                    </connections>
+                </button>
             </subviews>
-            <point key="canvasLocation" x="69.5" y="52"/>
+            <point key="canvasLocation" x="69.5" y="-22"/>
         </customView>
     </objects>
 </document>