blob: c1c85298914de3a1ef716c2f80ec21ec28b788d5 [file] [log] [blame]
Alexandre Lisione4d61cb2016-02-10 09:26:24 -05001/*
2 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
3 * Author: Alexandre Lision <alexandre.lision@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 Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19#import "AccMediaVC.h"
20
21///Qt
22#import <QSortFilterProxyModel>
23#import <qitemselectionmodel.h>
24
25///LRC
Edric Milaretea245cd2016-03-21 12:19:39 -040026#import <codecmodel.h>
Alexandre Lisione4d61cb2016-02-10 09:26:24 -050027#import <accountmodel.h>
28#import <ringtonemodel.h>
29#import <ringtone.h>
30
31@interface AccMediaVC ()
32
33@property QNSTreeController* audioTreeController;
34@property QNSTreeController* videoTreeController;
35@property (unsafe_unretained) IBOutlet NSPopUpButton* ringtonePopUpButton;
36@property (unsafe_unretained) IBOutlet NSButton* enableRingtone;
37@property (unsafe_unretained) IBOutlet NSButton* playRingtone;
38@property (unsafe_unretained) IBOutlet NSButton *toggleVideoButton;
39@property (unsafe_unretained) IBOutlet NSOutlineView* audioCodecView;
40@property (unsafe_unretained) IBOutlet NSOutlineView* videoCodecView;
41@property (unsafe_unretained) IBOutlet NSView* videoPanelContainer;
42
43@end
44
45@implementation AccMediaVC
46@synthesize audioTreeController, videoTreeController;
47@synthesize audioCodecView, videoCodecView;
48@synthesize videoPanelContainer;
49@synthesize ringtonePopUpButton, enableRingtone, playRingtone, toggleVideoButton;
50
51NSInteger const TAG_CHECK = 100;
52NSInteger const TAG_NAME = 200;
53NSInteger const TAG_DETAILS = 300;
54
55NSString* const ID_AUDIO = @"audioview";
56NSString* const ID_VIDEO = @"videoview";
57
58- (void) loadView
59{
60 [super loadView];
61 NSLog(@"INIT Media VC");
62 QObject::connect(AccountModel::instance().selectionModel(),
63 &QItemSelectionModel::currentChanged,
64 [=](const QModelIndex &current, const QModelIndex &previous) {
65 if(!current.isValid())
66 return;
67 [self loadAccount];
68 });
69
70 QObject::connect(&RingtoneModel::instance(),
71 &QAbstractItemModel::dataChanged,
72 [=](const QModelIndex &current, const QModelIndex &previous) {
73 if(!current.isValid())
74 return;
75
76 NSString* label;
77 if (!RingtoneModel::instance().isPlaying()) {
78 label = NSLocalizedString(@"Play", @"Button label");
79 } else {
80 label = NSLocalizedString(@"Pause", @"Button label");
81 }
82 [playRingtone setTitle:label];
83 });
84}
85
86- (void)loadAccount
87{
88 // AUDIO
89 [self loadAudioPrefs];
90
91 // VIDEO
92 [self loadVideoPrefs];
93
94}
95
96#pragma Audio Preferences method
97
98- (void) loadAudioPrefs
99{
100 auto account = AccountModel::instance().selectedAccount();
101 audioTreeController = [[QNSTreeController alloc] initWithQModel:account->codecModel()->audioCodecs()];
102 [audioTreeController setAvoidsEmptySelection:NO];
103 [audioTreeController setChildrenKeyPath:@"children"];
104 [audioCodecView bind:@"content" toObject:audioTreeController withKeyPath:@"arrangedObjects" options:nil];
105 [audioCodecView bind:@"sortDescriptors" toObject:audioTreeController withKeyPath:@"sortDescriptors" options:nil];
106 [audioCodecView bind:@"selectionIndexPaths" toObject:audioTreeController withKeyPath:@"selectionIndexPaths" options:nil];
107 [audioCodecView setIdentifier:ID_AUDIO];
108
109 QModelIndex qIdx = RingtoneModel::instance().selectionModel(account)->currentIndex();
110 [ringtonePopUpButton removeAllItems];
111 [ringtonePopUpButton addItemWithTitle:RingtoneModel::instance().data(qIdx, Qt::DisplayRole).toString().toNSString()];
112
113 [enableRingtone setState:account->isRingtoneEnabled()];
114 [ringtonePopUpButton setEnabled:account->isRingtoneEnabled()];
115}
116
117- (IBAction)startStopRingtone:(id)sender {
118 auto qIdx = RingtoneModel::instance().selectionModel(AccountModel::instance().selectedAccount())->currentIndex();
119 RingtoneModel::instance().play(qIdx);
120}
121
122- (IBAction)toggleRingtoneEnabled:(id)sender {
123 AccountModel::instance().selectedAccount()->setRingtoneEnabled([sender state]);
124 [ringtonePopUpButton setEnabled:[sender state]];
125}
126
127- (IBAction)chooseRingtone:(id)sender {
128 int index = [sender indexOfSelectedItem];
129 QModelIndex qIdx = RingtoneModel::instance().index(index, 0);
130 RingtoneModel::instance().selectionModel(AccountModel::instance().selectedAccount())->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
131}
132
133- (IBAction)moveAudioCodecUp:(id)sender {
134 if([[audioTreeController selectedNodes] count] > 0) {
135 QModelIndex qIdx = [audioTreeController toQIdx:[audioTreeController selectedNodes][0]];
136 if(!qIdx.isValid())
137 return;
138
139 QMimeData* mime = AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->mimeData(QModelIndexList() << qIdx);
140 AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->dropMimeData(mime, Qt::MoveAction, qIdx.row() - 1, 0, QModelIndex());
141 }
142}
143
144- (IBAction)moveAudioCodecDown:(id)sender {
145 if([[audioTreeController selectedNodes] count] > 0) {
146 QModelIndex qIdx = [audioTreeController toQIdx:[audioTreeController selectedNodes][0]];
147 if(!qIdx.isValid())
148 return;
149
150 QMimeData* mime = AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->mimeData(QModelIndexList() << qIdx);
151 AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->dropMimeData(mime, Qt::MoveAction, qIdx.row() + 1, 0, QModelIndex());
152 }
153}
154
155- (IBAction)toggleAudioCodec:(NSButton*)sender {
156 NSInteger row = [audioCodecView rowForView:sender];
157 QModelIndex qIdx = AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->index(row, 0, QModelIndex());
158 AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->setData(qIdx, sender.state == NSOnState ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
159}
160
161#pragma Video Preferences method
162
163-(void) loadVideoPrefs
164{
165 auto account = AccountModel::instance().selectedAccount();
166 videoTreeController = [[QNSTreeController alloc] initWithQModel:account->codecModel()->videoCodecs()];
167 [videoTreeController setAvoidsEmptySelection:NO];
168 [videoTreeController setChildrenKeyPath:@"children"];
169
170 [videoCodecView setIdentifier:ID_VIDEO];
171 [videoCodecView bind:@"content" toObject:videoTreeController withKeyPath:@"arrangedObjects" options:nil];
172 [videoCodecView bind:@"sortDescriptors" toObject:videoTreeController withKeyPath:@"sortDescriptors" options:nil];
173 [videoCodecView bind:@"selectionIndexPaths" toObject:videoTreeController withKeyPath:@"selectionIndexPaths" options:nil];
174 [videoPanelContainer setHidden:!account->isVideoEnabled()];
175 [toggleVideoButton setState:account->isVideoEnabled()?NSOnState:NSOffState];
176
177}
178
179- (IBAction)toggleVideoEnabled:(id)sender {
180 AccountModel::instance().selectedAccount()->setVideoEnabled([sender state] == NSOnState);
181 [videoPanelContainer setHidden:!AccountModel::instance().selectedAccount()->isVideoEnabled()];
182}
183
184- (IBAction)toggleVideoCodec:(NSButton*)sender {
185 NSInteger row = [videoCodecView rowForView:sender];
186 QModelIndex qIdx = AccountModel::instance().selectedAccount()->codecModel()->videoCodecs()->index(row, 0, QModelIndex());
187 AccountModel::instance().selectedAccount()->codecModel()->videoCodecs()->setData(qIdx, sender.state == NSOnState ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
188}
189
190- (IBAction)moveVideoCodecUp:(id)sender {
191
192 if([[videoTreeController selectedNodes] count] > 0) {
193 QModelIndex qIdx = [videoTreeController toQIdx:[videoTreeController selectedNodes][0]];
194 if(!qIdx.isValid())
195 return;
196
197 QMimeData* mime = AccountModel::instance().selectedAccount()->codecModel()->mimeData(QModelIndexList() << qIdx);
198 AccountModel::instance().selectedAccount()->codecModel()->dropMimeData(mime, Qt::MoveAction, qIdx.row() - 1, 0, QModelIndex());
199 }
200}
201
202- (IBAction)moveVideoCodecDown:(id)sender {
203 if([[videoTreeController selectedNodes] count] > 0) {
204 QModelIndex qIdx = [videoTreeController toQIdx:[videoTreeController selectedNodes][0]];
205 if(!qIdx.isValid())
206 return;
207
208 QMimeData* mime = AccountModel::instance().selectedAccount()->codecModel()->mimeData(QModelIndexList() << qIdx);
209 AccountModel::instance().selectedAccount()->codecModel()->dropMimeData(mime, Qt::MoveAction, qIdx.row() + 1, 0, QModelIndex());
210 }
211}
212
213
214#pragma mark - NSOutlineViewDelegate methods
215
216- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item;
217{
218 return YES;
219}
220
221- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
222{
223 NSTableView* result = [outlineView makeViewWithIdentifier:@"CodecView" owner:self];
224
225 QModelIndex qIdx;
226 if ([outlineView.identifier isEqualToString:ID_AUDIO])
227 qIdx = [audioTreeController toQIdx:((NSTreeNode*)item)];
228 else
229 qIdx = [videoTreeController toQIdx:((NSTreeNode*)item)];
230
231 if(!qIdx.isValid())
232 return result;
233 NSTextField* name = [result viewWithTag:TAG_NAME];
234 NSTextField* details = [result viewWithTag:TAG_DETAILS];
235 NSButton* check = [result viewWithTag:TAG_CHECK];
236
237 if ([outlineView.identifier isEqualToString:ID_AUDIO]) {
238 [name setStringValue:AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->data(qIdx, CodecModel::Role::NAME).toString().toNSString()];
239 [details setStringValue:[NSString stringWithFormat:@"%@ Hz", AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->data(qIdx, CodecModel::Role::SAMPLERATE).toString().toNSString()]];
240 [check setState:AccountModel::instance().selectedAccount()->codecModel()->audioCodecs()->data(qIdx, Qt::CheckStateRole).value<BOOL>()?NSOnState:NSOffState];
241 } else {
242 [name setStringValue:AccountModel::instance().selectedAccount()->codecModel()->videoCodecs()->data(qIdx, CodecModel::Role::NAME).toString().toNSString()];
243 [check setState:AccountModel::instance().selectedAccount()->codecModel()->videoCodecs()->data(qIdx, Qt::CheckStateRole).value<BOOL>()?NSOnState:NSOffState];
244 }
245
246 return result;
247}
248
249#pragma mark - NSMenuDelegate methods
250
251- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
252{
253 QModelIndex qIdx;
254 qIdx = RingtoneModel::instance().index(index, 0);
255 [item setTitle:RingtoneModel::instance().data(qIdx, Qt::DisplayRole).toString().toNSString()];
256
257 if (qIdx == RingtoneModel::instance().selectionModel(AccountModel::instance().selectedAccount())->currentIndex()) {
258 [ringtonePopUpButton selectItem:item];
259 }
260 return YES;
261}
262
263- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
264{
265 return RingtoneModel::instance().rowCount();
266}
267
268@end