playlist.m 18.5 KB
Newer Older
1
2
3
/*****************************************************************************
 * playlist.m: MacOS X interface plugin
 *****************************************************************************
4
 * Copyright (C) 2002-2003 VideoLAN
5
 * $Id: playlist.m,v 1.41 2003/11/17 14:11:05 bigben Exp $
6
7
 *
 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
hartman's avatar
hartman committed
8
 *          Derk-Jan Hartman <thedj@users.sourceforge.net>
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include <stdlib.h>                                      /* malloc(), free() */
#include <sys/param.h>                                    /* for MAXPATHLEN */
#include <string.h>
31
#include <math.h>
hartman's avatar
hartman committed
32
#include <sys/mount.h>
bigben's avatar
bigben committed
33
#include <vlc_keys.h>
34
35
36

#include "intf.h"
#include "playlist.h"
hartman's avatar
hartman committed
37
#include "controls.h"
38
39
40
41
42
43
44
45

/*****************************************************************************
 * VLCPlaylistView implementation 
 *****************************************************************************/
@implementation VLCPlaylistView

- (NSMenu *)menuForEvent:(NSEvent *)o_event
{
Jon Lech Johansen's avatar
Jon Lech Johansen committed
46
    return( [[self delegate] menuForEvent: o_event] );
47
48
}

49
50
51
- (void)keyDown:(NSEvent *)o_event
{
    unichar key = 0;
hartman's avatar
hartman committed
52
53
54
55
    int i, c, i_row;
    NSMutableArray *o_to_delete;
    NSNumber *o_number;
    
56
57
    playlist_t * p_playlist;
    intf_thread_t * p_intf = [NSApp getIntf];
58
59
60
61
62
63

    if( [[o_event characters] length] )
    {
        key = [[o_event characters] characterAtIndex: 0];
    }

64
65
    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                          FIND_ANYWHERE );
66
67
    
    if ( p_playlist == NULL )
68
    {
69
        return;
70
    }
71
    
72
73
    switch( key )
    {
74
75
76
77
        case NSDeleteCharacter:
        case NSDeleteFunctionKey:
        case NSDeleteCharFunctionKey:
        case NSBackspaceCharacter:
hartman's avatar
hartman committed
78
79
80
81
82
83
84
            o_to_delete = [NSMutableArray arrayWithArray:[[self selectedRowEnumerator] allObjects]];
            c = [o_to_delete count];
            
            for( i = 0; i < c; i++ ) {
                o_number = [o_to_delete lastObject];
                i_row = [o_number intValue];
                
85
86
87
88
                if( p_playlist->i_index == i_row && p_playlist->i_status )
                {
                    playlist_Stop( p_playlist );
                }
hartman's avatar
hartman committed
89
                [o_to_delete removeObject: o_number];
90
                [self deselectRow: i_row];
hartman's avatar
hartman committed
91
                playlist_Delete( p_playlist, i_row );
92
93
94
95
            }
            [self reloadData];
            break;
            
96
97
98
99
        default:
            [super keyDown: o_event];
            break;
    }
100
101
102
103
104

    if( p_playlist != NULL )
    {
        vlc_object_release( p_playlist );
    }
105
106
}

107
108
109
110
111
112
113
@end

/*****************************************************************************
 * VLCPlaylist implementation 
 *****************************************************************************/
@implementation VLCPlaylist

hartman's avatar
hartman committed
114
115
116
117
118
119
120
121
122
123
- (id)init
{
    self = [super init];
    if ( self !=nil )
    {
        i_moveRow = -1;
    }
    return self;
}

