AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[Techdemo] Move Rows in a ListView

 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Obi-Wahn



Joined: 20 Apr 2006
Posts: 75
Location: Vienna

PostPosted: Sat Jul 31, 2010 6:00 pm    Post subject: [Techdemo] Move Rows in a ListView Reply with quote

I searched for a Function for a Script to move Rows in a ListView to sort them manually, but I just found a little hint.

So I decided to write my own function...

It also works (now) with multible selections...

Code:
Gui, +LastFound
Gui, Add, Listview, w360 h300 vmylistview, test|test2|test3|test4
   LV_Modifycol(1, 60)
   LV_Modifycol(2, 60)
   LV_Modifycol(3, 60)
   LV_Modifycol(4, 60)

Loop, 10
   LV_Add("", A_Index, "-" A_Index, (10 - A_Index), "x" A_Index)
   
Gui, Show, Center AutoSize, TestGUI
Return

GuiClose:
GuiEscape:
ExitApp

PgUp::LV_MoveRow()
PgDn::LV_MoveRow(false)

LV_MoveRow(moveup = true) {
   ; Original by diebagger (Guest) from:
   ; http://de.autohotkey.com/forum/viewtopic.php?p=58526#58526
   ; Slightly Modifyed by Obi-Wahn
   If moveup not in 1,0
      Return   ; If direction not up or down (true or false)
   while x := LV_GetNext(x)   ; Get selected lines
      i := A_Index, i%i% := x
   If (!i) || ((i1 < 2) && moveup) || ((i%i% = LV_GetCount()) && !moveup)
      Return   ; Break Function if: nothing selected, (first selected < 2 AND moveup = true) [header bug]
            ; OR (last selected = LV_GetCount() AND moveup = false) [delete bug]
   cc := LV_GetCount("Col"), fr := LV_GetNext(0, "Focused"), d := moveup ? -1 : 1
   ; Count Columns, Query Line Number of next selected, set direction math.
   Loop, %i% {   ; Loop selected lines
      r := moveup ? A_Index : i - A_Index + 1, ro := i%r%, rn := ro + d
      ; Calculate row up or down, ro (current row), rn (target row)
      Loop, %cc% {   ; Loop through header count
         LV_GetText(to, ro, A_Index), LV_GetText(tn, rn, A_Index)
         ; Query Text from Current and Targetrow
         LV_Modify(rn, "Col" A_Index, to), LV_Modify(ro, "Col" A_Index, tn)
         ; Modify Rows (switch text)
      }
      LV_Modify(ro, "-select -focus"), LV_Modify(rn, "select vis")
      If (ro = fr)
         LV_Modify(rn, "Focus")
   }
}


Have a nice Weekend

EDIT 02.08.2010: Bug killed thanks to diebagger


Last edited by Obi-Wahn on Mon Aug 02, 2010 10:57 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
SoLong&Thx4AllTheFish



Joined: 27 May 2007
Posts: 4999

PostPosted: Sat Jul 31, 2010 6:12 pm    Post subject: Reply with quote

Very nice and very useful, small bug: if you select multiple rows and move them DOWN the header appears as extra row each time you press pagedown.
_________________
AHK Wiki FAQ
TF : Text files & strings lib, TF Forum
Back to top
View user's profile Send private message
Obi-Wahn



Joined: 20 Apr 2006
Posts: 75
Location: Vienna

PostPosted: Sat Jul 31, 2010 6:36 pm    Post subject: Reply with quote

Thx 4 Reply.

I didn't noticed the but until now, because I tried it every time with only 2 selected rows -> works like a charm.

I'll try to kill that bug...
Back to top
View user's profile Send private message Visit poster's website
jchang
Guest





PostPosted: Thu Sep 09, 2010 1:08 pm    Post subject: Re: [Techdemo] Move Rows in a ListView Reply with quote

It's nice,but if the listview have icons,now it can't move the icon synchronous,here is a example of listview,I suggest improve your script so that the icon can be moved at the same time
Code:

