// NewMoveJob creates a new move job for dbus.
func NewMoveJob(srcUrls []string, destDirURL string, targetName string, flags uint32, uiDelegate IUIDelegate) *MoveJob {
	job := &MoveJob{
		dbusInfo: genDBusInfo("MoveJob", &_MoveJobCount),
		op:       operations.NewMoveJob(srcUrls, destDirURL, targetName, gio.FileCopyFlags(flags), uiDelegate),
	}
	return job
}
// RequestCreatingAppGroup creates app group according to the files, and emits AppGroupCreated signal when it's done.
func (app *Application) RequestCreatingAppGroup(files []string) error {
	C.g_reload_user_special_dirs_cache()
	desktopDir := GetDesktopDir()

	availableFiles := filterDesktop(files)

	// get group name
	groupName := getGroupName(availableFiles)

	dirName := AppGroupPrefix + groupName

	// create app group.
	createJob := operations.NewCreateDirectoryJob(desktopDir, dirName, nil)
	createJob.Execute()

	if err := createJob.GetError(); err != nil {
		Log.Error("create appgroup failed:", err)
		return err
	}

	appGroupURI := createJob.Result().(string)

	// move files into app group.
	moveJob := operations.NewMoveJob(availableFiles, appGroupURI, "", 0, nil)
	moveJob.Execute()
	if err := moveJob.GetError(); err != nil {
		Log.Error("move apps to appgroup failed:", err)
		return err
	}

	return app.emitAppGroupCreated(appGroupURI, availableFiles)
}
// GenMenu generates json format menu content used in DeepinMenu for AppGroup.
func (item *AppGroup) GenMenu() (*Menu, error) {
	item.menu = NewMenu()
	return item.menu.AppendItem(NewMenuItem(Tr("_Open"), func(uint32) {
		ops := make([]int32, len(item.uris))
		for i := range item.uris {
			ops[i] = OpOpen
		}
		item.app.emitRequestOpen(item.uris, ops)
	}, true)).AddSeparator().AppendItem(NewMenuItem(Tr("_Rename"), func(uint32) {
		item.emitRequestRename()
	}, !item.multiple)).AddSeparator().AppendItem(NewMenuItem(Tr("_Ungroup"), func(uint32) {
		for _, uri := range item.uris {
			files := []string{}

			listJob := operations.NewListDirJob(uri, operations.ListJobFlagIncludeHidden)
			listJob.ListenProperty(func(p operations.ListProperty) {
				files = append(files, p.URI)
			})
			listJob.Execute()
			if err := listJob.GetError(); err != nil {
				Log.Warningf("list appgroup %s failed: %s\n", uri, err)
				continue
			}

			moveJob := operations.NewMoveJob(files, GetDesktopDir(), "", 0, nil)
			moveJob.Execute()
			if err := moveJob.GetError(); err != nil {
				Log.Warningf("dismiss appgroup %s failed: %s\n", uri, err)
			}
		}
	}, true)).AddSeparator().AppendItem(NewMenuItem(Tr("_Delete"), func(uint32) {
		item.emitRequestDelete()
	}, true)), nil
}
// RequestMergeIntoAppGroup will merge files into existed AppGroup, and emits AppGroupMerged signal when it's done.
func (app *Application) RequestMergeIntoAppGroup(files []string, appGroup string) error {
	availableFiles := filterDesktop(files)

	moveJob := operations.NewMoveJob(availableFiles, appGroup, "", 0, nil)
	moveJob.Execute()
	if err := moveJob.GetError(); err != nil {
		return err
	}

	return app.emitAppGroupMerged(appGroup, availableFiles)
}