Button: Merge Folders v2

This button is an update and enhanced version of the original by @leo here.

Overview

Just select the folders* you want to merge and press the Merge Folders button to get the dialog. You'll be able to choose one of the selected folders as the target or create a new folder as the target.
*only ones in the same active tab will be merged

1

If you click the New button you'll be prompted to input a name for the new target folder. By default the name is the same as the first selected folder.

2

Once you click Ok, the job is done in the twinkling of an eye.

The old folders will be deleted at the end, as long as they are now empty. (They might not be empty if files in two folders had the same name and you chose to skip them.)

Download and install

Download Merge Folders.[your language].dcf above, then right click on a toolbar and select Customize... and drag the downloaded .dcf file to where you want the new button on your toolbar. Finally, click OK in the Customize window.

Changelog

[NEW] You can merge into one of the selected folders
[NEW] User friendly and fast action dialogs to allow multiple choice
[NEW] Dialog with a drop-down list of the selected folders
[FIX] Should be error proof now

Limitation

Currently, some features are missing such as:

  • Merge to a folder that is elsewhere from the current tab.
  • In flat view grouped mode, can not merge the selected subfolders, only the folders.

Note

If you want to improve this script, be my guest, post it in this thread and I will update this post.

Script Code

This is the code inside the download above, reproduced so you can see how the button works without downloading it:

' Console output function
' Sub Say(txt)
' 	DOpus.Create.Command.RunCommand("Say " & txt & "")
' End Sub

Function OnClick(ByRef ClickData)

	' INITIATE VARIABLES
	Match = 0
    Set cmd = ClickData.Func.command

	' Check the right kind of things are selected.
	If ClickData.Func.sourcetab.selected_dirs.count < 2 Then
		Set dlg = ClickData.Func.Dlg
		dlg.Request "2 folders at least are to be selected"  & vbCrLf & "Select serveral fodlers then run the command again", "OK"
		Exit Function
	End If

	If ClickData.Func.sourcetab.selected_files.count <> 0 Then
		Set dlg = ClickData.Func.Dlg
		dlg.Request "Only folders are to be selected."  & vbCrLf & "Unselect file(s) then run the command again", "OK"
		Exit Function
	End If

' 	DOpus.ClearOutput
	' Get the number of folder that are selected
	AllSel = ClickData.Func.sourcetab.selected_dirs.count

	' Concatenate all selected folders name to create a vector list
    Set SelDirCollection = DOpus.Create.Vector
	For Each SelDir In ClickData.Func.sourcetab.selected_dirs
        SelDirCollection.push_back SelDir.name
	Next

	' Create 1st Dialog object.
	Set dlg = DOpus.Dlg

	' Initialise the object to display a message with three buttons, one of which is a drop-down with multiple choices' This dialog also has a warning icon, a text field allowing the user to enter a line of text,' and two checkboxes which the user can turn on or off.
	dlg.window = DOpus.Listers(0)
	dlg.title = "Merge the " & AllSel & " selected folders"
	dlg.message = "Select existing target" & vbCrLf & "or create a new one with the last button below."
	dlg.buttons = "&OK|&Cancel|&New"
	dlg.icon = "question"
	dlg.sort = true
	dlg.choices = SelDirCollection
	dlg.selection = 0

	' Show the dialog and print the results to the script log
	ret = dlg.Show
' 	DOpus.Output "Dialog.Show returned " & ret
' 	DOpus.Output "The selected choice was " & dlg.choices(dlg.selection)
	If ret = 2 then ' When user cancel action
		Exit Function
	End If
	TargetDir = dlg.choices(dlg.selection)
    Set dlg = Nothing ' destroy 1st dialog prompt

	If (IsEmpty(TargetDir)) Then
        Set dlg = DOpus.Dlg
    	dlg.Request "ERROR : Target folder is invalid." & vbCrLf  & vbCrLf & "Nothing can't be done", "OK"
		Exit Function
	End If

	' When user want to create new target folder
	If ret = 0 Then
    	' Create 2nd Dialog object.
        Set dlg = DOpus.Dlg
		' Initialise the object to display a message with three buttons, one of which is a drop-down with multiple choices' This dialog also has a warning icon, a text field allowing the user to enter a line of text,' and two checkboxes which the user can turn on or off.
		dlg.Window = DOpus.Listers(0)
		dlg.title = "Merge the " & AllSel & " selected folders"
		dlg.message = "You can create a new folder below"
		dlg.buttons = "&OK|&Cancel"
		dlg.icon = "question"
        dlg.default = ClickData.Func.sourcetab.selected_dirs(0).name
		dlg.Select = True
		dlg.max = 128  ' enable the text field
		' Show the dialog and print the results to the script log
		ret = dlg.Show