Gui +Resize


Gui, Add, Button, Default gButtonLoadFolder, Load a folder
Gui, Add, Button, x+20 gButtonClear, Clear List
Gui, Add, Button, x+20, Switch View


Gui, Add, ListView, xm r20 w700 vMyListView gMyListView, Name|In Folder|Size (KB)|Type
LV_ModifyCol(3, "Integer")  ;


ImageListID1 := IL_Create(10)
ImageListID2 := IL_Create(10, 10, true)  ; A list of large icons to go with the small ones.


LV_SetImageList(ImageListID1)
LV_SetImageList(ImageListID2)


Menu, MyContextMenu, Add, Open, ContextOpenFile
Menu, MyContextMenu, Add, Properties, ContextProperties
Menu, MyContextMenu, Add, Clear from ListView, ContextClearRows
Menu, MyContextMenu, Default, Open 


Gui, Show
return


ButtonLoadFolder:
Gui +OwnDialogs 
FileSelectFolder, Folder,, 3, Select a folder to read:
if not Folder 
    return


StringRight, LastChar, Folder, 1
if LastChar = \
    StringTrimRight, Folder, Folder, 1 


VarSetCapacity(Filename, 260)
sfi_size = 352
VarSetCapacity(sfi, sfi_size)


GuiControl, -Redraw, MyListView
Loop %Folder%\*.*
{
    FileName := A_LoopFileFullPath

   
    SplitPath, FileName,,, FileExt
    if FileExt in EXE,ICO,ANI,CUR
    {
        ExtID := FileExt 
        IconNumber = 0
    }
    else 
    {
        ExtID = 0 
        Loop 7   
        {
            StringMid, ExtChar, FileExt, A_Index, 1
            if not ExtChar 
                break
           
            ExtID := ExtID | (Asc(ExtChar) << (8 * (A_Index - 1)))
        }
       
        IconNumber := IconArray%ExtID%
    }
    if not IconNumber 
    {
     
        if not DllCall("Shell32\SHGetFileInfoA", "str", FileName, "uint", 0, "str", sfi, "uint", sfi_size, "uint", 0x101)  ; 0x101 是 SHGFI_ICON+SHGFI_SMALLICON
            IconNumber = 9999999 
        else
        {
            ; Extract the hIcon member from the structure:
            hIcon = 0
            Loop 4
                hIcon += *(&sfi + A_Index-1) << 8*(A_Index-1)
            ; Add the HICON directly to the small-icon and large-icon lists.
            ; Below uses +1 to convert the returned index from zero-based to one-based:
            IconNumber := DllCall("ImageList_ReplaceIcon", "uint", ImageListID1, "int", -1, "uint", hIcon) + 1
            DllCall("ImageList_ReplaceIcon", "uint", ImageListID2, "int", -1, "uint", hIcon)
            ; Now that it's been copied into the ImageLists, the original should be destroyed:
            DllCall("DestroyIcon", "uint", hIcon)
            ; Cache the icon to save memory and improve loading performance:
            IconArray%ExtID% := IconNumber
        }
    }

    ; Create the new row in the ListView and assign it the icon number determined above:
    LV_Add("Icon" . IconNumber, A_LoopFileName, A_LoopFileDir, A_LoopFileSizeKB, FileExt)
}
GuiControl, +Redraw, MyListView
LV_ModifyCol()
LV_ModifyCol(3, 60)
return


ButtonClear:
LV_Delete() 
return

ButtonSwitchView:
if not IconView
    GuiControl, +Icon, MyListView   
else
    GuiControl, +Report, MyListView 
IconView := not IconView           
return

MyListView:
if A_GuiEvent = DoubleClick 
{
    LV_GetText(FileName, A_EventInfo, 1)
    LV_GetText(FileDir, A_EventInfo, 2) 
    Run %FileDir%\%FileName%,, UseErrorLevel
    if ErrorLevel
        MsgBox Could not open "%FileDir%\%FileName%".
}
return

