@@ -27,7 +27,7 @@ import { isSCMResource, isSCMResourceGroup, connectPrimaryMenuToInlineActionBar,
27
27
import { WorkbenchCompressibleObjectTree , IOpenEvent } from 'vs/platform/list/browser/listService' ;
28
28
import { IConfigurationService , ConfigurationTarget , IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration' ;
29
29
import { disposableTimeout , ThrottledDelayer } from 'vs/base/common/async' ;
30
- import { ITreeNode , ITreeFilter , ITreeSorter , ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree' ;
30
+ import { ITreeNode , ITreeFilter , ITreeSorter , ITreeContextMenuEvent , ITreeDragAndDrop , ITreeDragOverReaction } from 'vs/base/browser/ui/tree/tree' ;
31
31
import { ResourceTree , IResourceNode } from 'vs/base/common/resourceTree' ;
32
32
import { ISplice } from 'vs/base/common/sequence' ;
33
33
import { ICompressibleTreeRenderer , ICompressibleKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/tree/objectTree' ;
@@ -92,6 +92,10 @@ import { InlineCompletionsController } from 'vs/editor/contrib/inlineCompletions
92
92
import { CodeActionController } from 'vs/editor/contrib/codeAction/browser/codeActionController' ;
93
93
import { IResolvedTextEditorModel , ITextModelContentProvider , ITextModelService } from 'vs/editor/common/services/resolverService' ;
94
94
import { Schemas } from 'vs/base/common/network' ;
95
+ import { IDragAndDropData } from 'vs/base/browser/dnd' ;
96
+ import { fillEditorsDragData } from 'vs/workbench/browser/dnd' ;
97
+ import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView' ;
98
+ import { CodeDataTransfers } from 'vs/platform/dnd/browser/dnd' ;
95
99
96
100
type TreeElement = ISCMRepository | ISCMInput | ISCMActionButton | ISCMResourceGroup | IResourceNode < ISCMResource , ISCMResourceGroup > | ISCMResource ;
97
101
@@ -166,6 +170,58 @@ class ActionButtonRenderer implements ICompressibleTreeRenderer<ISCMActionButton
166
170
}
167
171
}
168
172
173
+
174
+ class SCMTreeDragAndDrop implements ITreeDragAndDrop < TreeElement > {
175
+ constructor ( private readonly instantiationService : IInstantiationService ) { }
176
+
177
+ getDragURI ( element : TreeElement ) : string | null {
178
+ if ( isSCMResource ( element ) ) {
179
+ return element . sourceUri . toString ( ) ;
180
+ }
181
+
182
+ return null ;
183
+ }
184
+
185
+ onDragStart ( data : IDragAndDropData , originalEvent : DragEvent ) : void {
186
+ const items = SCMTreeDragAndDrop . getResourcesFromDragAndDropData ( data as ElementsDragAndDropData < TreeElement , TreeElement [ ] > ) ;
187
+ if ( originalEvent . dataTransfer && items ?. length ) {
188
+ this . instantiationService . invokeFunction ( accessor => fillEditorsDragData ( accessor , items , originalEvent ) ) ;
189
+
190
+ const fileResources = items . filter ( s => s . scheme === Schemas . file ) . map ( r => r . fsPath ) ;
191
+ if ( fileResources . length ) {
192
+ originalEvent . dataTransfer . setData ( CodeDataTransfers . FILES , JSON . stringify ( fileResources ) ) ;
193
+ }
194
+ }
195
+ }
196
+
197
+ getDragLabel ( elements : TreeElement [ ] , originalEvent : DragEvent ) : string | undefined {
198
+ if ( elements . length === 1 ) {
199
+ const element = elements [ 0 ] ;
200
+ if ( isSCMResource ( element ) ) {
201
+ return basename ( element . sourceUri ) ;
202
+ }
203
+ }
204
+
205
+ return String ( elements . length ) ;
206
+ }
207
+
208
+ onDragOver ( data : IDragAndDropData , targetElement : TreeElement | undefined , targetIndex : number | undefined , originalEvent : DragEvent ) : boolean | ITreeDragOverReaction {
209
+ return true ;
210
+ }
211
+
212
+ drop ( data : IDragAndDropData , targetElement : TreeElement | undefined , targetIndex : number | undefined , originalEvent : DragEvent ) : void { }
213
+
214
+ private static getResourcesFromDragAndDropData ( data : ElementsDragAndDropData < TreeElement , TreeElement [ ] > ) : URI [ ] {
215
+ const uris : URI [ ] = [ ] ;
216
+ for ( const element of [ ...data . context ?? [ ] , ...data . elements ] ) {
217
+ if ( isSCMResource ( element ) ) {
218
+ uris . push ( element . sourceUri ) ;
219
+ }
220
+ }
221
+ return uris ;
222
+ }
223
+ }
224
+
169
225
interface InputTemplate {
170
226
readonly inputWidget : SCMInputWidget ;
171
227
readonly elementDisposables : DisposableStore ;
@@ -2307,6 +2363,7 @@ export class SCMViewPane extends ViewPane {
2307
2363
const sorter = new SCMTreeSorter ( ( ) => this . _viewModel ) ;
2308
2364
const keyboardNavigationLabelProvider = this . instantiationService . createInstance ( SCMTreeKeyboardNavigationLabelProvider , ( ) => this . _viewModel ) ;
2309
2365
const identityProvider = new SCMResourceIdentityProvider ( ) ;
2366
+ const dnd = new SCMTreeDragAndDrop ( this . instantiationService ) ;
2310
2367
2311
2368
this . tree = this . instantiationService . createInstance (
2312
2369
WorkbenchCompressibleObjectTree ,
@@ -2317,6 +2374,7 @@ export class SCMViewPane extends ViewPane {
2317
2374
{
2318
2375
transformOptimization : false ,
2319
2376
identityProvider,
2377
+ dnd,
2320
2378
horizontalScrolling : false ,
2321
2379
setRowLineHeight : false ,
2322
2380
filter,
0 commit comments