blob: ba3095bf44abe9d45cfe63b5dacb83e7a56b2c75 [file] [log] [blame]
Alexandre Lisionf5fc4792015-03-17 09:15:43 -04001/*
Alexandre Lision9fe374b2016-01-06 10:17:31 -05002 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
Alexandre Lisionf5fc4792015-03-17 09:15:43 -04003 * 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.
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040018 */
19
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040020#import "AccountsVC.h"
21
Alexandre Lision0c56cb62016-02-12 18:04:08 -050022// Qt
23#import <QItemSelectionModel>
Alexandre Lision91d11e52015-03-20 17:42:05 -040024#import <QSortFilterProxyModel>
Alexandre Lision0c56cb62016-02-12 18:04:08 -050025#import <QtCore/qdir.h>
26#import <QtCore/qstandardpaths.h>
27
28// LRC
Alexandre Lision91d11e52015-03-20 17:42:05 -040029#import <accountmodel.h>
30#import <protocolmodel.h>
Alexandre Lision91d11e52015-03-20 17:42:05 -040031#import <account.h>
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040032
33#import "QNSTreeController.h"
34#import "AccGeneralVC.h"
Alexandre Lisione4d61cb2016-02-10 09:26:24 -050035#import "AccMediaVC.h"
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040036#import "AccAdvancedVC.h"
37#import "AccSecurityVC.h"
38#import "AccRingVC.h"
Alexandre Lisionc1f96662016-03-23 17:24:19 -040039#import "PathPasswordWC.h"
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040040
Alexandre Lisionc1f96662016-03-23 17:24:19 -040041@interface AccountsVC () <PathPasswordDelegate>
42
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040043@property (assign) IBOutlet NSPopUpButton *protocolList;
44
45@property (assign) IBOutlet NSTabView *configPanels;
46@property (retain) IBOutlet NSTabViewItem *generalTabItem;
Alexandre Lisione4d61cb2016-02-10 09:26:24 -050047@property (retain) IBOutlet NSTabViewItem *mediaTabItem;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040048@property (retain) IBOutlet NSTabViewItem *advancedTabItem;
49@property (retain) IBOutlet NSTabViewItem *securityTabItem;
50@property (retain) IBOutlet NSTabViewItem *ringTabItem;
51
52@property QNSTreeController *treeController;
53@property (assign) IBOutlet NSOutlineView *accountsListView;
54@property (assign) IBOutlet NSTabView *accountDetailsView;
Alexandre Lisionc1f96662016-03-23 17:24:19 -040055@property (unsafe_unretained) IBOutlet NSButton* exportAccountButton;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040056
57@property AccRingVC* ringVC;
58@property AccGeneralVC* generalVC;
Alexandre Lisione4d61cb2016-02-10 09:26:24 -050059@property AccMediaVC* audioVC;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040060@property AccAdvancedVC* advancedVC;
61@property AccSecurityVC* securityVC;
Alexandre Lisionc1f96662016-03-23 17:24:19 -040062@property PathPasswordWC* passwordWC;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040063
64@end
65
66@implementation AccountsVC
67@synthesize protocolList;
68@synthesize configPanels;
69@synthesize generalTabItem;
Alexandre Lisione4d61cb2016-02-10 09:26:24 -050070@synthesize mediaTabItem;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040071@synthesize advancedTabItem;
72@synthesize securityTabItem;
73@synthesize ringTabItem;
74@synthesize accountsListView;
75@synthesize accountDetailsView;
76@synthesize treeController;
Alexandre Lisionc1f96662016-03-23 17:24:19 -040077@synthesize passwordWC;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040078
Alexandre Lision0c56cb62016-02-12 18:04:08 -050079NSInteger const TAG_CHECK = 100;
80NSInteger const TAG_NAME = 200;
81NSInteger const TAG_STATUS = 300;
82NSInteger const TAG_TYPE = 400;
83
Alexandre Lisionc1f96662016-03-23 17:24:19 -040084typedef NS_ENUM(NSUInteger, Action) {
85 ACTION_EXPORT = 0,
86 ACTION_IMPORT = 1,
87};
88
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040089- (void)awakeFromNib
90{
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040091 treeController = [[QNSTreeController alloc] initWithQModel:&AccountModel::instance()];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040092 [treeController setAvoidsEmptySelection:NO];
93 [treeController setAlwaysUsesMultipleValuesMarker:YES];
94 [treeController setChildrenKeyPath:@"children"];
95
96 [accountsListView bind:@"content" toObject:treeController withKeyPath:@"arrangedObjects" options:nil];
97 [accountsListView bind:@"sortDescriptors" toObject:treeController withKeyPath:@"sortDescriptors" options:nil];
98 [accountsListView bind:@"selectionIndexPaths" toObject:treeController withKeyPath:@"selectionIndexPaths" options:nil];
99
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400100 QObject::connect(&AccountModel::instance(),
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400101 &QAbstractItemModel::dataChanged,
102 [=](const QModelIndex &topLeft, const QModelIndex &bottomRight) {
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400103 [accountsListView reloadDataForRowIndexes:
104 [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(topLeft.row(), bottomRight.row() + 1)]
105 columnIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, accountsListView.tableColumns.count)]];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400106 });
107
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500108 QObject::connect(AccountModel::instance().selectionModel(),
109 &QItemSelectionModel::currentChanged,
110 [=](const QModelIndex &current, const QModelIndex &previous) {
111 [accountDetailsView setHidden:!current.isValid()];
112 if(!current.isValid()) {
113 [accountsListView deselectAll:nil];
114 return;
115 }
116
117 [treeController setSelectionQModelIndex:current];
118 });
119
120
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400121 AccountModel::instance().selectionModel()->clearCurrentIndex();
Alexandre Lision7f3164c2015-06-12 11:45:37 -0400122
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400123 QModelIndex qProtocolIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400124 [self.protocolList addItemWithTitle:
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400125 AccountModel::instance().protocolModel()->data(qProtocolIdx, Qt::DisplayRole).toString().toNSString()];
Alexandre Lision274c22c2016-06-30 11:57:43 -0400126 QObject::connect(AccountModel::instance().protocolModel()->selectionModel(),
127 &QItemSelectionModel::currentChanged,
128 [=](const QModelIndex &current, const QModelIndex &previous) {
129 if (!current.isValid()) {
130 return;
131 }
132 [protocolList removeAllItems];
133 [protocolList addItemWithTitle:AccountModel::instance().protocolModel()->data(current, Qt::DisplayRole).toString().toNSString()];
134 });
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400135
136 self.generalVC = [[AccGeneralVC alloc] initWithNibName:@"AccGeneral" bundle:nil];
137 [[self.generalVC view] setFrame:[self.generalTabItem.view frame]];
138 [[self.generalVC view] setBounds:[self.generalTabItem.view bounds]];
139 [self.generalTabItem setView:self.generalVC.view];
140
Alexandre Lisione4d61cb2016-02-10 09:26:24 -0500141 self.audioVC = [[AccMediaVC alloc] initWithNibName:@"AccMedia" bundle:nil];
142 [[self.audioVC view] setFrame:[self.mediaTabItem.view frame]];
143 [[self.audioVC view] setBounds:[self.mediaTabItem.view bounds]];
144 [self.mediaTabItem setView:self.audioVC.view];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400145
146 self.advancedVC = [[AccAdvancedVC alloc] initWithNibName:@"AccAdvanced" bundle:nil];
147 [[self.advancedVC view] setFrame:[self.advancedTabItem.view frame]];
148 [[self.advancedVC view] setBounds:[self.advancedTabItem.view bounds]];
149 [self.advancedTabItem setView:self.advancedVC.view];
150
151 self.securityVC = [[AccSecurityVC alloc] initWithNibName:@"AccSecurity" bundle:nil];
152 [[self.securityVC view] setFrame:[self.securityTabItem.view frame]];
153 [[self.securityVC view] setBounds:[self.securityTabItem.view bounds]];
154 [self.securityTabItem setView:self.securityVC.view];
155
156 self.ringVC = [[AccRingVC alloc] initWithNibName:@"AccRing" bundle:nil];
157 [[self.ringVC view] setFrame:[self.ringTabItem.view frame]];
158 [[self.ringVC view] setBounds:[self.ringTabItem.view bounds]];
159 [self.ringTabItem setView:self.ringVC.view];
160}
161
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400162- (IBAction)addAccount:(id)sender {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400163 QModelIndex qIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400164
Alexandre Lision81c97212015-06-17 15:51:53 -0400165 auto newAccName = [[NSString alloc] initWithFormat:@"%@ account",
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400166 AccountModel::instance().protocolModel()->data(qIdx, Qt::DisplayRole).toString().toNSString(), nil];
167 auto acc = AccountModel::instance().add([newAccName UTF8String], qIdx);
Alexandre Lisiona1f07bf2015-07-28 10:30:55 -0400168 acc->setDisplayName(acc->alias());
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400169 AccountModel::instance().save();
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400170}
171
172- (IBAction)protocolSelectedChanged:(id)sender {
173
174 int index = [sender indexOfSelectedItem];
Alexandre Lision274c22c2016-06-30 11:57:43 -0400175 auto qIdx = AccountModel::instance().protocolModel()->index(index, 0);
176 AccountModel::instance().protocolModel()->selectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400177}
178
Alexandre Lision7f3164c2015-06-12 11:45:37 -0400179- (void) setupSIPPanels
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400180{
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400181 // Start by removing all tabs
182 for(NSTabViewItem* item in configPanels.tabViewItems) {
183 [configPanels removeTabViewItem:item];
184 }
185
186 [configPanels insertTabViewItem:generalTabItem atIndex:0];
Alexandre Lisione4d61cb2016-02-10 09:26:24 -0500187 [configPanels insertTabViewItem:mediaTabItem atIndex:1];
188 [configPanels insertTabViewItem:advancedTabItem atIndex:2];
189 [configPanels insertTabViewItem:securityTabItem atIndex:3];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400190}
191
Alexandre Lision7f3164c2015-06-12 11:45:37 -0400192- (void) setupRINGPanels
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400193{
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400194 // Start by removing all tabs
195 for(NSTabViewItem* item in configPanels.tabViewItems) {
196 [configPanels removeTabViewItem:item];
197 }
198
199 [configPanels insertTabViewItem:ringTabItem atIndex:0];
Alexandre Lisione4d61cb2016-02-10 09:26:24 -0500200 [configPanels insertTabViewItem:mediaTabItem atIndex:1];
201 [configPanels insertTabViewItem:advancedTabItem atIndex:2];
Alexandre Lision9ddfd8d2015-08-10 15:11:16 -0400202
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400203}
Alexandre Lisionc1f96662016-03-23 17:24:19 -0400204- (IBAction)exportAccount:(id)sender
205{
206 passwordWC = [[PathPasswordWC alloc] initWithDelegate:self actionCode:Action::ACTION_EXPORT];
207#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9
208 [self.view.window beginSheet:passwordWC.window completionHandler:nil];
209#else
210 [NSApp beginSheet: passwordWC.window
211 modalForWindow: self.view.window
212 modalDelegate: self
213 didEndSelector: nil
214 contextInfo: nil];
215#endif
216 [passwordWC setAllowFileSelection:NO];
217}
218
219- (IBAction)importAccount:(id)sender
220{
221 passwordWC = [[PathPasswordWC alloc] initWithDelegate:self actionCode:Action::ACTION_IMPORT];
222#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9
223 [self.view.window beginSheet:passwordWC.window completionHandler:nil];
224#else
225 [NSApp beginSheet: passwordWC.window
226 modalForWindow: self.view.window
227 modalDelegate: self
228 didEndSelector: nil
229 contextInfo: nil];
230#endif
231}
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400232
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500233- (IBAction)toggleAccount:(NSButton*)sender {
234 NSInteger row = [accountsListView rowForView:sender];
235 auto accountToToggle = AccountModel::instance().getAccountByModelIndex(AccountModel::instance().index(row));
236 accountToToggle->setEnabled(sender.state);
237 accountToToggle << Account::EditAction::SAVE;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400238}
239
240#pragma mark - NSOutlineViewDelegate methods
241
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400242- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item;
243{
244 return YES;
245}
246
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500247- (NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400248{
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500249 return [outlineView makeViewWithIdentifier:@"HoverRowView" owner:nil];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400250}
251
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500252- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400253{
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500254 NSTableView* result = [outlineView makeViewWithIdentifier:@"AccountView" owner:self];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400255
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400256 QModelIndex qIdx = [treeController toQIdx:((NSTreeNode*)item)];
257 if(!qIdx.isValid())
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500258 return result;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400259
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500260 NSTextField* nameLabel = [result viewWithTag:TAG_NAME];
261 NSTextField* stateLabel = [result viewWithTag:TAG_STATUS];
262 NSButton* checkButton = [result viewWithTag:TAG_CHECK];
263 NSTextField* typeLabel = [result viewWithTag:TAG_TYPE];
Alexandre Lision0ab46082015-08-11 12:10:21 -0400264
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500265 auto account = AccountModel::instance().getAccountByModelIndex(qIdx);
266 auto humanState = account->toHumanStateName();
267
268 [nameLabel setStringValue:account->alias().toNSString()];
269 [stateLabel setStringValue:humanState.toNSString()];
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500270
271 switch (account->protocol()) {
272 case Account::Protocol::SIP:
273 [typeLabel setStringValue:@"SIP"];
274 break;
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500275 case Account::Protocol::RING:
276 [typeLabel setStringValue:@"RING"];
277 break;
278 default:
279 break;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400280 }
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500281
282 switch (account->registrationState()) {
283 case Account::RegistrationState::READY:
284 [stateLabel setTextColor:[NSColor colorWithCalibratedRed:116/255.0 green:179/255.0 blue:93/255.0 alpha:1.0]];
285 break;
286 case Account::RegistrationState::TRYING:
287 [stateLabel setTextColor:[NSColor redColor]];
288 break;
289 case Account::RegistrationState::UNREGISTERED:
290 [stateLabel setTextColor:[NSColor blackColor]];
291 break;
292 case Account::RegistrationState::ERROR:
293 [stateLabel setTextColor:[NSColor redColor]];
294 break;
295 default:
296 [stateLabel setTextColor:[NSColor blackColor]];
297 break;
298 }
299
300 [checkButton setState:qIdx.data(Qt::CheckStateRole).value<BOOL>()];
301
302 return result;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400303}
304
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400305- (void)outlineViewSelectionDidChange:(NSNotification *)notification
306{
307 // ask the tree controller for the current selection
Alexandre Lisionc1f96662016-03-23 17:24:19 -0400308 [self.exportAccountButton setEnabled:[[treeController selectedNodes] count] > 0];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400309 if([[treeController selectedNodes] count] > 0) {
Alexandre Lision81c97212015-06-17 15:51:53 -0400310 auto qIdx = [treeController toQIdx:[treeController selectedNodes][0]];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400311 //Update details view
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400312 auto acc = AccountModel::instance().getAccountByModelIndex(qIdx);
313 AccountModel::instance().selectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400314
Alexandre Lision0c56cb62016-02-12 18:04:08 -0500315 switch (acc->protocol()) {
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400316 case Account::Protocol::SIP:
Alexandre Lision7f3164c2015-06-12 11:45:37 -0400317 [self setupSIPPanels];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400318 break;
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400319 case Account::Protocol::RING:
Alexandre Lision7f3164c2015-06-12 11:45:37 -0400320 [self setupRINGPanels];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400321 break;
322 default:
323 break;
324 }
325
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400326 [self.accountDetailsView setHidden:NO];
327 } else {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400328 AccountModel::instance().selectionModel()->clearCurrentIndex();
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400329 }
330}
331
Alexandre Lisionc1f96662016-03-23 17:24:19 -0400332-(void) didCompleteWithPath:(NSURL*) path Password:(NSString*) password ActionCode:(NSInteger)requestCode
333{
334 switch (requestCode) {
335 case Action::ACTION_EXPORT:
336 if(treeController.selectedNodes.count > 0) {
337 QStringList accounts;
338 for (id item : [treeController selectedNodes]) {
339 QModelIndex accIdx = [treeController toQIdx:item];
340 accounts << AccountModel::instance().getAccountByModelIndex(accIdx)->id();
341
342 }
343 auto finalURL = [path URLByAppendingPathComponent:@"accounts.ring"];
344 [passwordWC showLoading];
345 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
346 int result = AccountModel::instance().exportAccounts(accounts, finalURL.path.UTF8String, password.UTF8String);
347 switch (result) {
348 case 0:
349 [[NSWorkspace sharedWorkspace] selectFile:finalURL.path inFileViewerRootedAtPath:@""];
350 [passwordWC close];
351 break;
352 default:
353 [passwordWC showError:NSLocalizedString(@"An error occured during the export", @"Error shown to the user" )];
354 break;
355 }
356 });
357 }
358 break;
359 case Action::ACTION_IMPORT: {
360 [passwordWC showLoading];
361 SEL sel = @selector(importAccountsWithPath:andPassword:);
362 NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:sel]];
363 [inv setSelector:sel];
364 [inv setTarget:self];
365 //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
366 [inv setArgument:&path atIndex:2];
367 [inv setArgument:&password atIndex:3];
368
369 // Schedule import for next iteration of event loop in order to let us start the loading anim
370 [inv performSelector:@selector(invoke) withObject:nil afterDelay:0];
371
372 }
373 break;
374 default:
375 NSLog(@"Unrecognized action %d", requestCode);
376 break;
377 }
378}
379
380- (void) importAccountsWithPath:(NSURL*) path andPassword:(NSString*) password
381{
382 int result = AccountModel::instance().importAccounts(path.path.UTF8String, password.UTF8String);
383 switch (result) {
384 case 0:
385 [passwordWC close];
386 break;
387 default:
388 [passwordWC showError:NSLocalizedString(@"An error occured during the import", @"Error shown to the user" )];
389 break;
390 }
391}
392
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400393#pragma mark - NSMenuDelegate methods
394
395- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
396{
Alexandre Lision274c22c2016-06-30 11:57:43 -0400397 auto qIdx = AccountModel::instance().protocolModel()->index(index, 0);
Alexandre Lision4de68ce2015-04-24 18:22:49 -0400398 [item setTitle:qIdx.data(Qt::DisplayRole).toString().toNSString()];
Alexandre Lision274c22c2016-06-30 11:57:43 -0400399 if (qIdx == AccountModel::instance().protocolModel()->selectionModel()->currentIndex()) {
400 [protocolList selectItem:item];
401 }
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400402 return YES;
403}
404
405- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
406{
Alexandre Lision274c22c2016-06-30 11:57:43 -0400407 return AccountModel::instance().protocolModel()->rowCount();
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400408}
409
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400410@end