GuiContextMenu:
if A_GuiControl <> MyListView 
    return

Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY%
return

ContextOpenFile:
ContextProperties:

FocusedRowNumber := LV_GetNext(0, "F") 
if not FocusedRowNumber
    return
LV_GetText(FileName, FocusedRowNumber, 1)
LV_GetText(FileDir, FocusedRowNumber, 2)
IfInString A_ThisMenuItem, Open
    Run %FileDir%\%FileName%,, UseErrorLevel
else
    Run Properties "%FileDir%\%FileName%",, UseErrorLevel
if ErrorLevel
    MsgBox Could not perform requested action on "%FileDir%\%FileName%".
return

ContextClearRows:
RowNumber = 0 
Loop
{
   
    RowNumber := LV_GetNext(RowNumber - 1)
    if not RowNumber
        break
    LV_Delete(RowNumber) 
}
return

GuiSize:
if A_EventInfo = 1
    return

GuiControl, Move, MyListView, % "W" . (A_GuiWidth - 20) . " H" . (A_GuiHeight - 40)
return

GuiClose: 
ExitApp

PgUp::LV_MoveRow()
PgDn::LV_MoveRow(false)

LV_MoveRow(moveup = true) {
   ; Original by diebagger (Guest) from:
   ; http://de.autohotkey.com/forum/viewtopic.php?p=58526#58526
   ; Slightly Modifyed by Obi-Wahn
   If moveup not in 1,0
      Return   ; If direction not up or down (true or false)
   while x := LV_GetNext(x)   ; Get selected lines
      i := A_Index, i%i% := x
   If (!i) || ((i1 < 2) && moveup) || ((i%i% = LV_GetCount()) && !moveup)
      Return   ; Break Function if: nothing selected, (first selected < 2 AND moveup = true) [header bug]
            ; OR (last selected = LV_GetCount() AND moveup = false) [delete bug]
   cc := LV_GetCount("Col"), fr := LV_GetNext(0, "Focused"), d := moveup ? -1 : 1
   ; Count Columns, Query Line Number of next selected, set direction math.
   Loop, %i% {   ; Loop selected lines
      r := moveup ? A_Index : i - A_Index + 1, ro := i%r%, rn := ro + d
      ; Calculate row up or down, ro (current row), rn (target row)
      Loop, %cc% {   ; Loop through header count
         LV_GetText(to, ro, A_Index), LV_GetText(tn, rn, A_Index)
         ; Query Text from Current and Targetrow
         LV_Modify(rn, "Col" A_Index, to), LV_Modify(ro, "Col" A_Index, tn)
         ; Modify Rows (switch text)
      }
      LV_Modify(ro, "-select -focus"), LV_Modify(rn, "select vis")
      If (ro = fr)
     ;gosub,icon
         LV_Modify(rn, "Focus")
      ;LV_Modify("Icon" . IconNumber,rn)
   }

}
Back to top
luffy



Joined: 11 Mar 2010
Posts: 177
Location: glendale, az

PostPosted: Tue Sep 14, 2010 3:35 am    Post subject: Reply with quote

that's great. i'm very proud of you for getting that function going.

a bit off topic, but i hope some you could help me anyway. could you tell me how to delete a line on a list and/or reset a list to remove all lines? i'm not seing it in the help file for some reason. probly cause i'm quasi retarded.
_________________
2+2 does not equal 3, and 9/11 was a big fat inside job!
Back to top
View user's profile Send private message Send e-mail Visit poster's website
TomXIII



Joined: 14 Apr 2009
Posts: 182

PostPosted: Tue Sep 14, 2010 7:36 am    Post subject: Reply with quote

@Obi-Wahn : Thanks a lot!
May be you could look into my LvLauncher project.
In the include file "LvFunctions3.ahk" there is my solution to move multiple rows with the corresponding icons.
LvLauncher v0.3
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group