VLCPlaylistViewController.m 24.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
/*****************************************************************************
 * VLCPlaylistViewController.m
 * VLC for iOS
 *****************************************************************************
 * Copyright (c) 2013 VideoLAN. All rights reserved.
 * $Id$
 *
 * Authors: Felix Paul Kühne <fkuehne # videolan.org>
 *          Gleb Pinigin <gpinigin # gmail.com>
 *          Tamas Timar <ttimar.vlc # gmail.com>
 *
 * Refer to the COPYING file of the official project for license.
 *****************************************************************************/
Felix Paul Kühne's avatar
Felix Paul Kühne committed
14
15

#import "VLCPlaylistViewController.h"
16
#import "VLCMovieViewController.h"
17
#import "VLCPlaylistTableViewCell.h"
18
#import "VLCPlaylistCollectionViewCell.h"
Romain Goyet's avatar
Romain Goyet committed
19
#import "UINavigationController+Theme.h"
20
#import "NSString+SupportedMedia.h"
21
#import "VLCBugreporter.h"
22
#import "VLCAppDelegate.h"
23
#import "UIBarButtonItem+Theme.h"
24
#import "VLCFirstStepsViewController.h"
25

26
@implementation EmptyLibraryView
27
28
29
30
31
32
33
34
35
36

- (IBAction)learnMore:(id)sender
{
    UIViewController *firstStepsVC = [[VLCFirstStepsViewController alloc] initWithNibName:nil bundle:nil];
    UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:firstStepsVC];
    navCon.modalPresentationStyle = UIModalPresentationFormSheet;
    [navCon loadTheme];
    [self.window.rootViewController presentViewController:navCon animated:YES completion:nil];
}

37
38
@end

Felix Paul Kühne's avatar
Felix Paul Kühne committed
39
@interface VLCPlaylistViewController () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UITableViewDataSource, UITableViewDelegate, MLMediaLibrary> {
Felix Paul Kühne's avatar
Felix Paul Kühne committed
40
    NSMutableArray *_foundMedia;
41
    VLCLibraryMode _libraryMode;
42
    UIBarButtonItem *_menuButton;
Felix Paul Kühne's avatar
Felix Paul Kühne committed
43
}
44
45

@property (nonatomic, strong) UITableView *tableView;
46
@property (nonatomic, strong) UICollectionView *collectionView;
47
48
@property (nonatomic, strong) EmptyLibraryView *emptyLibraryView;

Felix Paul Kühne's avatar
Felix Paul Kühne committed
49
50
51
52
@end

@implementation VLCPlaylistViewController

53
54
55
- (void)loadView {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        _tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
56
        _tableView.backgroundColor = [UIColor colorWithWhite:.122 alpha:1.];
57
58
        _tableView.rowHeight = [VLCPlaylistTableViewCell heightOfCell];
        _tableView.separatorColor = [UIColor colorWithWhite:.122 alpha:1.];
59
60
        _tableView.delegate = self;
        _tableView.dataSource = self;
61
        _tableView.opaque = YES;
62
        self.view = _tableView;
63

Felix Paul Kühne's avatar
Felix Paul Kühne committed
64
        if (SYSTEM_RUNS_IOS7_OR_LATER) {
65
66
67
            UILongPressGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(tableViewLongTouchGestureAction:)];
            [self.view addGestureRecognizer:gestureRecognizer];
        }
68
    } else {
Felix Paul Kühne's avatar
Felix Paul Kühne committed
69
70
71
72
73
74
75
        UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];

        _collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:flowLayout];
        _collectionView.alwaysBounceVertical = YES;
        _collectionView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
        _collectionView.delegate = self;
        _collectionView.dataSource = self;
76
77
        _collectionView.opaque = YES;
        _collectionView.backgroundColor = [UIColor colorWithWhite:.122 alpha:1.];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
78
79
        self.view = _collectionView;

80
        if (SYSTEM_RUNS_IOS7_OR_LATER)
