VLCPlaylistViewController.m 13.6 KB
Newer Older
Felix Paul Kühne's avatar
Felix Paul Kühne committed
1 2 3 4 5 6 7
//
//  VLCMasterViewController.m
//  AspenProject
//
//  Created by Felix Paul Kühne on 27.02.13.
//  Copyright (c) 2013 VideoLAN. All rights reserved.
//
8 9
//  Refer to the COPYING file of the official project for license.
//
Felix Paul Kühne's avatar
Felix Paul Kühne committed
10 11

#import "VLCPlaylistViewController.h"
12
#import "VLCMovieViewController.h"
13
#import "VLCPlaylistTableViewCell.h"
14
#import "VLCPlaylistGridView.h"
15
#import "VLCMenuViewController.h"
Romain Goyet's avatar
Romain Goyet committed
16
#import "UINavigationController+Theme.h"
17
#import "NSString+SupportedMedia.h"
18
#import "VLCBugreporter.h"
19
#import "VLCAppDelegate.h"
20
#import "UIBarButtonItem+Theme.h"
Felix Paul Kühne's avatar
Felix Paul Kühne committed
21

22 23 24 25 26
@implementation EmptyLibraryView
@end

@interface VLCPlaylistViewController () <AQGridViewDataSource, AQGridViewDelegate,
                                         UITableViewDataSource, UITableViewDelegate> {
Felix Paul Kühne's avatar
Felix Paul Kühne committed
27 28 29 30 31 32
    NSMutableArray *_foundMedia;
}
@end

@implementation VLCPlaylistViewController

33 34 35
- (void)loadView {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        _tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
36
        _tableView.backgroundColor = [UIColor colorWithWhite:.122 alpha:1.];
37 38 39 40 41 42 43
        _tableView.delegate = self;
        _tableView.dataSource = self;
        self.view = _tableView;
    } else {
        _gridView = [[AQGridView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _gridView.delegate = self;
        _gridView.dataSource = self;
44
        _gridView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"libraryBackground"]];
45 46 47 48 49 50 51 52 53
        self.view = _gridView;
    }

    self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    self.emptyLibraryView = [[[NSBundle mainBundle] loadNibNamed:@"VLCEmptyLibraryView" owner:self options:nil] lastObject];
}

#pragma mark -

