Page 1 sur 1

[OK] Problème avec le Drag&Drop+multiselection

Publié : mer. 01/mars/2017 10:06
par Teckzor
Bonjour à tous !

J'ai un petit problème dont je n'arrive pas à trouver de solution : Je souhaite déplacer plusieurs items de la ListIcon vers l'endroit ou l'on drop, cependant (Et je ne sais pas pourquoi) lorsque je sélectionne des items et que je veux les déplacer en dessous de cette sélection, les items ne sont pas déplacer.
Le GetgadgetState que j'utilise dans la procédure Drop() ne prend pas en compte la position du drop Uniquement lorsque je déplace en dessous de la sélection. Le programme fonctionne correctement au dessus de la selection par contre. :roll:
Pour info, je cherche à faire un programme pour trier les fichiers automatiquement et les renommer en conséquence.

Merci d'avance pour votre aide ! :lol:

Code : Tout sélectionner

; 
;-  Enumeration 
Enumeration image
  #FlecheUP
  #FlecheDown
  #FlecheTraitUp
  #FlecheTraitDown
  #Sup
  #ValidOK
EndEnumeration
Enumeration Gadget
  #TG_ChooseFile
  #BG_OKChoose
  #SG_DestiFile
  #SG_ChooseWord
  #BG_OKChooseWord
  #TG_ChooseWord
  #PBG
  #BG_ValidSearch
  #LVG_NameList
  #BG_Down
  #BG_Up
  #BG_TEST
  #BG_DEL
  #BG_INCFin
  #BG_DECDeb