81
            [_collectionView registerNib:[UINib nibWithNibName:@"VLCFuturePlaylistCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"PlaylistCell"];
82
        else
83
            [_collectionView registerNib:[UINib nibWithNibName:@"VLCPlaylistCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"PlaylistCell"];
84
        self.view.backgroundColor = [UIColor colorWithWhite:.122 alpha:1.];
85
86
    }

87
    _libraryMode = VLCLibraryModeAllFiles;
88

89
90
    self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    self.emptyLibraryView = [[[NSBundle mainBundle] loadNibNamed:@"VLCEmptyLibraryView" owner:self options:nil] lastObject];
91
    _emptyLibraryView.emptyLibraryLongDescriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;
92
    _emptyLibraryView.emptyLibraryLongDescriptionLabel.numberOfLines = 0;
93
94
95
96
}

#pragma mark -

Felix Paul Kühne's avatar
Felix Paul Kühne committed
97
98
99
- (void)viewDidLoad
{
    [super viewDidLoad];
100
    self.title = NSLocalizedString(@"LIBRARY_ALL_FILES", @"");
101
    _menuButton = [UIBarButtonItem themedRevealMenuButtonWithTarget:self andSelector:@selector(leftButtonAction:)];
102
103
104
105
106
107
108
109
110
111

    /* After day 354 of the year, the usual VLC cone is replaced by another cone
     * wearing a Father Xmas hat.
     * Note: this icon doesn't represent an endorsement of The Coca-Cola Company
     * and should not be confused with the idea of religious statements or propagation there off
     */
    NSCalendar *gregorian =
    [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSUInteger dayOfYear = [gregorian ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];
    if (dayOfYear >= 354)
112
        _menuButton.image = [UIImage imageNamed:@"vlc-xmas"];
113

114
    self.navigationItem.leftBarButtonItem = _menuButton;
115

Felix Paul Kühne's avatar
Felix Paul Kühne committed
116
    if (SYSTEM_RUNS_IOS7_OR_LATER)
117
118
119
120
121
122
123
        self.editButtonItem.tintColor = [UIColor whiteColor];
    else {
        [self.editButtonItem setBackgroundImage:[UIImage imageNamed:@"button"]
                                       forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
        [self.editButtonItem setBackgroundImage:[UIImage imageNamed:@"buttonHighlight"]
                                       forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
    }
Felix Paul Kühne's avatar
Felix Paul Kühne committed
124

125
126
127
    _emptyLibraryView.emptyLibraryLabel.text = NSLocalizedString(@"EMPTY_LIBRARY", @"");
    _emptyLibraryView.emptyLibraryLongDescriptionLabel.text = NSLocalizedString(@"EMPTY_LIBRARY_LONG", @"");
    [_emptyLibraryView.emptyLibraryLongDescriptionLabel sizeToFit];
128

129
130
    [self setToolbarItems:@[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteMultipleFiles)]]];

131
132
    if (SYSTEM_RUNS_IOS7_OR_LATER)
        [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
Felix Paul Kühne's avatar
Felix Paul Kühne committed
133
134
}

135
136
137
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
138
    [self.collectionView.collectionViewLayout invalidateLayout];
139
    [self _displayEmptyLibraryViewIfNeeded];
140
141
}

142
143
- (void)viewDidAppear:(BOOL)animated
{
144
145
    [super viewDidAppear:animated];

146
147
148
    if ([[MLMediaLibrary sharedMediaLibrary] libraryNeedsUpgrade]) {
        self.navigationItem.rightBarButtonItem = nil;
        self.navigationItem.leftBarButtonItem = nil;
Gleb Pinigin's avatar
Gleb Pinigin committed
149
        self.title = @"";
150
151
152
        self.emptyLibraryView.emptyLibraryLabel.text = NSLocalizedString(@"UPGRADING_LIBRARY", @"");
        self.emptyLibraryView.emptyLibraryLongDescriptionLabel.hidden = YES;
        [self.emptyLibraryView.activityIndicator startAnimating];
Gleb Pinigin's avatar
Gleb Pinigin committed
153
        self.emptyLibraryView.frame = self.view.bounds;
154
155
156
157
158
159
160
        [self.view addSubview:self.emptyLibraryView];

        [[MLMediaLibrary sharedMediaLibrary] setDelegate: self];
        [[MLMediaLibrary sharedMediaLibrary] performSelectorInBackground:@selector(upgradeLibrary) withObject:nil];
        return;
    }

161
    if (_foundMedia.count < 1)
162
        [self updateViewContents];
163
164
165
166
167
168
169
170
171
    [[MLMediaLibrary sharedMediaLibrary] performSelector:@selector(libraryDidAppear) withObject:nil afterDelay:1.];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [[MLMediaLibrary sharedMediaLibrary] libraryDidDisappear];
}

172
173
174
175
176
177
178
179
180
181
182
- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (motion == UIEventSubtypeMotionShake)
        [[VLCBugreporter sharedInstance] handleBugreportRequest];
}

183
184
185
- (void)openMediaObject:(NSManagedObject *)mediaObject
{
    if ([mediaObject isKindOfClass:[MLAlbum class]]) {
186
        _foundMedia = [NSMutableArray arrayWithArray:[(MLAlbum *)mediaObject sortedTracks]];
187
        self.navigationItem.leftBarButtonItem = [UIBarButtonItem themedBackButtonWithTarget:self andSelector:@selector(backToAllItems:)];
188
189
190
191
        if (_libraryMode == VLCLibraryModeAllFiles)
            self.navigationItem.leftBarButtonItem.title = NSLocalizedString(@"BUTTON_BACK", @"");
        else
            [self.navigationItem.leftBarButtonItem setTitle:NSLocalizedString(@"LIBRARY_MUSIC", @"")];
192
193
194
        self.title = [(MLAlbum*)mediaObject name];
        [self reloadViews];
    } else if ([mediaObject isKindOfClass:[MLShow class]]) {
195
        _foundMedia = [NSMutableArray arrayWithArray:[(MLShow *)mediaObject sortedEpisodes]];
196
        self.navigationItem.leftBarButtonItem = [UIBarButtonItem themedBackButtonWithTarget:self andSelector:@selector(backToAllItems:)];
197
198
199
200
        if (_libraryMode == VLCLibraryModeAllFiles)
            self.navigationItem.leftBarButtonItem.title = NSLocalizedString(@"BUTTON_BACK", @"");
        else
            [self.navigationItem.leftBarButtonItem setTitle:NSLocalizedString(@"LIBRARY_SERIES", @"")];
201
202
        self.title = [(MLShow*)mediaObject name];
        [self reloadViews];
203
204
    } else
        [(VLCAppDelegate*)[UIApplication sharedApplication].delegate openMediaFromManagedObject:mediaObject];
205
206
}

207
- (void)removeMediaObject:(id)managedObject updateDatabase:(BOOL)updateDB
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
{
        // delete all tracks from an album
    if ([managedObject isKindOfClass:[MLAlbum class]]) {
        MLAlbum *album = managedObject;
        NSSet *iterAlbumTrack = [NSSet setWithSet:album.tracks];

        for (MLAlbumTrack *track in iterAlbumTrack) {
            NSSet *iterFiles = [NSSet setWithSet:track.files];

            for (MLFile *file in iterFiles)
                [self _deleteMediaObject:file];
        }
        // delete all episodes from a show
    } else if ([managedObject isKindOfClass:[MLShow class]]) {
        MLShow *show = managedObject;
        NSSet *iterShowEpisodes = [NSSet setWithSet:show.episodes];

        for (MLShowEpisode *episode in iterShowEpisodes) {
            NSSet *iterFiles = [NSSet setWithSet:episode.files];

            for (MLFile *file in iterFiles)
                [self _deleteMediaObject:file];
        }
        // delete all files from an episode
    } else if ([managedObject isKindOfClass:[MLShowEpisode class]]) {
        MLShowEpisode *episode = managedObject;
        NSSet *iterFiles = [NSSet setWithSet:episode.files];

        for (MLFile *file in iterFiles)
            [self _deleteMediaObject:file];
        // delete all files from a track
    } else if ([managedObject isKindOfClass:[MLAlbumTrack class]]) {
        MLAlbumTrack *track = managedObject;
        NSSet *iterFiles = [NSSet setWithSet:track.files];

        for (MLFile *file in iterFiles)
            [self _deleteMediaObject:file];
245
246
    } else
        [self _deleteMediaObject:managedObject];
247

248
249
250
251
    if (updateDB) {
        [[MLMediaLibrary sharedMediaLibrary] updateMediaDatabase];
        [self updateViewContents];
    }
252
253
254
}

- (void)_deleteMediaObject:(MLFile *)mediaObject
255
{
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *folderLocation = [[[NSURL URLWithString:mediaObject.url] path] stringByDeletingLastPathComponent];
    NSArray *allfiles = [fileManager contentsOfDirectoryAtPath:folderLocation error:nil];
    NSString *fileName = [[[[NSURL URLWithString:mediaObject.url] path] lastPathComponent] stringByDeletingPathExtension];
    NSIndexSet *indexSet = [allfiles indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
       return ([obj rangeOfString:fileName].location != NSNotFound);
    }];
    unsigned int count = indexSet.count;
    NSString *additionalFilePath;
    NSUInteger currentIndex = [indexSet firstIndex];
    for (unsigned int x = 0; x < count; x++) {
        additionalFilePath = allfiles[currentIndex];
        if ([additionalFilePath isSupportedSubtitleFormat])
            [fileManager removeItemAtPath:[folderLocation stringByAppendingPathComponent:additionalFilePath] error:nil];
        currentIndex = [indexSet indexGreaterThanIndex:currentIndex];
    }
    [fileManager removeItemAtPath:[[NSURL URLWithString:mediaObject.url] path] error:nil];
273
274
275
276
}

- (void)_displayEmptyLibraryViewIfNeeded
{
277
278
279
    if (self.emptyLibraryView.superview)
        [self.emptyLibraryView removeFromSuperview];

Gleb Pinigin's avatar
Gleb Pinigin committed
280
281
    if (_foundMedia.count == 0) {
        self.emptyLibraryView.frame = self.view.bounds;
282
        [self.view addSubview:self.emptyLibraryView];
283
        self.navigationItem.rightBarButtonItem = nil;
284
285
    } else
        self.navigationItem.rightBarButtonItem = self.editButtonItem;
286
287
288
289

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        _tableView.separatorStyle = (_foundMedia.count > 0)? UITableViewCellSeparatorStyleSingleLine:
                                                             UITableViewCellSeparatorStyleNone;
290
291
    } else
        [self.collectionView.collectionViewLayout invalidateLayout];
292
293
}

