Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
GSoC
GSoC2018
macOS
vlc
Commits
f24504e4
Commit
f24504e4
authored
Nov 30, 2014
by
David
Browse files
macosx: Move drag and drop support to new PLModel and rewrite
This simplifies the methods, also using a simpler storage for dragged items.
parent
42d2a27a
Changes
6
Hide whitespace changes
Inline
Side-by-side
modules/gui/macosx/MainWindow.m
View file @
f24504e4
...
...
@@ -1182,7 +1182,7 @@ static VLCMainWindow *_o_sharedInstance = nil;
{
if
([[
item
identifier
]
isEqualToString
:
@"playlist"
]
||
[[
item
identifier
]
isEqualToString
:
@"medialibrary"
])
{
NSPasteboard
*
o_pasteboard
=
[
info
draggingPasteboard
];
if
([[
o_pasteboard
types
]
containsObject
:
@"
VLCP
laylist
ItemPboa
r
dType
"
]
||
[[
o_pasteboard
types
]
containsObject
:
NSFilenamesPboardType
])
if
([[
o_pasteboard
types
]
containsObject
:
VLCP
L
ItemP
aste
boadType
]
||
[[
o_pasteboard
types
]
containsObject
:
NSFilenamesPboardType
])
return
NSDragOperationGeneric
;
}
return
NSDragOperationNone
;
...
...
@@ -1225,11 +1225,10 @@ static VLCMainWindow *_o_sharedInstance = nil;
NSArray
*
array
=
[[[
VLCMain
sharedInstance
]
playlist
]
draggedItems
];
NSUInteger
count
=
[
array
count
];
playlist_item_t
*
p_item
=
NULL
;
PL_LOCK
;
for
(
NSUInteger
i
=
0
;
i
<
count
;
i
++
)
{
p
_item
=
[[
array
objectAtIndex
:
i
]
p
ointerValue
]
;
p
laylist_item_t
*
p_item
=
playlist_ItemGetById
(
p_playlist
,
[[
array
objectAtIndex
:
i
]
p
lItemId
])
;
if
(
!
p_item
)
continue
;
playlist_NodeAddCopy
(
p_playlist
,
p_item
,
p_node
,
PLAYLIST_END
);
}
...
...
modules/gui/macosx/PLItem.h
View file @
f24504e4
...
...
@@ -36,9 +36,9 @@
@property
(
readonly
,
copy
)
NSMutableArray
*
children
;
@property
(
readonly
)
int
plItemId
;
@property
(
readonly
)
input_item_t
*
input
;
@property
(
read
only
)
PLItem
*
parent
;
@property
(
read
write
,
retain
)
PLItem
*
parent
;
-
(
id
)
initWithPlaylistItem
:(
playlist_item_t
*
)
p_item
parent
:(
PLItem
*
)
parent
;
-
(
id
)
initWithPlaylistItem
:(
playlist_item_t
*
)
p_item
;
-
(
BOOL
)
isLeaf
;
...
...
modules/gui/macosx/PLItem.m
View file @
f24504e4
...
...
@@ -33,7 +33,7 @@
@synthesize
input
=
p_input
;
@synthesize
parent
=
_parent
;
-
(
id
)
initWithPlaylistItem
:(
playlist_item_t
*
)
p_item
parent
:(
PLItem
*
)
parent
;
-
(
id
)
initWithPlaylistItem
:(
playlist_item_t
*
)
p_item
;
{
self
=
[
super
init
];
if
(
self
)
{
...
...
@@ -42,8 +42,6 @@
p_input
=
p_item
->
p_input
;
input_item_Hold
(
p_input
);
_children
=
[[
NSMutableArray
alloc
]
init
];
[
parent
retain
];
_parent
=
parent
;
}
return
self
;
...
...
@@ -58,6 +56,21 @@
[
super
dealloc
];
}
// own hash and isEqual methods are important to retain expandable state
// when items are moved / recreated
-
(
NSUInteger
)
hash
{
return
(
NSUInteger
)[
self
plItemId
];
}
-
(
BOOL
)
isEqual
:(
id
)
other
{
if
(
other
==
self
)
return
YES
;
if
(
!
other
||
!
[
other
isKindOfClass
:[
self
class
]])
return
NO
;
return
[
self
plItemId
]
==
[
other
plItemId
];
}
-
(
BOOL
)
isLeaf
{
...
...
@@ -71,15 +84,14 @@
-
(
void
)
addChild
:(
PLItem
*
)
item
atPos
:(
int
)
pos
{
// if ([o_children count] > pos) {
// NSLog(@"invalid position %d", pos);
// }
[
_children
insertObject
:
item
atIndex
:
pos
];
[
item
setParent
:
self
];
}
-
(
void
)
deleteChild
:(
PLItem
*
)
child
{
[
child
setParent
:
nil
];
[
_children
removeObject
:
child
];
}
...
...
modules/gui/macosx/PLModel.h
View file @
f24504e4
...
...
@@ -25,17 +25,29 @@
#include
<vlc_common.h>
#define VLCPLItemPasteboadType @"VLCPlaylistItemPboardType"
@class
VLCPlaylist
;
@interface
PLModel
:
NSObject
<
NSOutlineViewDataSource
>
{
PLItem
*
_rootItem
;
playlist_t
*
p_playlist
;
NSOutlineView
*
_outlineView
;
// TODO: write these objects to the pastboard properly?
NSMutableArray
*
_draggedItems
;
// TODO: for transition
VLCPlaylist
*
_playlist
;
}
@property
(
readonly
)
PLItem
*
rootItem
;
@property
(
readonly
,
copy
)
NSArray
*
draggedItems
;
-
(
id
)
initWithOutlineView
:(
NSOutlineView
*
)
outlineView
playlist
:(
playlist_t
*
)
pl
rootItem
:(
playlist_item_t
*
)
root
;
-
(
id
)
initWithOutlineView
:(
NSOutlineView
*
)
outlineView
playlist
:(
playlist_t
*
)
pl
rootItem
:(
playlist_item_t
*
)
root
playlistObject
:(
id
)
plObj
;
-
(
void
)
changeRootItem
:(
playlist_item_t
*
)
p_root
;
...
...
modules/gui/macosx/PLModel.m
View file @
f24504e4
...
...
@@ -23,8 +23,11 @@
#import "misc.h"
#import "playlist.h"
#include
<vlc_playlist.h>
#include
<vlc_input_item.h>
#import <vlc_input.h>
#include
<vlc_url.h>
#define TRACKNUM_COLUMN @"tracknumber"
...
...
@@ -44,16 +47,19 @@
@implementation
PLModel
@synthesize
rootItem
=
_rootItem
;
@synthesize
draggedItems
=
_draggedItems
;
-
(
id
)
initWithOutlineView
:(
NSOutlineView
*
)
outlineView
playlist
:(
playlist_t
*
)
pl
rootItem
:(
playlist_item_t
*
)
root
;
-
(
id
)
initWithOutlineView
:(
NSOutlineView
*
)
outlineView
playlist
:(
playlist_t
*
)
pl
rootItem
:(
playlist_item_t
*
)
root
playlistObject
:(
id
)
plObj
;
{
self
=
[
super
init
];
if
(
self
)
{
p_playlist
=
pl
;
_outlineView
=
[
outlineView
retain
];
_playlist
=
plObj
;
PL_LOCK
;
_rootItem
=
[[
PLItem
alloc
]
initWithPlaylistItem
:
root
parent
:
nil
];
_rootItem
=
[[
PLItem
alloc
]
initWithPlaylistItem
:
root
];
[
self
rebuildPLItem
:
_rootItem
];
PL_UNLOCK
;
...
...
@@ -67,7 +73,7 @@
NSLog
(
@"change root item to %p"
,
p_root
);
PL_ASSERT_LOCKED
;
[
_rootItem
release
];
_rootItem
=
[[
PLItem
alloc
]
initWithPlaylistItem
:
p_root
parent
:
nil
];
_rootItem
=
[[
PLItem
alloc
]
initWithPlaylistItem
:
p_root
];
[
self
rebuildPLItem
:
_rootItem
];
[
_outlineView
reloadData
];
}
...
...
@@ -106,7 +112,7 @@
if
(
p_child
->
i_flags
&
PLAYLIST_DBL_FLAG
)
continue
;
PLItem
*
o_child
=
[[[
PLItem
alloc
]
initWithPlaylistItem
:
p_child
parent
:
o_item
]
autorelease
];
PLItem
*
o_child
=
[[[
PLItem
alloc
]
initWithPlaylistItem
:
p_child
]
autorelease
];
[
o_item
addChild
:
o_child
atPos
:
currPos
++
];
if
(
p_child
->
i_children
>=
0
)
{
...
...
@@ -159,7 +165,8 @@
playlist_item_t
*
p_item
=
playlist_ItemGetById
(
p_playlist
,
i_item
);
if
(
!
p_item
||
p_item
->
i_flags
&
PLAYLIST_DBL_FLAG
)
{
PL_UNLOCK
;
return
;
PL_UNLOCK
;
return
;
}
int
pos
;
...
...
@@ -167,7 +174,7 @@
if
(
p_item
->
p_parent
->
pp_children
[
pos
]
==
p_item
)
break
;
PLItem
*
o_new_item
=
[[[
PLItem
alloc
]
initWithPlaylistItem
:
p_item
parent
:
o_parent
]
autorelease
];
PLItem
*
o_new_item
=
[[[
PLItem
alloc
]
initWithPlaylistItem
:
p_item
]
autorelease
];
PL_UNLOCK
;
if
(
pos
<
0
)
return
;
...
...
@@ -375,4 +382,197 @@
return
o_value
;
}
#pragma mark -
#pragma mark Drag and Drop support
-
(
BOOL
)
isItem
:
(
PLItem
*
)
p_item
inNode
:
(
PLItem
*
)
p_node
{
while
(
p_item
)
{
if
([
p_item
plItemId
]
==
[
p_node
plItemId
])
{
return
YES
;
}
p_item
=
[
p_item
parent
];
}
return
NO
;
}
-
(
BOOL
)
outlineView
:(
NSOutlineView
*
)
outlineView
writeItems
:(
NSArray
*
)
items
toPasteboard
:(
NSPasteboard
*
)
pboard
{
NSUInteger
itemCount
=
[
items
count
];
[
_draggedItems
release
];
_draggedItems
=
[[
NSMutableArray
alloc
]
initWithArray
:
items
];
/* Add the data to the pasteboard object. */
[
pboard
declareTypes
:
[
NSArray
arrayWithObject
:
VLCPLItemPasteboadType
]
owner
:
self
];
[
pboard
setData
:[
NSData
data
]
forType
:
VLCPLItemPasteboadType
];
return
YES
;
}
-
(
NSDragOperation
)
outlineView
:(
NSOutlineView
*
)
outlineView
validateDrop
:(
id
<
NSDraggingInfo
>
)
info
proposedItem
:(
id
)
item
proposedChildIndex
:(
NSInteger
)
index
{
NSPasteboard
*
o_pasteboard
=
[
info
draggingPasteboard
];
/* Dropping ON items is not allowed if item is not a node */
if
(
item
)
{
if
(
index
==
NSOutlineViewDropOnItemIndex
&&
[
item
isLeaf
])
{
return
NSDragOperationNone
;
}
}
if
(
!
[
self
editAllowed
])
return
NSDragOperationNone
;
/* Drop from the Playlist */
if
([[
o_pasteboard
types
]
containsObject
:
VLCPLItemPasteboadType
])
{
NSUInteger
count
=
[
_draggedItems
count
];
for
(
NSUInteger
i
=
0
;
i
<
count
;
i
++
)
{
/* We refuse to Drop in a child of an item we are moving */
if
([
self
isItem
:
item
inNode
:
[
_draggedItems
objectAtIndex
:
i
]])
{
return
NSDragOperationNone
;
}
}
return
NSDragOperationMove
;
}
/* Drop from the Finder */
else
if
([[
o_pasteboard
types
]
containsObject
:
NSFilenamesPboardType
])
{
return
NSDragOperationGeneric
;
}
return
NSDragOperationNone
;
}
-
(
BOOL
)
outlineView
:(
NSOutlineView
*
)
outlineView
acceptDrop
:(
id
<
NSDraggingInfo
>
)
info
item
:(
id
)
targetItem
childIndex
:(
NSInteger
)
index
{
NSPasteboard
*
o_pasteboard
=
[
info
draggingPasteboard
];
/* Drag & Drop inside the playlist */
if
([[
o_pasteboard
types
]
containsObject
:
VLCPLItemPasteboadType
])
{
if
(
index
==
-
1
)
// this is no valid target, sanitize to top of table
index
=
0
;
if
(
targetItem
==
nil
)
{
targetItem
=
_rootItem
;
}
NSMutableArray
*
o_filteredItems
=
[
NSMutableArray
arrayWithArray
:
_draggedItems
];
const
NSUInteger
draggedItemsCount
=
[
_draggedItems
count
];
for
(
NSInteger
i
=
0
;
i
<
[
o_filteredItems
count
];
i
++
)
{
for
(
NSUInteger
j
=
0
;
j
<
draggedItemsCount
;
j
++
)
{
PLItem
*
itemToCheck
=
[
o_filteredItems
objectAtIndex
:
i
];
PLItem
*
nodeToTest
=
[
_draggedItems
objectAtIndex
:
j
];
if
([
itemToCheck
plItemId
]
==
[
nodeToTest
plItemId
])
continue
;
if
([
self
isItem
:
itemToCheck
inNode
:
nodeToTest
])
{
[
o_filteredItems
removeObjectAtIndex
:
i
];
--
i
;
break
;
}
}
}
NSUInteger
count
=
[
o_filteredItems
count
];
if
(
count
==
0
)
return
NO
;
playlist_item_t
**
pp_items
=
(
playlist_item_t
**
)
calloc
(
count
,
sizeof
(
playlist_item_t
*
));
if
(
!
pp_items
)
return
NO
;
PL_LOCK
;
playlist_item_t
*
p_new_parent
=
playlist_ItemGetById
(
p_playlist
,
[
targetItem
plItemId
]);
if
(
!
p_new_parent
)
{
PL_UNLOCK
;
return
NO
;
}
NSUInteger
j
=
0
;
for
(
NSUInteger
i
=
0
;
i
<
count
;
i
++
)
{
playlist_item_t
*
p_item
=
playlist_ItemGetById
(
p_playlist
,
[[
o_filteredItems
objectAtIndex
:
i
]
plItemId
]);
if
(
p_item
)
pp_items
[
j
++
]
=
p_item
;
}
if
(
playlist_TreeMoveMany
(
p_playlist
,
j
,
pp_items
,
p_new_parent
,
index
)
!=
VLC_SUCCESS
)
{
PL_UNLOCK
;
free
(
pp_items
);
return
NO
;
}
PL_UNLOCK
;
free
(
pp_items
);
// rebuild our model
NSUInteger
filteredItemsCount
=
[
o_filteredItems
count
];
for
(
NSUInteger
i
=
0
;
i
<
filteredItemsCount
;
++
i
)
{
PLItem
*
o_item
=
[
o_filteredItems
objectAtIndex
:
i
];
NSLog
(
@"delete child from parent %p"
,
[
o_item
parent
]);
[[
o_item
parent
]
deleteChild
:
o_item
];
[
targetItem
addChild
:
o_item
atPos
:
index
+
i
];
}
[
_outlineView
reloadData
];
NSMutableIndexSet
*
selectedIndexes
=
[[
NSMutableIndexSet
alloc
]
init
];
for
(
NSUInteger
i
=
0
;
i
<
draggedItemsCount
;
++
i
)
{
NSInteger
row
=
[
_outlineView
rowForItem
:[
_draggedItems
objectAtIndex
:
i
]];
if
(
row
<
0
)
continue
;
[
selectedIndexes
addIndex
:
row
];
}
if
([
selectedIndexes
count
]
==
0
)
[
selectedIndexes
addIndex
:[
_outlineView
rowForItem
:
targetItem
]];
[
_outlineView
selectRowIndexes
:
selectedIndexes
byExtendingSelection
:
NO
];
[
selectedIndexes
release
];
return
YES
;
}
else
if
([[
o_pasteboard
types
]
containsObject
:
NSFilenamesPboardType
])
{
NSArray
*
o_values
=
[[
o_pasteboard
propertyListForType
:
NSFilenamesPboardType
]
sortedArrayUsingSelector:
@selector
(
caseInsensitiveCompare
:)];
NSUInteger
count
=
[
o_values
count
];
NSMutableArray
*
o_array
=
[
NSMutableArray
arrayWithCapacity
:
count
];
input_thread_t
*
p_input
=
playlist_CurrentInput
(
p_playlist
);
if
(
count
==
1
&&
p_input
)
{
int
i_result
=
input_AddSubtitleOSD
(
p_input
,
vlc_path2uri
([[
o_values
objectAtIndex
:
0
]
UTF8String
],
NULL
),
true
,
true
);
vlc_object_release
(
p_input
);
if
(
i_result
==
VLC_SUCCESS
)
return
YES
;
}
else
if
(
p_input
)
vlc_object_release
(
p_input
);
for
(
NSUInteger
i
=
0
;
i
<
count
;
i
++
)
{
NSDictionary
*
o_dic
;
char
*
psz_uri
=
vlc_path2uri
([[
o_values
objectAtIndex
:
i
]
UTF8String
],
NULL
);
if
(
!
psz_uri
)
continue
;
o_dic
=
[
NSDictionary
dictionaryWithObject
:[
NSString
stringWithCString
:
psz_uri
encoding
:
NSUTF8StringEncoding
]
forKey
:
@"ITEM_URL"
];
free
(
psz_uri
);
[
o_array
addObject
:
o_dic
];
}
// if (item == nil)
[
_playlist
appendArray
:
o_array
atPos
:
index
enqueue
:
YES
];
// TODO support for drop on sub nodes
// else {
// assert(p_node->i_children != -1);
// [_playlist appendNodeArray:o_array inNode: p_node atPos:index enqueue:YES];
// }
return
YES
;
}
return
NO
;
}
@end
modules/gui/macosx/playlist.m
View file @
f24504e4
...
...
@@ -164,9 +164,6 @@
NSImage
*
o_descendingSortingImage
;
NSImage
*
o_ascendingSortingImage
;
NSMutableArray
*
o_nodes_array
;
NSMutableArray
*
o_items_array
;
BOOL
b_selected_item_met
;
BOOL
b_isSortDescending
;
id
o_tc_sortColumn
;
...
...
@@ -238,9 +235,6 @@
playlist_t
*
p_playlist
=
pl_Get
(
VLCIntf
);
p_current_root_item
=
p_playlist
->
p_local_category
;
o_outline_dict
=
[[
NSMutableDictionary
alloc
]
init
];
o_nodes_array
=
[[
NSMutableArray
alloc
]
init
];
o_items_array
=
[[
NSMutableArray
alloc
]
init
];
}
return
self
;
}
...
...
@@ -248,8 +242,6 @@
-
(
void
)
dealloc
{
[
o_outline_dict
release
];
[
o_nodes_array
release
];
[
o_items_array
release
];
[
super
dealloc
];
}
...
...
@@ -267,7 +259,7 @@
[
self
reloadStyles
];
[
self
initStrings
];
o_model
=
[[
PLModel
alloc
]
initWithOutlineView
:
o_outline_view
playlist
:
p_playlist
rootItem
:
p_current_root_item
];
o_model
=
[[
PLModel
alloc
]
initWithOutlineView
:
o_outline_view
playlist
:
p_playlist
rootItem
:
p_current_root_item
playlistObject
:
self
];
[
o_outline_view
setDataSource
:
o_model
];
[
o_outline_view
reloadData
];
...
...
@@ -450,30 +442,6 @@
return
NO
;
}
/* This method is useful for instance to remove the selected children of an
already selected node */
-
(
void
)
removeItemsFrom
:(
id
)
o_items
ifChildrenOf
:(
id
)
o_nodes
{
NSUInteger
itemCount
=
[
o_items
count
];
NSUInteger
nodeCount
=
[
o_nodes
count
];
for
(
NSUInteger
i
=
0
;
i
<
itemCount
;
i
++
)
{
for
(
NSUInteger
j
=
0
;
j
<
nodeCount
;
j
++
)
{
if
(
o_items
==
o_nodes
)
{
if
(
j
==
i
)
continue
;
}
if
([
self
isItem
:
[
o_items
objectAtIndex
:
i
]
inNode:
[
o_nodes
objectAtIndex
:
j
]
checkItemExistence:
NO
locked
:
NO
])
{
[
o_items
removeObjectAtIndex
:
i
];
/* We need to execute the next iteration with the same index
since the current item has been deleted */
i
--
;
break
;
}
}
}
}
-
(
IBAction
)
savePlaylist
:(
id
)
sender
{
playlist_t
*
p_playlist
=
pl_Get
(
VLCIntf
);
...
...
@@ -1048,9 +1016,10 @@
return
o_playing_item
;
}
// TODO remove method
-
(
NSArray
*
)
draggedItems
{
return
[[
o_nodes_array
arrayByAddingObjectsFromArray
:
o_items_array
]
retain
];
return
[[
self
model
]
draggedItems
];
}
-
(
void
)
setColumn
:
(
NSString
*
)
o_column
state
:
(
NSInteger
)
i_state
translationDict
:(
NSDictionary
*
)
o_dict
...
...
@@ -1466,203 +1435,4 @@
return
o_value
;
}
/* Required for drag & drop and reordering */
-
(
BOOL
)
outlineView
:(
NSOutlineView
*
)
outlineView
writeItems
:(
NSArray
*
)
items
toPasteboard
:(
NSPasteboard
*
)
pboard
{
playlist_t
*
p_playlist
=
pl_Get
(
VLCIntf
);
/* First remove the items that were moved during the last drag & drop
operation */
[
o_items_array
removeAllObjects
];
[
o_nodes_array
removeAllObjects
];
NSUInteger
itemCount
=
[
items
count
];
for
(
NSUInteger
i
=
0
;
i
<
itemCount
;
i
++
)
{
id
o_item
=
[
items
objectAtIndex
:
i
];
/* Fill the items and nodes to move in 2 different arrays */
if
(
!
[
o_item
isLeaf
])
[
o_nodes_array
addObject
:
o_item
];
else
[
o_items_array
addObject
:
o_item
];
}
/* Now we need to check if there are selected items that are in already
selected nodes. In that case, we only want to move the nodes */
[
self
removeItemsFrom
:
o_nodes_array
ifChildrenOf
:
o_nodes_array
];
[
self
removeItemsFrom
:
o_items_array
ifChildrenOf
:
o_nodes_array
];
/* We add the "VLCPlaylistItemPboardType" type to be able to recognize
a Drop operation coming from the playlist. */
[
pboard
declareTypes
:
[
NSArray
arrayWithObject
:
@"VLCPlaylistItemPboardType"
]
owner
:
self
];
[
pboard
setData
:[
NSData
data
]
forType
:
@"VLCPlaylistItemPboardType"
];
return
YES
;
}
-
(
NSDragOperation
)
outlineView
:(
NSOutlineView
*
)
outlineView
validateDrop
:(
id
<
NSDraggingInfo
>
)
info
proposedItem
:(
id
)
item
proposedChildIndex
:(
NSInteger
)
index
{
playlist_t
*
p_playlist
=
pl_Get
(
VLCIntf
);
NSPasteboard
*
o_pasteboard
=
[
info
draggingPasteboard
];
if
(
!
p_playlist
)
return
NSDragOperationNone
;
/* Dropping ON items is not allowed if item is not a node */
if
(
item
)
{
if
(
index
==
NSOutlineViewDropOnItemIndex
&&
((
playlist_item_t
*
)[
item
pointerValue
])
->
i_children
==
-
1
)
{
return
NSDragOperationNone
;
}
}
/* We refuse to drop an item in anything else than a child of the General
Node. We still accept items that would be root nodes of the outlineview
however, to allow drop in an empty playlist. */
/// todo
// if (!(([self isItem: [item pointerValue] inNode: p_playlist->p_local_category checkItemExistence: NO locked: NO] ||
// (var_CreateGetBool(p_playlist, "media-library") && [self isItem: [item pointerValue] inNode: p_playlist->p_ml_category checkItemExistence: NO locked: NO])) || item == nil)) {
// return NSDragOperationNone;
// }
/* Drop from the Playlist */
if
([[
o_pasteboard
types
]
containsObject
:
@"VLCPlaylistItemPboardType"
])
{
NSUInteger
count
=
[
o_nodes_array
count
];
for
(
NSUInteger
i
=
0
;
i
<
count
;
i
++
)
{
/* We refuse to Drop in a child of an item we are moving */
if
([
self
isItem
:
item
inNode
:
[
o_nodes_array
objectAtIndex
:
i
]
checkItemExistence
:
NO
locked
:
NO
])
{
return
NSDragOperationNone
;
}
}
return
NSDragOperationMove
;
}
/* Drop from the Finder */
else
if
([[
o_pasteboard
types
]
containsObject
:
NSFilenamesPboardType
])
{
return
NSDragOperationGeneric
;
}
return
NSDragOperationNone
;
}
-
(
BOOL
)
outlineView
:(
NSOutlineView
*
)
outlineView
acceptDrop
:(
id
<
NSDraggingInfo
>
)
info
item
:(
id
)
item
childIndex
:(
NSInteger
)
index
{
playlist_t
*
p_playlist
=
pl_Get
(
VLCIntf
);
NSPasteboard
*
o_pasteboard
=
[
info
draggingPasteboard
];
/* Drag & Drop inside the playlist */
if
([[
o_pasteboard
types
]
containsObject
:
@"VLCPlaylistItemPboardType"
])
{
if
(
index
==
-
1
)
// this is no valid target, sanitize to top of table
index
=
0
;
int
i_row
=
0
;
playlist_item_t
*
p_new_parent
,
*
p_item
=
NULL
;
NSArray
*
o_all_items
=
[
o_nodes_array
arrayByAddingObjectsFromArray
:
o_items_array
];
/* If the item is to be dropped as root item of the outline, make it a
child of the respective general node, if is either the pl or the ml
Else, choose the proposed parent as parent. */
if
(
item
==
nil
)
{
// TODO edit allowed / no drop in other types
if
([[
self
model
]
currentRootType
]
==
ROOT_TYPE_PLAYLIST
||
[[
self
model
]
currentRootType
]
==
ROOT_TYPE_MEDIALIBRARY
)
item
=
[[
self
model
]
rootItem
];
else
return
NO
;
}
/* Make sure the proposed parent is a node.
(This should never be true) */
if
(
p_new_parent
->
i_children
<
0
)
return
NO
;
NSUInteger
count
=
[
o_all_items
count
];
if
(
count
==
0
)
return
NO
;
playlist_item_t
**
pp_items
=
(
playlist_item_t
**
)
calloc
(
count
,
sizeof
(
playlist_item_t
*
));
if
(
!
pp_items
)
return
NO
;
PL_LOCK
;
p_new_parent
=
playlist_ItemGetById
(
p_playlist
,
[
item
plItemId
]);
if
(
!
p_new_parent
)
{
PL_UNLOCK
;
return
NO
;
}
NSUInteger
j
=
0
;
for
(
NSUInteger
i
=
0
;
i
<
count
;
i
++
)
{
p_item
=
playlist_ItemGetById
(
p_playlist
,
[[
o_all_items
objectAtIndex
:
i
]
plItemId
]);
if
(
p_item
)
pp_items
[
j
++
]
=
p_item
;
}
if
(
j
==
0
||
playlist_TreeMoveMany
(
p_playlist
,
j
,
pp_items
,
p_new_parent
,
index
)
!=
VLC_SUCCESS
)
{
PL_UNLOCK
;