To distinguish between copied and cut files

Please check the FAQ (https://www.xyplorer.com/faq.php) before posting a question...
Post Reply
John_C
Posts: 336
Joined: 16 May 2018 20:04

To distinguish between copied and cut files

Post by John_C »

Does anybody know, is there some way to distinguish whether the clipboard contains copied files or cut files? That is, to distinguish between them.

I believe that there is no such option, but may be someone knows better. I ask it because I'm trying to implement a script to copy, duplicate, and cut files.

It works successfully, but as I discovered, Ctrl-X Ctrl-V works the same way as Ctrl-C Ctrl-V.

Here is how it works:
script.PNG
script.PNG (5.84 KiB) Viewed 1406 times
This is incredibly useful. It fives you possibility to have the proper order of duplicated and copied items.

highend
Posts: 13327
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: To distinguish between copied and cut files

Post by highend »

If scripted, why should this matter? There are window messages (e.g. WM_CUT / WM_COPY) but applications don't need to use them if they decide to act on their own...
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: To distinguish between copied and cut files

Post by John_C »

> If scripted, why should this matter?

The script is attached to Ctrl-V.

I can select some file, press Ctrl-C Ctrl-V and this file will be correctly copied.

However, in case I try to cut some file from directory Foo and paste it to the directory Bar, it will be copied instead.

Code: Select all

$affix = getkey('PostfixNum', 'General');

foreach($item, <clp>, <crlf>, 'e') {
    // Get the digit(s) from the used affix
    $cntNumAffix = regexmatches($affix, '\d+');

    // How many digits do we have? (e.g. 2 in '01')
    $lenNumAffix = strlen($cntNumAffix);

    // Base file (everything up to but not including the first dot)
    $baseFile = regexmatches(gpc($item, 'file'), '^[^.]+');

    // Keep everything after the first dot
    $exts = regexreplace($item, '^[^.]+\.?');

    // Generate destination file name (without path!)
    if ($exts != '') {
        ; msg '1-i';
        $dstFile1 = $baseFile . '.' . $exts;
        $dstFile2 = $baseFile . '.' . $exts . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.');
    } else {
        ; msg '2-i';
        $dstFile1 = $baseFile;
        $dstFile2 = $baseFile . $affix;
    }

    while (true) {
        // If the destination file does NOT exist
        if (exists(<curpath> . '\' . $dstFile1) == False) {
            if ($exts != '') {
                ; msg '3-i';
                copyas $baseFile . '.' . $exts,, $item;
            } else {
                ; msg '4-i';
                copyas $baseFile,, $item;
            }
            break;
        }
        if (exists(<curpath> . '\' . $dstFile2) == False) {
            if ($exts != '') {
                ; msg '5-i';
                copyas $baseFile . '.' . $exts . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.'),, $item;
            } else {
                ; msg '6-i';
                copyas $baseFile . $affix,, $item;
            }
            break;
        }

        // Destination file DOES already exist
        // Increase the digits of the affix by one
        $cntNumAffix++;

        // Create the new, formatted affix number
        $incAffix = format($cntNumAffix, strrepeat('0', $lenNumAffix));

        // Replace the digits with the incremented one(s)
        $affix = regexreplace($affix, '\d+', $incAffix);

        // This is the new (counted up) destination file name (again, no path!)
        if ($exts != '') {
            $dstFile2 = $baseFile . '.' . $exts . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.');
        } else {
            $dstFile2 = $baseFile . $affix;
        }
    }
}

highend
Posts: 13327
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: To distinguish between copied and cut files

Post by highend »

Then bind Ctrl+Shift+V to a second one which uses a move instead of a copy?

Even windows uses different bindings to invoke different functionality, e.g.
shift+delete = skip recycle bin, and most external tools do it in a similar way,
if they process content that comes from a different source...
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: To distinguish between copied and cut files

Post by John_C »

> Ctrl+Shift+V to a second one which uses a move instead of a copy?

Yes, this is a possible workaround. However it will not be very convenient and consistent. It is an old habit to associate Ctrl-X with "cut" operation across both file management and text editing.

highend
Posts: 13327
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: To distinguish between copied and cut files

Post by highend »

*sigh*. Write a message handler and interpret the changes to the clipboard yourself...
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: To distinguish between copied and cut files

Post by John_C »

You mean the handler for WM_COPY and WM_CUT? It seems they are Windows internal things. Where in the Help to read about handling such things?

highend
Posts: 13327
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: To distinguish between copied and cut files

Post by highend »

It seems they are Windows internal things
Of course they are. Help file? Windows API...
One of my scripts helped you out? Please donate via Paypal

highend
Posts: 13327
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: To distinguish between copied and cut files

Post by highend »

Another idea: Use AHK with non-blocking hotkeys for ctrl+c and ctrl+x and send a script that uses two perm variables for the state if it was a copy or a cut...
One of my scripts helped you out? Please donate via Paypal

jupe
Posts: 2801
Joined: 20 Oct 2017 21:14
Location: Win10 22H2 120dpi

Re: To distinguish between copied and cut files

Post by jupe »

You can tell if an item on the clipboard is cut or copied by using this command:

Code: Select all

text get('clipboarddropeffect');
Which returns different bitfield values for each, you should be able to integrate it in your script yourself.

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: To distinguish between copied and cut files

Post by John_C »

Thank you Jupe and Highend for new ideas. get('clipboarddropeffect'); looks as a better way. This is great.

Here are two scripts, in case they will be useful for someone. Works for me, thought I don't say the code is perfect:

Code: Select all

// To create timestamped copy

$affix = getkey('PostfixNum', 'General');
$affixDate = getkey('PostfixDate', 'General');

foreach($item, <get SelectedItemsNames |>,, 'e') {
    // Get the digit(s) from the used affix
    $cntNumAffix = regexmatches($affix, '\d+');

    // How many digits do we have? (e.g. 2 in '01')
    $lenNumAffix = strlen($cntNumAffix);

    // Base file (everything up to but not including the first dot)
    $baseFile = regexmatches(gpc($item, 'file'), '^[^.]+');

    // Keep everything after the first dot
    $exts = regexreplace($item, '^[^.]+\.?');

    // Generate destination file name (without path!)
    if ($exts != '') {
        $dstFile1 = $baseFile . '.' . $exts;
        $dstFile2 = $baseFile . '.' . $exts . $affixDate . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.') . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.');
    } else {
        $dstFile1 = $baseFile;
        $dstFile2 = $baseFile . $affixDate . $affix;
    }

    while (true) {
        // If the destination file does NOT exist
        if (exists(<curpath> . '\' . $dstFile1) == False) {
            if ($exts != '') {
                copyas $baseFile . '.' . $exts,, $item;
            } else {
                copyas $baseFile,, $item;
            }
            break;
        }
        if (exists(<curpath> . '\' . $dstFile2) == False) {
            if ($exts != '') {
                // Check if the 'pre' version (the one before the e.g. #2 suffix) exists
                $preDstFile2 = $baseFile . '.' . $exts . $affixDate . '.' . gpc($item, 'ext');
                if (exists(<curpath> . '\' . $preDstFile2) == False) {
                    copyas $preDstFile2,, $item;
                } else {
                    copyas $dstFile2,, $item;
                }
            } else {
                // Check if the 'pre' version (the one before the e.g. #2 suffix) exists
                $preDstFile1 = $baseFile . $affixDate;
                if (exists(<curpath> . '\' . $preDstFile1) == False) {
                    copyas $preDstFile1,, $item;
                } else {
                    copyas $dstFile2,, $item;
                }
            }
            break;
        }

        // Destination file DOES already exist
        // Increase the digits of the affix by one
        $cntNumAffix++;

        // Create the new, formatted affix number
        $incAffix = format($cntNumAffix, strrepeat('0', $lenNumAffix));

        // Replace the digits with the incremented one(s)
        $affix = regexreplace($affix, '\d+', $incAffix);

        // This is the new (counted up) destination file name (again, no path!)
        if ($exts != '') {
            $dstFile2 = $baseFile . '.' . $exts . $affixDate . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.') . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.'),, $item;
        } else {
            $dstFile2 = $baseFile . $affixDate . $affix,, $item;
        }
    }
}

Code: Select all

// To create incremented copy

$affix = getkey('PostfixNum', 'General');

foreach($item, <clp>, <crlf>, 'e') {
    // Get the digit(s) from the used affix
    $cntNumAffix = regexmatches($affix, '\d+');

    // How many digits do we have? (e.g. 2 in '01')
    $lenNumAffix = strlen($cntNumAffix);

    // Base file (everything up to but not including the first dot)
    $baseFile = regexmatches(gpc($item, 'file'), '^[^.]+');

    // Keep everything after the first dot
    $exts = regexreplace($item, '^[^.]+\.?');

    // Generate destination file name (without path!)
    if ($exts != '') {
        $dstFile1 = $baseFile . '.' . $exts;
        $dstFile2 = $baseFile . '.' . $exts . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.');
    } else {
        $dstFile1 = $baseFile;
        $dstFile2 = $baseFile . $affix;
    }

    while (true) {
        // If the destination file does NOT exist
        if (exists(<curpath> . '\' . $dstFile1) == False) {
            if ($exts != '') {
                if (get('clipboarddropeffect') == 5) {
                    copyas $baseFile . '.' . $exts,, $item;
                } elseif (get('clipboarddropeffect') == 2) {
                    moveas $baseFile . '.' . $exts,, $item;
                }
            } else {
                if (get('clipboarddropeffect') == 5) {
                    copyas $baseFile,, $item;
                } elseif (get('clipboarddropeffect') == 2) {
                    moveas $baseFile,, $item;
                }
            }
            break;
        }
        if (exists(<curpath> . '\' . $dstFile2) == False) {
            if ($exts != '') {
                if (get('clipboarddropeffect') == 5) {
                    copyas $baseFile . '.' . $exts . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.'),, $item;
                } elseif (get('clipboarddropeffect') == 2) {
                    moveas $baseFile . '.' . $exts . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.'),, $item;
                }
            } else {
                if (get('clipboarddropeffect') == 5) {
                    copyas $baseFile . $affix,, $item;
                } elseif (get('clipboarddropeffect') == 2) {
                    moveas $baseFile . $affix,, $item;
                }
            }
            break;
        }

        // Destination file DOES already exist
        // Increase the digits of the affix by one
        $cntNumAffix++;

        // Create the new, formatted affix number
        $incAffix = format($cntNumAffix, strrepeat('0', $lenNumAffix));

        // Replace the digits with the incremented one(s)
        $affix = regexreplace($affix, '\d+', $incAffix);

        // This is the new (counted up) destination file name (again, no path!)
        if ($exts != '') {
            $dstFile2 = $baseFile . '.' . $exts . $affix . '.' . regexreplace($exts, '^.+(#\d+|@[\d-]+)\.');
        } else {
            $dstFile2 = $baseFile . $affix;
        }
    }
}
Preliminary setup: Tools > Configuration > Templates > Incremental affix: #2, Date affix: @<date yyyy-mm-dd-hh-nn>

Known issue: Each file will create its own copy window.

Post Reply