124
125
126
127
128
129
- (void)awakeFromNib
{
    [o_table_view setTarget: self];
    [o_table_view setDelegate: self];
    [o_table_view setDataSource: self];

Jon Lech Johansen's avatar
Jon Lech Johansen committed
130
    [o_table_view setDoubleAction: @selector(playItem:)];
131
132
133
134

    [o_table_view registerForDraggedTypes: 
        [NSArray arrayWithObjects: NSFilenamesPboardType, nil]];

hartman's avatar
hartman committed
135
136
    [o_window setExcludedFromWindowsMenu: TRUE];

137
    [o_window setTitle: _NS("Playlist")];
138
    [o_mi_save_playlist setTitle: _NS("Save Playlist...")];
Jon Lech Johansen's avatar
Jon Lech Johansen committed
139
140
141
    [o_mi_play setTitle: _NS("Play")];
    [o_mi_delete setTitle: _NS("Delete")];
    [o_mi_selectall setTitle: _NS("Select All")];
142
143
    [[o_tc_name headerCell] setStringValue:_NS("Name")];
    [[o_tc_author headerCell] setStringValue:_NS("Author")];
144
145
146
    [o_random_ckb setTitle: _NS("Random")];
    [o_loop_ckb setTitle: _NS("Repeat All")];
    [o_repeat_ckb setTitle: _NS("Repeat One")];
bigben's avatar
bigben committed
147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

    vlc_value_t val;
    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );
    if( p_playlist != NULL )
    {
    int i_state;

    var_Get( p_playlist, "random", &val );
    i_state = val.b_bool ? NSOnState : NSOffState;
    [o_random_ckb setState: i_state];

    var_Get( p_playlist, "loop", &val );
    i_state = val.b_bool ? NSOnState : NSOffState;
    [o_loop_ckb setState: i_state];

    var_Get( p_playlist, "repeat", &val );
    i_state = val.b_bool ? NSOnState : NSOffState;
    [o_repeat_ckb setState: i_state];

    vlc_mutex_unlock( &p_playlist->object_lock );
    vlc_object_release( p_playlist );
    }


174
175
176
177
178
179
180
181
182
}

- (BOOL)tableView:(NSTableView *)o_tv 
                  shouldEditTableColumn:(NSTableColumn *)o_tc
                  row:(int)i_row
{
    return( NO );
}

Jon Lech Johansen's avatar
Jon Lech Johansen committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
- (NSMenu *)menuForEvent:(NSEvent *)o_event
{
    NSPoint pt;
    vlc_bool_t b_rows;
    vlc_bool_t b_item_sel;

    pt = [o_table_view convertPoint: [o_event locationInWindow] 
                                                 fromView: nil];
    b_item_sel = ( [o_table_view rowAtPoint: pt] != -1 &&
                   [o_table_view selectedRow] != -1 );
    b_rows = [o_table_view numberOfRows] != 0;

    [o_mi_play setEnabled: b_item_sel];
    [o_mi_delete setEnabled: b_item_sel];
    [o_mi_selectall setEnabled: b_rows];

    return( o_ctx_menu );
}

202
203
204
205
206
207
208
209
210
211
212
213
- (IBAction)toggleWindow:(id)sender
{
    if( [o_window isVisible] )
    {
        [o_window orderOut:sender];
    }
    else
    {
        [o_window makeKeyAndOrderFront:sender];
    }
}

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
- (IBAction)savePlaylist:(id)sender
{
    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );
    
    NSSavePanel *o_save_panel = [NSSavePanel savePanel];
    NSString * o_name = [NSString stringWithFormat: @"%@.m3u", _NS("Untitled")];
    [o_save_panel setTitle: _NS("Save Playlist")];
    [o_save_panel setPrompt: _NS("Save")];

    if( [o_save_panel runModalForDirectory: nil
            file: o_name] == NSOKButton )
    {
        playlist_SaveFile( p_playlist, [[o_save_panel filename] fileSystemRepresentation] );
    }

}

Jon Lech Johansen's avatar
Jon Lech Johansen committed
233
- (IBAction)playItem:(id)sender
234
235
236
237
238
{
    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );

hartman's avatar
hartman committed
239
    if( p_playlist != NULL )
240
    {
hartman's avatar
hartman committed
241
242
        playlist_Goto( p_playlist, [o_table_view selectedRow] );
        vlc_object_release( p_playlist );
243
244
245
    }
}

Jon Lech Johansen's avatar
Jon Lech Johansen committed
246
247
- (IBAction)deleteItems:(id)sender
{
hartman's avatar
hartman committed
248
249
250
    int i, c, i_row;
    NSMutableArray *o_to_delete;
    NSNumber *o_number;
Jon Lech Johansen's avatar
Jon Lech Johansen committed
251
252
253
254
255
256
257
258
259

    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );

    if( p_playlist == NULL )
    {
        return;
    }
hartman's avatar
hartman committed
260
261
    
    o_to_delete = [NSMutableArray arrayWithArray:[[o_table_view selectedRowEnumerator] allObjects]];
hartman's avatar
hartman committed
262
    c = (int)[o_to_delete count];