EndEnumeration
;} End Enumeration
;-  Constantes 
UsePNGImageDecoder()
#MainWind=0
#SecWind=1
#MenuTitle=0
Global gWindWidth=350,gWindHeight=400
LoadImage(#FlecheUP,RequireFlecheUP.png)
LoadImage(#FlecheDown,RequireFlecheDown.png)
LoadImage(#FlecheTraitUp,RequireFlecheTraitUp.png)
LoadImage(#FlecheTraitDown,RequireFlecheTraitD.png)
LoadImage(#Sup,RequireDelete.png)
; LoadImage(#ValidOK,RequireValide.png)
; ResizeImage(#ValidOK,60,30)
;} END Constantes
;-  Structure, Map, List 
Structure _drag
  text$
  depart.i
  arrive.i
EndStructure
Global NewList Nom.s()
Global NewList Pos_Select.i()
;} END Structure, Map, List
;-  Variable 
Global drag._drag
Global StartPath$ = HPurebasicProgrammesIncrémentation de fichier
;} END Variable
;-  Procedures 
Procedure OpenMainWind()
  OpenWindow(#MainWind,0,0,gWindWidth,gWindHeight,IncFile,#PB_Window_ScreenCentered#PB_Window_SystemMenu#PB_Window_MinimizeGadget)
  TextGadget(#TG_ChooseFile,10,20,gWindWidth-20,20,Veuillez choisir un dossier de destination ,#PB_Text_Center)
  StringGadget(#SG_DestiFile,10,60,gWindWidth-20,20,)
  ButtonGadget(#BG_OKChoose,(gWindWidth2)-15,100,30,30,...)
  StringGadget(#SG_ChooseWord,10,gWindHeight-180,220,20,)
  TextGadget(#TG_ChooseWord,10,gWindHeight-215,gWindWidth-20,40,Veuillez entrer le nom du premier fichier à renommer et chosir l'ordre des fichiers,#PB_Text_Center)
  ProgressBarGadget(#PBG,10,gWindHeight-40,gWindWidth-20,30,0,10)
  ButtonGadget(#BG_ValidSearch,(gWindWidth2)-30,gWindHeight-110,60,30,Valider)
  ListIconGadget(#LVG_NameList,360,60,280,gWindHeight-70,n°,30,#PB_ListIcon_GridLines#PB_ListIcon_FullRowSelect #PB_ListIcon_AlwaysShowSelection#PB_ListIcon_MultiSelect)
  AddGadgetColumn(#LVG_NameList,1,Noms des fichiers,245)
  DisableGadget(#LVG_NameList,1)
  HideGadget(#LVG_NameList,1)
  ButtonImageGadget(#BG_Down,360,10,40,40,ImageID(#FlecheDown))
  ButtonImageGadget(#BG_Up,410,10,40,40,ImageID(#FlecheUP))
  ButtonImageGadget(#BG_INCFin,460,10,40,40,ImageID(#FlecheTraitDown))
  ButtonImageGadget(#BG_DECDeb,510,10,40,40,ImageID(#FlecheTraitUp))
  ButtonImageGadget(#BG_DEL,600,10,40,40,ImageID(#sup))
  DisableGadget(#BG_Down,1)
  HideGadget(#BG_Down,1)
  DisableGadget(#BG_Up,1)
  HideGadget(#BG_Up,1)
  DisableGadget(#BG_DEL,1)
  HideGadget(#BG_DEL,1)
  EnableGadgetDrop(#LVG_NameList,#PB_Drop_Text,#PB_Drag_Copy)
EndProcedure
Procedure ClearGadget()
  a=0
  ForEach Nom()
    SetGadgetItemText(#LVG_NameList,a,nom(),1)
    a+1
  Next
    SetGadgetState(#LVG_NameList,-1)
EndProcedure
Procedure SelectList()
ClearList(Pos_Select())
AddElement(Pos_Select())
Pos_Select() = GetGadgetState(#LVG_NameList)
For index = Pos_Select()+1 To CountGadgetItems(#LVG_NameList)-1
  If GetGadgetItemState(#LVG_NameList,index) = #PB_ListIcon_Selected
    AddElement(Pos_Select())
    Pos_Select() = index
  EndIf
Next
ForEach Pos_Select()
  Debug Pos_Select()
Next

EndProcedure
Procedure Drag()
  If EventType() = #PB_EventType_DragStart
    SelectList()
    dragdepart=GetGadgetState(#LVG_NameList)
    dragtext$=GetGadgetItemText(#LVG_NameList,GetGadgetState(#LVG_NameList),1)
    DragText(dragtext$)
  EndIf
EndProcedure
Procedure Drop()
  If EventGadget() = #LVG_NameList
      Debug  GetGadgetState(#LVG_NameList) 
      dragarrive = GetGadgetState(#LVG_NameList)
  
    If dragarrive-1
      arrive = SelectElement(nom(),dragarrive)
      ForEach Pos_Select()
        If Pos_Select()-1CountGadgetItems(#LVG_NameList) And Pos_Select()-1
          SelectElement(Nom(),Pos_Select())
          MoveElement(nom(),#PB_List_Before,arrive)
        EndIf
      Next 
    EndIf
    ClearGadget()
    For a=1 To CountGadgetItems(#LVG_NameList)  
      SetGadgetItemText(#LVG_NameList,a-1,Str(a),0)
    Next
  EndIf 
EndProcedure
Procedure ResizeWind()
  DisableGadget(#BG_Down,0)
  HideGadget(#BG_Down,0)
  DisableGadget(#BG_Up,0)
  HideGadget(#BG_Up,0)
  DisableGadget(#LVG_NameList,0)
  HideGadget(#LVG_NameList,0)
  DisableGadget(#BG_DEL,0)
  HideGadget(#BG_DEL,0)
 ClearGadgetItems(#LVG_NameList)
  a=1
  ForEach Nom()
    AddGadgetItem(#LVG_NameList,-1,Str(a)+ Chr(10)+ nom())
    a+1
  Next
  ResizeWindow(#MainWind,#PB_Ignore,#PB_Ignore,650,#PB_Ignore)
EndProcedure
Procedure RenameListe()
  SetGadgetAttribute(#PBG, #PB_ProgressBar_Maximum,CountGadgetItems(#LVG_NameList))
  numero = 1
  ForEach Nom()
    SetGadgetState(#pbg,numero)
    If numero10
      texte$ = GetGadgetText(#SG_ChooseWord) + + RSet(Str(numero),2,0) +. + GetExtensionPart(nom())
    EndIf
    If numero9
      texte$ = GetGadgetText(#SG_ChooseWord) + + Str(numero) +. + GetExtensionPart(nom())
    EndIf
;     Debug ancien fichier  + StartPath$ + nom()
;     Debug nouveau fichier + StartPath$ + texte$
;   RenameFile(StartPath$ + nom(),StartPath$ + texte$)  ;! ! ! à enlever pour test.
    nom() = texte$
    SetGadgetItemText(#LVG_NameList,numero-1,texte$,1)
    numero+1
  Next
  MessageRequester(succès,Convertion des fichiers terminés)
  SetGadgetState(#pbg,0)
EndProcedure
Procedure SelectDossier() 
  SelectFile$=GetGadgetText(#SG_DestiFile)
  selectFile$=PathRequester(Selectionne un dossier,StartPath$) 
  StartPath$=selectFile$
  If selectFile$
    ClearList(nom())
    ClearGadgetItems(#LVG_NameList)
    SetGadgetText(#SG_DestiFile,selectFile$)
    ExamineDirectory(0,SelectFile$,)
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        AddElement(nom())
        nom()=DirectoryEntryName(0)
      EndIf
    Wend
    FinishDirectory(0)
    SortList(nom(),#PB_Sort_Ascending)
    ResizeWind()
  EndIf
EndProcedure
Procedure TrieNom()
  If GetGadgetText(#SG_DestiFile) And GetGadgetText(#SG_ChooseWord)
    SelectFile$=GetGadgetText(#SG_DestiFile)
    If MessageRequester(Validation, Le nom du premier fichier de la liste sera   +GetGadgetText(#SG_ChooseWord)+ 01 +Chr(13)+Etes-vous sur de vouloir renommer tous les fichiers ,#PB_MessageRequester_YesNo)=#PB_MessageRequester_Yes
      RenameListe()
    EndIf 
  Else
    MessageRequester(Erreur,Veuillez renseigner les champs obligatoires)
  EndIf
EndProcedure
Procedure Delete()
  If GetGadgetState(#LVG_NameList)-1
    SelectList()
    SortList(Pos_Select(),#PB_Sort_Descending)
    ForEach Pos_Select()
        RemoveGadgetItem(#LVG_NameList,Pos_Select())
        SelectElement (nom(),Pos_Select())
        DeleteElement(nom())        
    Next
    For a=1 To CountGadgetItems(#LVG_NameList)  
      SetGadgetItemText(#LVG_NameList,a-1,Str(a),0)
    Next
  EndIf
EndProcedure
Procedure DownName() 
  If GetGadgetState(#LVG_NameList)-1 And GetGadgetState(#LVG_NameList)+1CountGadgetItems(#LVG_NameList) 
    SelectList()
    SortList(Pos_Select(),#PB_Sort_Descending)
    FirstElement(Pos_Select())
    arrive = SelectElement(nom(),Pos_Select()+1)
    ForEach Pos_Select()
      If Pos_Select()+1CountGadgetItems(#LVG_NameList) And Pos_Select()-1 And arrive0
        SelectElement(nom(),Pos_Select())
        MoveElement (nom(),#PB_List_After,arrive)
        Pos_Select() = ListIndex(nom())
      EndIf
    Next Pos_Select()
  ClearGadget()
  ForEach Pos_Select()
    SetGadgetItemState(#LVG_NameList,Pos_Select(),#PB_ListIcon_Selected)  
  Next
  EndIf
EndProcedure
Procedure UpName()
  If GetGadgetState(#LVG_NameList)-1 And GetGadgetState(#LVG_NameList)-1=0
    SelectList()
    FirstElement(Pos_Select())
    arrive = SelectElement(nom(),Pos_Select()-1)
    ForEach Pos_Select()
      If Pos_Select()-1CountGadgetItems(#LVG_NameList) And Pos_Select()-1
        SelectElement(nom(),Pos_Select())
        MoveElement (nom(),#PB_List_Before,arrive)
        Pos_Select() = ListIndex(nom())
      EndIf
    Next Pos_Select()
    ClearGadget()
    ForEach Pos_Select()
      SetGadgetItemState(#LVG_NameList,Pos_Select(),#PB_ListIcon_Selected)  
    Next
  EndIf
EndProcedure
Procedure UpTop()
  If GetGadgetState(#LVG_NameList)-1 And GetGadgetState(#LVG_NameList)-1=0
    SelectList()
    ForEach Pos_Select()
      If Pos_Select()-1CountGadgetItems(#LVG_NameList) And Pos_Select()-1
        SelectElement(Nom(),Pos_Select())
        MoveElement(nom(),#PB_List_First)
      EndIf
    Next 
    For n=1 To ListSize(Pos_Select())-1 
      SelectElement(Nom(),n)
      MoveElement(nom(),#PB_List_First)
    Next
    ClearGadget()
    For n=0 To ListSize(Pos_Select())-1
      SetGadgetItemState(#LVG_NameList,n,#PB_ListIcon_Selected)  
    Next
  EndIf
EndProcedure
Procedure DownBot()
  If GetGadgetState(#LVG_NameList)-1 And GetGadgetState(#LVG_NameList)+1CountGadgetItems(#LVG_NameList) 
    SelectList()
    SortList(Pos_Select(),#PB_Sort_Descending)
    ForEach Pos_Select()
      If Pos_Select()-1CountGadgetItems(#LVG_NameList) And Pos_Select()-1
        SelectElement(Nom(),Pos_Select())
        MoveElement(nom(),#PB_List_Last)
      EndIf
    Next 
    For n=ListSize(Nom())-1 To (ListSize(Nom())-ListSize(Pos_Select())) Step -1 
      SelectElement(Nom(),n)
      MoveElement(nom(),#PB_List_Last)
    Next
    ClearGadget()
    For n=ListSize(Nom()) To (ListSize(Nom())-ListSize(Pos_Select())) Step -1
      SetGadgetItemState(#LVG_NameList,n,#PB_ListIcon_Selected)  
    Next
  EndIf
EndProcedure
;} END Procédures
;-  Exec Init 
OpenMainWind()
;} END Exec Init
;-  Boucle Principale 
Repeat  
  Event=WaitWindowEvent()
  gExit=#False
  gStart=#False
  Select Event
    Case #PB_Event_CloseWindow
      gExit=#True
    Case #PB_Event_GadgetDrop
      Drop() ; Drop l'item qui a était drag précedemment.
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #LVG_NameList
          drag() ; Drag l'item selectionné.
        Case #BG_OKChoose
          SelectDossier() ; Selection du dossier + affichage des fichiers dans la listicon.
        Case #BG_ValidSearch
          TrieNom() ; Triage des fichiers de la listIcon.
        Case #BG_Down
          DownName() ; Descente des fichiers selectionnés.
        Case #BG_Up
          UpName() ; Montée des fichiers selectionnés.
        Case #BG_DEL
          Delete() ; Suppression des fichiers selectionnés.
        Case #BG_INCFin
          DownBot() ; Descente des fichiers selectionnés à la fin de la listicon.
        Case #BG_DECDeb
          UpTop() ; Montée des fichiers selectionnés à la fin de la listicon.
      EndSelect
  EndSelect
Until gExit=#True
End
;} End Boucle Principale

Re: Problème avec le Drag&Drop+multiselection

Publié : jeu. 02/mars/2017 12:33
par celtic88

Re: Problème avec le Drag&Drop+multiselection

Publié : jeu. 02/mars/2017 13:22
par Marc56
@Teckzor
- Ton code ne contient aucun "" ni | ni ; (sauf ceux en début de ligne)
- Tes images ne sont pas présentes

Fais plutôt une archive du tout et met la sur un site.
Exemple sur http://dl.free.fr/ (inutile d'avoir un compte free.fr)

:wink:

Re: Problème avec le Drag&Drop+multiselection

Publié : sam. 04/mars/2017 1:18
par Teckzor
Bonsoir Messieurs.

Tout d'abord merci de vos réponses :)

@Celtic88 : Merci beaucoup pour ton lien, je regarderais cela en détail dans la semaine :)

@Marc56 : Voici le lien avec les images et tout et tout => http://dl.free.fr/u4hi7YhT0

Re: Problème avec le Drag&Drop+multiselection

Publié : sam. 04/mars/2017 13:23
par Ar-S
Je n'ai pas trop le temps de regarder mais à coup de debug ton d&d vers le bas fonctionne sauf que tu as un soucis de -1 quelque part.
En gros si tu bouges l'élément 2 vers 4, l'inversion se fait du 3 vers 2 mais les ID sont bons.

Code : Tout sélectionner

; Dans Drag()
Debug "Element de départ n°" + Str(drag\depart) + " : " + Drag\text$
; Dans ta procédure Drop()
Debug "Element cible n°" + Str(drag\arrive) +" : " + nom()
Je crois que ton soucis vient de #PB_List_Before qui fonctionne si tu montes, mais si tu descends il faudra mettre un #PB_List_After
Donc mettre un If / else / endif dans ta procédure Drop() dans le For Each

C'est une théorie. à toi de vérifier.
Note que le code de Celtic88 est très bon (comme d'hab) mais ne fonctionnera que sous Windows car bourré d'API.

Re: Problème avec le Drag&Drop+multiselection

Publié : jeu. 16/mars/2017 12:45
par Teckzor
Bonjour Messieurs,

Grâce à un ami et à vos reponses, voici la correction :

Code : Tout sélectionner

Procedure Drag()
  If EventType() = #PB_EventType_DragStart
    SelectList()
    drag\depart=GetGadgetState(#LVG_NameList)
    drag\text$=GetGadgetItemText(#LVG_NameList,GetGadgetState(#LVG_NameList),1)
    drag\my = WindowMouseY(#MainWind)
    DragText(drag\text$)
  EndIf
EndProcedure

Procedure Drop()
  Protected sens.b
  If EventGadget() = #LVG_NameList
    drag\arrive = GetGadgetState(#LVG_NameList)
    If drag\my > WindowMouseY(#MainWind)
      sens = 0 ; On monte 
    ElseIf drag\arrive > -1
      nb_ligne=CountGadgetItems(#LVG_NameList)-1
      sens = 1 ; On descend
      For i=0 To nb_ligne
        If GetGadgetItemState(#LVG_NameList,nb_ligne-i)
          drag\arrive = nb_ligne - i
          Break
        EndIf      
      Next     
    EndIf
    If drag\arrive>-1
      *arrive = SelectElement(nom(),drag\arrive)
      Select sens
        Case 1 ; On descend
          If drag\arrive>ListSize(Pos_Select())
            LastElement(Pos_Select())
            For i=0 To ListSize(Pos_Select())-1
              If Pos_Select() > -1
                SelectElement(nom(),Pos_Select())
                MoveElement(nom(),#PB_List_Before,*arrive)
              EndIf  
              PreviousElement(Pos_Select())
            Next
            If ListSize(Pos_Select())>1 
              For i=1 To ListSize(Pos_Select())
                SelectElement(nom(),drag\arrive-i)
                MoveElement(nom(),#PB_List_Before,*arrive) 
              Next
            EndIf
          Else ; Si on drop en dehors des items, on met les items selectionnés en fin de liste.
            LastElement(Pos_Select())
            For i=0 To ListSize(Pos_Select())-1
              If Pos_Select() > -1
                SelectElement(nom(),Pos_Select())
                MoveElement(nom(),#PB_List_Last)
              EndIf  
              PreviousElement(Pos_Select())
            Next
            For i=1 To ListSize(Pos_Select())-1
              SelectElement(nom(),ListSize(nom())-(i+1))
              MoveElement(nom(),#PB_List_Last)
            Next
          EndIf 
          
        Default ; On monte
          ForEach Pos_Select()
            If Pos_Select()<>-1
              SelectElement(Nom(),Pos_Select())
              MoveElement(nom(),#PB_List_Before,*arrive)
            EndIf
          Next          
      EndSelect
    Else       ; Descente d'un seul item en fin de liste.         
      SelectElement(nom(),Pos_Select())
      MoveElement(nom(),#PB_List_Last)
    EndIf
    ClearGadget()
    For a=1 To CountGadgetItems(#LVG_NameList)  
      SetGadgetItemText(#LVG_NameList,a-1,Str(a),0)
    Next
  EndIf 
EndProcedure
merci pour votre aide !