294
295
- (void)libraryUpgradeComplete
{
Gleb Pinigin's avatar
Gleb Pinigin committed
296
297
    self.title = NSLocalizedString(@"LIBRARY_ALL_FILES", @"");
    self.navigationItem.leftBarButtonItem = _menuButton;
298
299
300
301
302
    self.emptyLibraryView.emptyLibraryLongDescriptionLabel.hidden = NO;
    self.emptyLibraryView.emptyLibraryLabel.text = NSLocalizedString(@"EMPTY_LIBRARY", @"");
    [self.emptyLibraryView.activityIndicator stopAnimating];
    [self.emptyLibraryView removeFromSuperview];

303
304
305
306
307
308
    [self updateViewContents];
}

- (void)libraryWasUpdated
{
    [self updateViewContents];
309
310
}

311
- (void)updateViewContents
Felix Paul Kühne's avatar
Felix Paul Kühne committed
312
{
313
314
315
316
    _foundMedia = [[NSMutableArray alloc] init];

    /* add all albums */
    if (_libraryMode != VLCLibraryModeAllSeries) {
317
        NSArray *rawAlbums = [MLAlbum allAlbums];
318
        for (MLAlbum *album in rawAlbums) {
Carola's avatar
Carola committed
319
            if (album.name.length > 0 && album.tracks.count > 1)
320
321
                [_foundMedia addObject:album];
        }
322
323
324
325
326
    }
    if (_libraryMode == VLCLibraryModeAllAlbums) {
        [self reloadViews];
        return;
    }
327

328
329
330
    /* add all shows */
    NSArray *rawShows = [MLShow allShows];
    for (MLShow *show in rawShows) {
Carola's avatar
Carola committed
331
        if (show.name.length > 0 && show.episodes.count > 1)
332
333
334
335
336
337
338
339
340
341
342
343
            [_foundMedia addObject:show];
    }
    if (_libraryMode == VLCLibraryModeAllSeries) {
        [self reloadViews];
        return;
    }

    /* add all remaining files */
    NSArray *allFiles = [MLFile allFiles];
    for (MLFile *file in allFiles) {
        if (!file.isShowEpisode && !file.isAlbumTrack)
            [_foundMedia addObject:file];
344
345
346
347
348
349
350
        else if (file.isShowEpisode) {
            if (file.showEpisode.show.episodes.count < 2)
                [_foundMedia addObject:file];
        } else if (file.isAlbumTrack) {
            if (file.albumTrack.album.tracks.count < 2)
                [_foundMedia addObject:file];
        }
351
    }
352

353
    [self reloadViews];
354
}
355