hartman's avatar
hartman committed
263
264
265
266
267
    
    for( i = 0; i < c; i++ ) {
        o_number = [o_to_delete lastObject];
        i_row = [o_number intValue];
        
Jon Lech Johansen's avatar
Jon Lech Johansen committed
268
269
270
271
        if( p_playlist->i_index == i_row && p_playlist->i_status )
        {
            playlist_Stop( p_playlist );
        }
hartman's avatar
hartman committed
272
        [o_to_delete removeObject: o_number];
Jon Lech Johansen's avatar
Jon Lech Johansen committed
273
        [o_table_view deselectRow: i_row];
hartman's avatar
hartman committed
274
        playlist_Delete( p_playlist, i_row );
Jon Lech Johansen's avatar
Jon Lech Johansen committed
275
276
277
278
    }

    vlc_object_release( p_playlist );

hartman's avatar
hartman committed
279
280
281
    /* this is actually duplicity, because the intf.m manage also updates the view
     * when the playlist changes. we do this on purpose, because else there is a 
     * delay of .5 sec or so when we delete an item */
Jon Lech Johansen's avatar
Jon Lech Johansen committed
282
    [self playlistUpdated];
hartman's avatar
hartman committed
283
    [self updateRowSelection];
Jon Lech Johansen's avatar
Jon Lech Johansen committed
284
285
286
287
288
289
290
}

- (IBAction)selectAll:(id)sender
{
    [o_table_view selectAll: nil];
}

bigben's avatar
bigben committed
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338

- (IBAction)searchItem:(id)sender
{
    int i_start;
    int i_current;
    id o_current_name;

    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                               FIND_ANYWHERE );
    if ( [o_table_view selectedRow] == [o_table_view numberOfRows]-1 )
    {
         i_start = -1;
    }
    else 
    {
         i_start = [o_table_view selectedRow];
    }

    for ( i_current = i_start + 1 ; i_current < [o_table_view numberOfRows] ; i_current++ )
    {

        if( p_playlist == NULL )
        {
            o_current_name = nil;
        }


        else 
        {
            vlc_mutex_lock( &p_playlist->object_lock );
            o_current_name = [[NSString stringWithUTF8String: 
                p_playlist->pp_items[i_current]->psz_name] lastPathComponent]; 
            vlc_mutex_unlock( &p_playlist->object_lock );
        }

        if( [o_current_name rangeOfString:[o_search_keyword stringValue] options:NSCaseInsensitiveSearch ].length )
        {
             [o_table_view selectRow: i_current byExtendingSelection: NO];
             [o_table_view scrollRowToVisible: i_current];
             break;
        }
    [o_table_view selectRow: i_current byExtendingSelection: NO];
    [o_table_view scrollRowToVisible: i_current];
    }
    vlc_object_release( p_playlist );
}

339
- (void)appendArray:(NSArray*)o_array atPos:(int)i_position enqueue:(BOOL)b_enqueue
340
{
341
    int i_item;
342
343
344
345
346
347
348
349
350
    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );

    if( p_playlist == NULL )
    {
        return;
    }

351
    for ( i_item = 0; i_item < (int)[o_array count]; i_item++ )
352
    {
353
354
        /* One item */
        NSDictionary *o_one_item;
hartman's avatar
hartman committed
355
356
357
358
359
        int j;
        int i_total_options = 0;
        int i_mode = PLAYLIST_INSERT;
        BOOL b_rem = FALSE, b_dir = FALSE;
        NSString *o_url, *o_name;
360
361
        NSArray *o_options;
        char **ppsz_options = NULL;
hartman's avatar
hartman committed
362
    
363
364
365
366
367
368
        /* Get the item */
        o_one_item = [o_array objectAtIndex: i_item];
        o_url = (NSString *)[o_one_item objectForKey: @"ITEM_URL"];
        o_name = (NSString *)[o_one_item objectForKey: @"ITEM_NAME"];
        o_options = (NSArray *)[o_one_item objectForKey: @"ITEM_OPTIONS"];
        
hartman's avatar
hartman committed
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
        /* If no name, then make a guess */
        if( !o_name) o_name = [[NSFileManager defaultManager] displayNameAtPath: o_url];
    
        if( [[NSFileManager defaultManager] fileExistsAtPath:o_url isDirectory:&b_dir] && b_dir &&
            [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath: o_url isRemovable: &b_rem
                    isWritable:NULL isUnmountable:NULL description:NULL type:NULL] && b_rem   )
        {
            /* All of this is to make sure CD's play when you D&D them on VLC */
            /* Converts mountpoint to a /dev file */
            struct statfs *buf;
            char *psz_dev, *temp;
            buf = (struct statfs *) malloc (sizeof(struct statfs));
            statfs( [o_url fileSystemRepresentation], buf );
            psz_dev = strdup(buf->f_mntfromname);
            free( buf );
            temp = strrchr( psz_dev , 's' );
            psz_dev[temp - psz_dev] = '\0';
            o_url = [NSString stringWithCString: psz_dev ];
        }
    
389
        if (i_item == 0 && !b_enqueue)
390
            i_mode |= PLAYLIST_GO;
hartman's avatar
hartman committed
391
    
392
393
394
395
396
397
398
399
400
401
402
403
404
405
        if( o_options && [o_options count] > 0 )
        {
            /* Count the input options */
            i_total_options = [o_options count];
    
            /* Allocate ppsz_options */
            for( j = 0; j < i_total_options; j++ )
            {
                if( !ppsz_options )
                    ppsz_options = (char **)malloc( sizeof(char *) * i_total_options );
    
                ppsz_options[j] = strdup([[o_options objectAtIndex:j] UTF8String]);
            }
        }
hartman's avatar
hartman committed
406
407
    
        playlist_AddExt( p_playlist, [o_url fileSystemRepresentation], [o_name UTF8String], -1, 
408
            (ppsz_options != NULL ) ? (const char **)ppsz_options : 0, i_total_options,
hartman's avatar
hartman committed
409
410
            i_mode, i_position == -1 ? PLAYLIST_END : i_position + i_item);
    
411
412
413
414
        /* clean up */
        for( j = 0; j < i_total_options; j++ )
            free( ppsz_options[j] );
        if( ppsz_options ) free( ppsz_options );
hartman's avatar
hartman committed
415
416
    
        /* Recent documents menu */
417
418
        NSURL *o_true_url = [NSURL fileURLWithPath: o_url];
        if( o_true_url != nil )
419
420
        { 
            [[NSDocumentController sharedDocumentController]
421
                noteNewRecentDocumentURL: o_true_url]; 
422
423
424
425
        }
    }

    vlc_object_release( p_playlist );