Felix Paul Kühne's avatar
Felix Paul Kühne committed
54 55 56 57
- (void)viewDidLoad
{
    [super viewDidLoad];

58
    UIBarButtonItem *addButton = [UIBarButtonItem themedRevealMenuButtonWithTarget:self andSelector:@selector(leftButtonAction:)];
59 60 61 62 63 64 65 66 67 68 69 70

    /* 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)
        addButton.image = [UIImage imageNamed:@"vlc-xmas"];

Felix Paul Kühne's avatar
Felix Paul Kühne committed
71
    self.navigationItem.leftBarButtonItem = addButton;
72

73 74 75 76
    [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
77

78
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
79 80 81
        _gridView.separatorStyle = AQGridViewCellSeparatorStyleEmptySpace;
        _gridView.alwaysBounceVertical = YES;
        _gridView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
82 83
    } else {
        _tableView.rowHeight = [VLCPlaylistTableViewCell heightOfCell];
84
        _tableView.separatorColor = [UIColor colorWithWhite:.122 alpha:1.];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
85
    }
86 87
    self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"title"]];

88 89 90 91 92
    _emptyLibraryView.emptyLibraryLabel.text = NSLocalizedString(@"EMPTY_LIBRARY", @"");
    _emptyLibraryView.emptyLibraryLongDescriptionLabel.lineBreakMode = UILineBreakModeWordWrap;
    _emptyLibraryView.emptyLibraryLongDescriptionLabel.numberOfLines = 0;
    _emptyLibraryView.emptyLibraryLongDescriptionLabel.text = NSLocalizedString(@"EMPTY_LIBRARY_LONG", @"");
    [_emptyLibraryView.emptyLibraryLongDescriptionLabel sizeToFit];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
93 94
}

95 96 97
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
98
    [self _displayEmptyLibraryViewIfNeeded];
99 100
}

101 102
- (void)viewDidAppear:(BOOL)animated
{
103
    [self performSelector:@selector(updateViewContents) withObject:nil afterDelay:.0];
104
    [[MLMediaLibrary sharedMediaLibrary] performSelector:@selector(libraryDidAppear) withObject:nil afterDelay:1.];
105 106

    [super viewDidAppear:animated];
107 108 109 110 111 112 113 114
}

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

115 116 117 118 119 120 121 122 123 124 125
- (BOOL)canBecomeFirstResponder
{
    return YES;
}

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

126 127
- (void)removeMediaObject:(MLFile *)mediaObject
{
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    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];
145 146
    [[MLMediaLibrary sharedMediaLibrary] updateMediaDatabase];
    [self updateViewContents];
147 148 149 150 151 152 153
}

- (void)_displayEmptyLibraryViewIfNeeded
{
    if (_foundMedia.count > 0) {
        if (self.emptyLibraryView.superview)
            [self.emptyLibraryView removeFromSuperview];
154

155
        self.navigationItem.rightBarButtonItem = self.editButtonItem;
156
    } else {
157
        self.emptyLibraryView.frame = self.view.frame;
158
        [self.view addSubview:self.emptyLibraryView];
159
        self.navigationItem.rightBarButtonItem = nil;
160
    }
161 162 163 164 165

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        _tableView.separatorStyle = (_foundMedia.count > 0)? UITableViewCellSeparatorStyleSingleLine:
                                                             UITableViewCellSeparatorStyleNone;
    }
166 167
}

168
- (void)updateViewContents
Felix Paul Kühne's avatar
Felix Paul Kühne committed
169
{
Felix Paul Kühne's avatar
Felix Paul Kühne committed
170
    _foundMedia = [NSMutableArray arrayWithArray:[MLFile allFiles]];
171

172
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
173
        [self.tableView reloadData];
174
    else {
175
        [self.gridView reloadData];
176
        [self.gridView setNeedsLayout];
177
    }
178 179

    [self _displayEmptyLibraryViewIfNeeded];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
180 181
}

182 183 184

#pragma mark - Table View

Felix Paul Kühne's avatar
Felix Paul Kühne committed
185 186 187 188 189 190 191 192 193 194 195 196 197
- (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
{
198
    static NSString *CellIdentifier = @"PlaylistCell";
Felix Paul Kühne's avatar
Felix Paul Kühne committed
199

200
    VLCPlaylistTableViewCell *cell = (VLCPlaylistTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
201
    if (cell == nil)
202
        cell = [VLCPlaylistTableViewCell cellWithReuseIdentifier:CellIdentifier];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
203

204 205
    NSInteger row = indexPath.row;
    cell.mediaObject = _foundMedia[row];
206

Felix Paul Kühne's avatar
Felix Paul Kühne committed
207 208 209
    return cell;
}

210 211 212 213 214
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.backgroundColor = (indexPath.row % 2 == 0)? [UIColor blackColor]: [UIColor colorWithWhite:.122 alpha:1.];
}

Felix Paul Kühne's avatar
Felix Paul Kühne committed
215 216 217 218 219 220 221
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
222 223
    if (editingStyle == UITableViewCellEditingStyleDelete)
        [self removeMediaObject: _foundMedia[indexPath.row]];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
224 225
}

226
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Felix Paul Kühne's avatar
Felix Paul Kühne committed
227
{
228
    MLFile *mediaObject = _foundMedia[indexPath.row];
229
    if (!self.movieViewController)
230
        self.movieViewController = [[VLCMovieViewController alloc] initWithNibName:nil bundle:nil];
231

232 233
    self.movieViewController.mediaItem = mediaObject;
    [self.navigationController pushViewController:self.movieViewController animated:YES];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
234 235
}

236 237
#pragma mark - AQGridView
- (NSUInteger)numberOfItemsInGridView:(AQGridView *)gridView
Felix Paul Kühne's avatar
Felix Paul Kühne committed
238
{
239
    return _foundMedia.count;
Felix Paul Kühne's avatar
Felix Paul Kühne committed
240 241
}

242
- (AQGridViewCell *)gridView:(AQGridView *)gridView cellForItemAtIndex:(NSUInteger)index
Felix Paul Kühne's avatar
Felix Paul Kühne committed
243
{
244
    static NSString *AQCellIdentifier = @"AQPlaylistCell";
245

246
    VLCPlaylistGridView *cell = (VLCPlaylistGridView *)[gridView dequeueReusableCellWithIdentifier:AQCellIdentifier];
247
    if (cell == nil) {
248
        cell = [[[NSBundle mainBundle] loadNibNamed:@"VLCPlaylistGridView" owner:self options:nil] lastObject];
249
        cell.selectionStyle = AQGridViewCellSelectionStyleNone;
250
        cell.gridView = gridView;
251 252
    }

253
    cell.mediaObject = _foundMedia[index];
254 255 256 257 258 259

    return cell;
}

- (CGSize)portraitGridCellSizeForGridView:(AQGridView *)gridView
{
260
    return [VLCPlaylistGridView preferredSize];
261 262 263 264
}

- (void)gridView:(AQGridView *)gridView didSelectItemAtIndex:(NSUInteger)index
{
265 266
    [self.gridView deselectItemAtIndex:index animated:YES];

267
    MLFile *mediaObject = _foundMedia[index];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
268
    if (!self.movieViewController)
269
        self.movieViewController = [[VLCMovieViewController alloc] initWithNibName:nil bundle:nil];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
270

271 272
    self.movieViewController.mediaItem = mediaObject;
    [self.navigationController pushViewController:self.movieViewController animated:YES];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
273 274
}

275 276 277 278 279 280
- (void)gridView:(AQGridView *)aGridView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndex:(NSUInteger)index
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
        [self removeMediaObject: _foundMedia[index]];
}

281
#pragma mark - UI implementation
282 283
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
284
    [super setEditing:editing animated:animated];
285

Felix Paul Kühne's avatar
Felix Paul Kühne committed
286
    UIBarButtonItem *editButton = self.editButtonItem;
287 288
    NSString *editImage = editing? @"doneButton": @"button";
    NSString *editImageHighlight = editing? @"doneButtonHighlight": @"buttonHighlight";
Felix Paul Kühne's avatar
Felix Paul Kühne committed
289
    [editButton setBackgroundImage:[UIImage imageNamed:editImage] forState:UIControlStateNormal
290
                                 barMetrics:UIBarMetricsDefault];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
291
    [editButton setBackgroundImage:[UIImage imageNamed:editImageHighlight]
292
                                   forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
293 294
    [editButton setTitleTextAttributes: editing ? @{UITextAttributeTextShadowColor : [UIColor whiteColor], UITextAttributeTextColor : [UIColor blackColor]} : @{UITextAttributeTextShadowColor : [UIColor colorWithWhite:0. alpha:.37], UITextAttributeTextColor : [UIColor whiteColor]} forState:UIControlStateNormal];

295
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
296
        [self.gridView setEditing:editing];
297
    else
298
        [self.tableView setEditing:editing animated:YES];
299 300
}

301 302
- (void)initMenuViewController
{
303
    return;
304 305 306 307 308 309 310 311
    VLCMenuViewController *menuViewController = [[VLCMenuViewController alloc] initWithNibName:nil bundle:nil];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:menuViewController];
    [navigationController loadTheme];
    self.menuViewController = navigationController;
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        navigationController.navigationBarHidden = YES;
}

312
- (IBAction)leftButtonAction:(id)sender
313
{
314
    [[(VLCAppDelegate*)[UIApplication sharedApplication].delegate revealController] toggleSidebar:![(VLCAppDelegate*)[UIApplication sharedApplication].delegate revealController].sidebarShowing duration:kGHRevealSidebarDefaultAnimationDuration];
315 316
}

317
/* deprecated in iOS 6 */
318 319
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
320 321 322 323
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        return YES;

    return (_foundMedia.count > 0) || toInterfaceOrientation == UIInterfaceOrientationPortrait;
324 325
}

326 327
// 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)
328 329
/* introduced in iOS 6 */
- (NSUInteger)supportedInterfaceOrientations {
330 331 332 333 334
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        return UIInterfaceOrientationMaskAll;

    return (_foundMedia.count > 0)? UIInterfaceOrientationMaskAllButUpsideDown:
                                    UIInterfaceOrientationMaskPortrait;
335 336 337 338
}

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

342
#pragma mark - coin coin
343

344 345 346
- (void)openMovieFromURL:(NSURL *)url
{
    if (!self.movieViewController)
347
        self.movieViewController = [[VLCMovieViewController alloc] initWithNibName:nil bundle:nil];
348

349 350 351
    if (self.navigationController.topViewController != self.movieViewController)
        [self.navigationController pushViewController:self.movieViewController animated:YES];

352
    self.movieViewController.url = url;
353 354
}

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