356
- (void)reloadViews
357
{
358
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
359
        [self.tableView reloadData];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
360
361
    else
        [self.collectionView reloadData];
362
363

    [self _displayEmptyLibraryViewIfNeeded];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
364
365
}

366
367
#pragma mark - Table View

Felix Paul Kühne's avatar
Felix Paul Kühne committed
368
369
370
371
372
373
374
375
376
377
378
379
380
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _foundMedia.count;
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
381
    static NSString *CellIdentifier = @"PlaylistCell";
Felix Paul Kühne's avatar
Felix Paul Kühne committed
382

383
    VLCPlaylistTableViewCell *cell = (VLCPlaylistTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
384
    if (cell == nil)
385
        cell = [VLCPlaylistTableViewCell cellWithReuseIdentifier:CellIdentifier];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
386

387
388
    NSInteger row = indexPath.row;
    cell.mediaObject = _foundMedia[row];
389

Felix Paul Kühne's avatar
Felix Paul Kühne committed
390
391
392
    return cell;
}

393
394
395
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.backgroundColor = (indexPath.row % 2 == 0)? [UIColor blackColor]: [UIColor colorWithWhite:.122 alpha:1.];
396
    cell.multipleSelectionBackgroundView.backgroundColor = cell.backgroundColor;
397
398
}