Jon Lech Johansen's avatar
Jon Lech Johansen committed
426
427
428
429
430
}

- (void)playlistUpdated
{
    [o_table_view reloadData];
431
432
}

433
- (void)updateRowSelection
hartman's avatar
ALL:    
hartman committed
434
435
436
437
438
439
440
441
442
443
444
{
    int i_row;

    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );

    if( p_playlist == NULL )
    {
        return;
    }
445

hartman's avatar
ALL:    
hartman committed
446
447
    i_row = p_playlist->i_index;
    vlc_object_release( p_playlist );
448

hartman's avatar
ALL:    
hartman committed
449
450
451
    [o_table_view selectRow: i_row byExtendingSelection: NO];
    [o_table_view scrollRowToVisible: i_row];
}
bigben's avatar
bigben committed
452
    
hartman's avatar
ALL:    
hartman committed
453

454
455
456
457
458
459
460
461
462
@end

@implementation VLCPlaylist (NSTableDataSource)

- (int)numberOfRowsInTableView:(NSTableView *)o_tv
{
    int i_count = 0;
    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
463
                                                       FIND_ANYWHERE );
464
465
466

    if( p_playlist != NULL )
    {
467
        vlc_mutex_lock( &p_playlist->object_lock );
468
        i_count = p_playlist->i_size;
469
        vlc_mutex_unlock( &p_playlist->object_lock );
470
471
        vlc_object_release( p_playlist );
    }
472
    [o_status_field setStringValue: [NSString stringWithFormat:_NS("%i items in playlist"), i_count]];
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
    return( i_count );
}

- (id)tableView:(NSTableView *)o_tv 
                objectValueForTableColumn:(NSTableColumn *)o_tc 
                row:(int)i_row
{
    id o_value = nil;
    intf_thread_t * p_intf = [NSApp getIntf];
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                               FIND_ANYWHERE );

    if( p_playlist == NULL )
    {
        return( nil );
    }

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    if( [[o_tc identifier] isEqualToString:@"0"] )
    {
        o_value = [NSString stringWithFormat:@"%i", i_row + 1];
    }
    else if( [[o_tc identifier] isEqualToString:@"1"] )
    {
        vlc_mutex_lock( &p_playlist->object_lock );
        o_value = [[NSString stringWithUTF8String: 
            p_playlist->pp_items[i_row]->psz_name] lastPathComponent]; 
        vlc_mutex_unlock( &p_playlist->object_lock );
    }
    else if( [[o_tc identifier] isEqualToString:@"2"] )
    {
        vlc_mutex_lock( &p_playlist->object_lock );
        o_value = [NSString stringWithUTF8String: 
            p_playlist->pp_items[i_row]->psz_author]; 
        vlc_mutex_unlock( &p_playlist->object_lock );
    }