' 		DOpus.Output "Dialog.Show returned " & ret
' 		DOpus.Output "The string you entered was " & dlg.input
		If ret = 0 then ' When user cancel action
			Exit Function
		End If
		TargetDir = dlg.input
    	Set dlg = Nothing ' destroy 2nd dialog prompt

		If (IsEmpty(TargetDir)) Then
			Set dlg = ClickData.Func.Dlg
	    	dlg.Request "You haven't input a name for new folder." & vbCrLf  & vbCrLf & "Nothing will be done", "OK"
			Exit Function
		End If
	End If

	' Handle the case the user want to move the files into one of the selected folder
	' Check if TargetDir matches one of the selected folder to avoid errors.
    For Each SelDir In ClickData.Func.sourcetab.selected_dirs
		If TargetDir = SelDir.name Then
			cmd.RemoveFile(SelDir) ' remove the dir from the collection so command won't apply to it
			Match = 1
			' Say("<white,red>STOP<black> : <dgreen>TargetDirEdited<black> = <red>SelDir : <white,red>" & SelDir.name & "")
		End If
	Next

	' Move everything from the selected folders into the new dir.
	If Match = 1 then ' Case when target folder matches a selected one
		' Say("<white,red>STOP<black> : <red>Match = " & Match & "")
		cmd.RunCommand "Copy MOVE ""{filepath$}\*"" TO=""{sourcepath$}\" & TargetDir & """"
	Else
		' Say("<white,dgreen>OK<black> : <dgreen>Match = " & Match & "")
		cmd.RunCommand "Copy MOVE ""{filepath$}\*"" TO=""{sourcepath$}"" CREATEFOLDER=""" & TargetDir & """"
	End If

	' Check each selected folder and, if it is now empty, delete it.
	cmd.ClearFiles

	For Each SelDir In ClickData.Func.sourcetab.selected_dirs
		Set FolderEnum = DOpus.FSUtil.ReadDir(SelDir, False)
		If (FolderEnum.Complete) Then
			FolderEnum.Close ' So the folder is not locked.
			cmd.AddFile SelDir
			cmd.RunCommand "Delete QUIET"
			cmd.ClearFiles
		End If
	Next

End Function
6 Likes

I like the wizard approach here. Merging folders comes up quite often, but not that often, that you'd create need a zillion buttons/scripts to handle all the situations. Some simple predefined buttons/commands would be nice though for the more regular scenarios. I currently use flatview and selection "magic" to get these things done.

Some ideas, just in case you have time to kill: o)

  • create a MergeFolders script command (not using a dialog by default)
  • add switches and options to pass/determine the resulting final foldername
  • wizard mode (dialog) without actions builtin, just prompt, fetch config, then run "yourself" (the command) with the right arguments
  • add a deep/recursive option to pull all files from all subdirectories (take care for files with identical names automatically)
  • add an option to just copy, so in case something goes wrong or you picked the wrong options, you don't end up with a big mess
  • make sure to support flat view mode
  • allow merging to destination
  • allow a filter to be used (?)

Thanks! o)

lol you killed me, man!

I should tell this is my first script and my skills in vbs or jScript are very limited so as my time. I'm pretty proud of myself for having been able to do it.

Yeah, I thought my script would cover the more common and simple needs and regular scenarios you mentionned. I didn't need more at that time and still don't for now.

Among the ideas you shared, I'd love to realize those as a priority:

  • add an option to just copy, so in case something goes wrong or you picked the wrong options, you don't end up with a big mess
  • allow merging to destination

Comments about your other ideas:

  • create a MergeFolders script command (not using a dialog by default)

Yes I wanted to do that but it seemed more complex and hard to realize due to my poor skills for now. I wanted to do it fast so I chose the simple solution to just enhance an existing script. The base was here, I just needed to tweak it to suit my needs and fix bugs. Could you point me toward an existing script add-in that I could analyze to learn how to do it for this script?

  • add switches and options to pass/determine the resulting final foldername

Could you give me some examples? What would be your needs?

  • wizard mode (dialog) without actions builtin, just prompt, fetch config, then run "yourself" (the command) with the right arguments

Hehe, I'm more a wizard approach guy because I know I won't be able to remember the needed arguments to pass if I don't use them everyday. And I know average users are like me. But your idea should be doable if the script progresses as an add-in. The user could realize any button that suits ones needs.

  • make sure to support flat view mode

Currently, as shown in screenshots, it supports flat view grouped mode. I didn't even try the other flat view modes because I can't imagine a scenario how the user could use it.

  • add a deep/recursive option to pull all files from all subdirectories (take care for files with identical names automatically)

I'd like to be able to code that especially the take care for files with identical names automatically ^^' How do you think those files should be treated?[/li]

  • allow a filter to be used (?)

Same as above ^^'

I could provide a template, it would be in JScript though. Problem or challenge? o)

I was thinking of the mentioned options and features to be available as arguments - like so:

MergeFolders FOLDERS="foo","bar","xyz" [TARGETPATH=<here>,"\\custom\target"] [TARGETNAME=<auto>,none,first,last,"custom"] [MODE=<move>,copy,simulate] [OPTIONS=removeempty,deep,] [FILEEXISTS=<rename>,replace,keep] [FOLDEREXISTS=<rename>,merge] etc..

Not thinking about my actual needs here. o) But these things could be prompted for in the wizard, which then translates the user input into the required commandline.

They could be renamed, like DO does it (appending " (x)" or something) or replaced or skipped if already existing in the target.

A simple wildcard/pattern for items to be taken from the folders comes to my mind at first.

I'd love to accept the challenge. But currently, I feel I would have only time to create a wizard button that would use this add-in. However providing a commented template would be a first step and motivation for me or anyone who's got time to push it further. You could be that guy if you want this add-in come true before newt winter ^^'. You're the script master here and I'm just the wizard guy for now :wink:

I feel the motivation to begin with another goal for a first script add-in. See my [PROJECT] Smart Archive management.

hey guys new here and to this kind of thing in general so my apologies for using laymen's terms. i wonder if it would be possible to merge a folder with all its subfolders. not sure about anyone else but that would help me out a ton.

Do you mean you want to flatten a folder's contents? So e.g.

Folder
   Subfolder
      A
   Subfolder
      B

into

Folder
    A
    B

?