Felix Paul Kühne's avatar
Felix Paul Kühne committed
399
400
401
402
403
404
405
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
406
    if (editingStyle == UITableViewCellEditingStyleDelete)
407
        [self removeMediaObject: _foundMedia[indexPath.row] updateDatabase:YES];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
408
409
}

410
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Felix Paul Kühne's avatar
Felix Paul Kühne committed
411
{
412
413
414
    if (tableView.isEditing)
        return;

415
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
416
417
    NSManagedObject *selectedObject = _foundMedia[indexPath.row];
    [self openMediaObject:selectedObject];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
418
419
}

420
421
422
423
424
425
426
427
428
#pragma mark - table view gestures
- (void)tableViewLongTouchGestureAction:(UIGestureRecognizer *)recognizer
{
    NSIndexPath *path = [(UITableView *)self.view indexPathForRowAtPoint:[recognizer locationInView:self.view]];
    UITableViewCell *cell = [(UITableView *)self.view cellForRowAtIndexPath:path];

    CGRect frame = cell.frame;
    if (frame.size.height > 90.)
        frame.size.height = 90.;
429
    else if (recognizer.state == UIGestureRecognizerStateBegan)
430
431
432
433
434
435
436
437
        frame.size.height = 180;

    void (^animationBlock)() = ^() {
        cell.frame = frame;
    };

    void (^completionBlock)(BOOL finished) = ^(BOOL finished) {
        cell.frame = frame;
438
        [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionNone animated:YES];
439
440
441
442
443
444
    };

    NSTimeInterval animationDuration = .2;
    [UIView animateWithDuration:animationDuration animations:animationBlock completion:completionBlock];
 }

445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
#pragma mark - Collection View
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return _foundMedia.count;
}

- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    VLCPlaylistCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PlaylistCell" forIndexPath:indexPath];
    cell.mediaObject = _foundMedia[indexPath.row];
    cell.collectionView = _collectionView;

    [cell setEditing:self.editing animated:NO];

    return cell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
464
    if (SYSTEM_RUNS_IOS7_OR_LATER) {
465
        if (UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation))
466
467
468
469
            return CGSizeMake(341., 190.);
        else
            return CGSizeMake(384., 216.);
    }
470

471
472
473
474
475
    return CGSizeMake(298.0, 220.0);
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
476
477
    if (SYSTEM_RUNS_IOS7_OR_LATER)
        return UIEdgeInsetsMake(0., 0., 0., 0.);
478
479
480
    return UIEdgeInsetsMake(0.0, 34.0, 0.0, 34.0);
}

481
482
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
483
484
    if (SYSTEM_RUNS_IOS7_OR_LATER)
        return 0.;
485
486
487
488
489
    return 10.0;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
490
491
    if (SYSTEM_RUNS_IOS7_OR_LATER)
        return 0.;
492
493
494
    return 10.0;
}

495
496
497
498
499
500
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObject *selectedObject = _foundMedia[indexPath.row];
    [self openMediaObject:selectedObject];
}

501
#pragma mark - UI implementation
502
503
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
504
    [super setEditing:editing animated:animated];
505

Felix Paul Kühne's avatar
Felix Paul Kühne committed
506
    UIBarButtonItem *editButton = self.editButtonItem;
507
508
    NSString *editImage = editing? @"doneButton": @"button";
    NSString *editImageHighlight = editing? @"doneButtonHighlight": @"buttonHighlight";
Felix Paul Kühne's avatar
Felix Paul Kühne committed
509
    if (SYSTEM_RUNS_IOS7_OR_LATER)