508
509
510
511
512
513

    vlc_object_release( p_playlist );

    return( o_value );
}

hartman's avatar
hartman committed
514
515
516
- (BOOL)tableView:(NSTableView *)o_tv
                    writeRows:(NSArray*)o_rows
                    toPasteboard:(NSPasteboard*)o_pasteboard 
hartman's avatar
hartman committed
517
{
hartman's avatar
hartman committed
518
    int i_rows = [o_rows count];
hartman's avatar
hartman committed
519
520
    NSArray *o_filenames = [NSArray array];
    
hartman's avatar
hartman committed
521
522
523
    [o_pasteboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:self];
    [o_pasteboard setPropertyList:o_filenames forType:NSFilenamesPboardType];
    if ( i_rows == 1 )
hartman's avatar
hartman committed
524
    {
hartman's avatar
hartman committed
525
        i_moveRow = [[o_rows objectAtIndex:0]intValue];
hartman's avatar
hartman committed
526
527
528
529
530
        return YES;
    }
    return NO;
}

hartman's avatar
hartman committed
531
532
533
534
- (NSDragOperation)tableView:(NSTableView*)o_tv
                    validateDrop:(id <NSDraggingInfo>)o_info
                    proposedRow:(int)i_row
                    proposedDropOperation:(NSTableViewDropOperation)o_operation 
hartman's avatar
hartman committed
535
{
hartman's avatar
hartman committed
536
    if ( o_operation == NSTableViewDropAbove )
hartman's avatar
hartman committed
537
    {
hartman's avatar
hartman committed
538
        if ( i_moveRow >= 0 )
hartman's avatar
hartman committed
539
        {
hartman's avatar
hartman committed
540
541
542
543
544
545
546
            if ( i_row != i_moveRow )
            {
                return NSDragOperationMove;
            }
            /* what if in the previous run, the row wasn't actually moved? 
               then we can't drop new files on this location */
            return NSDragOperationNone;
hartman's avatar
hartman committed
547
        }
hartman's avatar
hartman committed
548
        return NSDragOperationGeneric;
hartman's avatar
hartman committed
549
550
551
552
    }
    return NSDragOperationNone;
}

hartman's avatar
hartman committed
553
554
555
556
- (BOOL)tableView:(NSTableView*)o_tv
                    acceptDrop:(id <NSDraggingInfo>)o_info
                    row:(int)i_proposed_row
                    dropOperation:(NSTableViewDropOperation)o_operation 
hartman's avatar
hartman committed
557
{
hartman's avatar
hartman committed
558
    if (  i_moveRow >= 0 )
hartman's avatar
hartman committed
559
    {
hartman's avatar
hartman committed
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
        if (i_moveRow != -1 && i_proposed_row != -1)
        {
            intf_thread_t * p_intf = [NSApp getIntf];
            playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                            FIND_ANYWHERE );
        
            if( p_playlist == NULL )
            {
                i_moveRow = -1;
                return NO;
            }
    
            playlist_Move( p_playlist, i_moveRow, i_proposed_row ); 
        
            vlc_object_release( p_playlist );
        }
hartman's avatar
hartman committed
576
        [self playlistUpdated];
hartman's avatar
hartman committed
577
578
        i_moveRow = -1;
        return YES;
hartman's avatar
hartman committed
579
580
581
582
    }
    else
    {
        NSPasteboard * o_pasteboard;
hartman's avatar
hartman committed
583
        o_pasteboard = [o_info draggingPasteboard];
hartman's avatar
hartman committed
584
585
586
        
        if( [[o_pasteboard types] containsObject: NSFilenamesPboardType] )
        {
587
588
589
            int i;
            NSArray *o_array = [NSArray array];
            NSArray *o_values = [[o_pasteboard propertyListForType: NSFilenamesPboardType]
hartman's avatar
hartman committed
590
                        sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
591

592
            for( i = 0; i < (int)[o_values count]; i++)
593
594
595
596
597
598
            {
                NSDictionary *o_dic;
                o_dic = [NSDictionary dictionaryWithObject:[o_values objectAtIndex:i] forKey:@"ITEM_URL"];
                o_array = [o_array arrayByAddingObject: o_dic];
            }
            [self appendArray: o_array atPos: i_proposed_row enqueue:YES];
hartman's avatar
hartman committed
599
            return YES;
hartman's avatar
hartman committed
600
        }
hartman's avatar
hartman committed
601
        return NO;
hartman's avatar
hartman committed
602
    }
603
    [self updateRowSelection];
hartman's avatar
hartman committed
604
605
}

606
607
@end