510
511
512
513
514
515
516
517
        editButton.tintColor = [UIColor whiteColor];
    else {
        [editButton setBackgroundImage:[UIImage imageNamed:editImage] forState:UIControlStateNormal
                                     barMetrics:UIBarMetricsDefault];
        [editButton setBackgroundImage:[UIImage imageNamed:editImageHighlight]
                                       forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
        [editButton setTitleTextAttributes: editing ? @{UITextAttributeTextShadowColor : [UIColor whiteColor], UITextAttributeTextColor : [UIColor blackColor]} : @{UITextAttributeTextShadowColor : [UIColor colorWithWhite:0. alpha:.37], UITextAttributeTextColor : [UIColor whiteColor]} forState:UIControlStateNormal];
    }
Felix Paul Kühne's avatar
Felix Paul Kühne committed
518

519
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
Felix Paul Kühne's avatar
Felix Paul Kühne committed
520
        NSArray *visibleCells = self.collectionView.visibleCells;
521

Felix Paul Kühne's avatar
Felix Paul Kühne committed
522
523
        [visibleCells enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            VLCPlaylistCollectionViewCell *aCell = (VLCPlaylistCollectionViewCell*)obj;
524

Felix Paul Kühne's avatar
Felix Paul Kühne committed
525
526
            [aCell setEditing:editing animated:animated];
        }];
527
528
529
    } else {
        self.navigationController.toolbarHidden = !editing;
        self.tableView.allowsMultipleSelectionDuringEditing = editing;
530
        [self.tableView setEditing:editing animated:YES];
531
532
        [self.editButtonItem setTitle:editing ? NSLocalizedString(@"BUTTON_CANCEL",@"") : NSLocalizedString(@"BUTTON_EDIT", @"")];
    }
533
534
}

535
536
537
538
539
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleDelete;
}

540
- (IBAction)leftButtonAction:(id)sender
541
{
542
    [[(VLCAppDelegate*)[UIApplication sharedApplication].delegate revealController] toggleSidebar:![(VLCAppDelegate*)[UIApplication sharedApplication].delegate revealController].sidebarShowing duration:kGHRevealSidebarDefaultAnimationDuration];
543
544
545

    if (self.isEditing)
        [self setEditing:NO animated:YES];
546
547
}

548
549
550
551
552
553
- (IBAction)backToAllItems:(id)sender
{
    self.navigationItem.leftBarButtonItem = _menuButton;
    [self setLibraryMode:_libraryMode];
}

554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
- (void)deleteMultipleFiles
{
    [self.tableView beginUpdates];

    NSArray *indexPaths = [self.tableView indexPathsForSelectedRows];
    NSUInteger count = indexPaths.count;
    NSMutableArray *objects = [[NSMutableArray alloc] initWithCapacity:count];

    for (NSUInteger x = 0; x < count; x++)
        [objects addObject:_foundMedia[[indexPaths[x] row]]];

    for (NSUInteger x = 0; x < count; x++)
        [self removeMediaObject:objects[x] updateDatabase:NO];

    [self.tableView endUpdates];

    [[MLMediaLibrary sharedMediaLibrary] updateMediaDatabase];
    [self updateViewContents];

    [self setEditing:NO animated:YES];
}

576
#pragma mark - coin coin
577

578
- (void)setLibraryMode:(VLCLibraryMode)mode
579
580
{
    _libraryMode = mode;
581

582
    if (_libraryMode == VLCLibraryModeAllAlbums)
583
        self.title = NSLocalizedString(@"LIBRARY_MUSIC", @"");
584
    else if( _libraryMode == VLCLibraryModeAllSeries)
585
586
587
588
        self.title = NSLocalizedString(@"LIBRARY_SERIES", @"");
    else
        self.title = NSLocalizedString(@"LIBRARY_ALL_FILES", @"");

589
    [self updateViewContents];
590
591
}

Gleb Pinigin's avatar
Gleb Pinigin committed
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
#pragma mark - autorotation

// RootController is responsible for supporting interface orientation(iOS6.0+), i.e. navigation controller
// so this will not work as intended without "voodoo magic"(UINavigationController category, subclassing, etc)
/* introduced in iOS 6 */
- (NSUInteger)supportedInterfaceOrientations {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        return UIInterfaceOrientationMaskAll;

    return (_foundMedia.count > 0)? UIInterfaceOrientationMaskAllButUpsideDown:
    UIInterfaceOrientationMaskPortrait;
}

/* introduced in iOS 6 */
- (BOOL)shouldAutorotate {
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (_foundMedia.count > 0);
}

610
611
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
612
613
614

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        [self.collectionView.collectionViewLayout invalidateLayout];
615
616
}

Felix Paul Kühne's avatar
Felix Paul Kühne committed
617
@end