eltos / PasteIntoFile

Paste clipboard data into files and copy file contents directly via hotkey or context menu
MIT License
87 stars 6 forks source link

Use ctrl key to perform default action #6

Closed David-Maisonave closed 2 years ago

David-Maisonave commented 2 years ago

Describe your idea in general, its use case and its benefits:

  1. Create a file automatically (without a windows prompt), when holding CTRL key while choosing [Paste Into File] in the context menu.
  2. Create the file in a default sub folder under the current directory, when holding SHIFT key while choosing [Paste Into File].
  3. Holding both keys (CTRL+SHIFT) while choosing [Paste Into File] creates the text file automatically in the default sub folder associated with the file type.

I posted this feature request on EslaMx7/PasteIntoFile, and I implemented the changes on David-Maisonave/PasteIntoFile before I realized there was a more updated version of this program here.

I look to see if I could port the changes to this version of PasteIntoFile, but the source code for this version looks very different.

I see there is an "Autosave Mode" in this version, but it's an option that has to be pre-selected. Also the text under Features doesn't state how the user would deselect (uncheck) Autosave if the user wanted to set it back.

On my modified version, I also added additional text file types, and I also made it only display text file types for text, and only image types for images. Most of the changes I made only had to be made in function frmMain_Load.

    if (Clipboard.ContainsText())
    {
    lblType.Text = "Text File";
            comExt.Items.AddRange(new object[] {
                "ahk",   // - AutoHotkey
                "au3",   // - AutoIt
                "bat",   // - DOS Batch
                "cmd",   // - DOS Batch (modern)
                "cpp",   // - C++ Language
                "cs",    // - C-Sharp Langauge
                "css",   // - Cascading Style Sheets - use to style an HTML document
                "csv",   // - Comma-Separated Value
                "htm",   // - Hypertext Markup Language
                "html",  // - Hypertext Markup Language
                "ini",   // - INI - Windows Configuration File
                "java",  // - Java Language
                "js",    // - JavaScript Language
                "json",  // - JavaScript Object Notation
                "php",   // - PHP Language
                "pl",    // - Perl Language
                "ps1",   // - PowerShell
                "py",    // - Python Language
                "reg",   // - Registry File
                "swift", // - Switft  Language
                "txt",   // - Text Files
                "vb",    // - Visual Basic Language
                "vbs",   // - Visual Basic Script Language
                "xml"    // - Extensible Markup Language
            });
    comExt.SelectedItem = "txt";
    IsText = true;
            txtContent.Text = Clipboard.GetText();
            if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
                txtCurrentLocation.Text = txtCurrentLocation.Text + @"\" + TextSubDir;
            if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
                Save_Action(0);
            return;
    }

    if (Clipboard.ContainsImage())
    {
    lblType.Text = "Image";
            comExt.Items.AddRange(new object[] {
                "png",
                "jpg",
                "bmp",
                "gif",
                "ico"
            });
    comExt.SelectedItem = "png";
            imgContent.Image = Clipboard.GetImage();
            if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
                txtCurrentLocation.Text = txtCurrentLocation.Text + @"\" + ImageSubDir;
            if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
                Save_Action(0);
    return;
    }

Related:

eltos commented 2 years ago

Hi @David-Maisonave, indeed, the code has diverged heavily.

I see there is an "Autosave Mode" in this version, but it's an option that has to be pre-selected. Also the text under Features doesn't state how the user would deselect (uncheck) Autosave if the user wanted to set it back.

sorge13248/PasteIntoFile implemented the logic the other way round, automatically save it and only promt if holding SHIFT. The page linked in the readme under features explains how to use it, and there are several messages included in the program that explain how to get back the dialog after having enabled autosave.

eltos commented 2 years ago

Create a file automatically (without a windows prompt), when holding CTRL key while choosing [Paste Into File] in the context menu.

I think this can easily be implemented, such that SHIFT will always force the dialog to pop up, CTRL will always force it to not pop up, and the default behaviour depends on the automode option.

Relevant code would be https://github.com/eltos/PasteIntoFile/blob/eda356b88d72c6ff040ff50e1ab9d18d1c349ea2/PasteIntoFile/Dialog.cs#L81

eltos commented 2 years ago

Create the file in a default sub folder under the current directory, when holding SHIFT key while choosing [Paste Into File].

This would clash with the present usage of the SHIFT Key, but one could use ALT instead? What would be the use case? Why not create the folder manually, considering that you want to rename it anyways? Or just right-click the existing folder to paste? In automode, should the folder or the file be auto-selected for quick renaming? Should there be different subfolders per filetype? What should be their name? Should the foldername be configurable by the user via template, just like the filename? So many questions 😅

eltos commented 2 years ago

On my modified version, I also added additional text file types

That's a difficult topic, because different users have different opinions on which extensions they would like to have as preset - and there are just too many to provide all.
In the present version there are a few common presets available, but you can always enter an arbitrary extensions in the text input. If it's not know, it will be treated as text format, and remembered for future executions.

eltos commented 2 years ago

I also made it only display text file types for text, and only image types for images.

The latest version even supports different clipboard content types simultaneously, so it suggests image extensions if there is an image in the clipboard, text extensions if there is text, and both if both text and image happen to be in clipboard (and even further, the same mechanism exists for html, rtf, ...). In this sense I think your suggestion is already implemented.

David-Maisonave commented 2 years ago

Create the file in a default sub folder under the current directory, when holding SHIFT key while choosing [Paste Into File].

What would be the use case?

The use case is when a user is working on a particular folder, and doesn't want to move explorer path back and forth, this allows the user to stay on the same folder, but collect the data in a sub folder.

Why not create the folder manually, considering that you want to rename it anyways?

The use case is not for the purpose of creating the sub folder, but for allowing user to stay in one path while collecting the data in a sub path.

but one could use ALT instead?

You can't use the ALT key, because as soon as the ALT key is press the context window closes.

I think this can easily be implemented, such that SHIFT will always force the dialog to pop up

I think using 2 keys for the same logic would be confusing to the user. IMHO, a better approach is to have the shift key perform the opposite of the current default behavior. That way the user doesn't have to memorize which key performs what function. Another option is to make the right mouse button perform the opposite default behavior. This would allow the user to perform the task without touching the keyboard. It's a more intuitive approach.

In the code I implemented, the user can use both the ctrl+shift key to instantly create the files in a sub folder. Where the ctrl key forces no-popup and the shift key is used to trigger creating the sub folder.

If in this implementation the shift key is being used to determine the no-popup, then the ctrl key can be used to trigger creating the sub folder.

EslaMx7 has responded to my post, and said he'll pull in my changes. It would be better if both versions of PasteIntoFile had similar keyboard functionality. Since your version is already using the shift key for no-popup, I'm going to change my code and flip it around so the shift key is used for no-popup and ctrl key is used to trigger creating sub folder. I'm also going to add the right mouse button logic to do the no-popup.

eltos commented 2 years ago

The use case is when a user is working on a particular folder, and doesn't want to move explorer path back and forth, this allows the user to stay on the same folder, but collect the data in a sub folder.

It sounds like for this use case it's really as easy as doing the right-click on this particular subfolder (rather than on the background of the current one), which will save the file into the folder you did the right-click on.

I think using 2 keys for the same logic would be confusing to the user. IMHO, a better approach is to have the shift key perform the opposite of the current default behavior.

Good point, I like your argument. So SHIFT would basically temporarily invert the Automode setting 👍

David-Maisonave commented 2 years ago

Additional Use Case

Another use case for supporting default folder option is for a user who wants to optionally specify an explicit (FQN) directory instead of a sub directory. In my new code this is accomplished with the same logic, but with a one line change that checks if the default folder has the ":" character. See second to last line in the code example.

Default Folder Options

Should there be different subfolders per filetype? What should be their name? Should the foldername be configurable by the user via template, just like the filename?

I didn't see these questions before. In my code I only use two different types. Text and Image. By default those are the folder names, but the user has the option to change the default folder names via command line, or by modifying the registry directly. If you're worried about expanding supported types, then for this version of PasteIntoFile it might be better just to support a single default sub folder.

Here's how the command line options work: From the Readme.md:

Right Clicking a Sub Folder

It sounds like for this use case it's really as easy as doing the right-click on this particular subfolder

Right clicking the sub folder can be difficult to do if the directory has many sub folders. In the case where there is a few sub folders but many files, the user would have to page up to the top of the list, or try right clicking on the folder tree view. However, when right clicking the folder tree view, the context menu is populated with a lot of junk that makes it harder to find [Paste Into File]. At least this is the case for Windows 10. On Windows 11 they've tried to simplify the context menu, but I'm not sure if [Paste Into File] is listed under the more option. If so, the end user will still have the clutter issue.

Feature Implementation

The implementation for this feature is surprisingly small, where 80% of the changes are in function frmMain_Load. This includes the registry key fetching logic, checking for ctrl key pressed, and support for both sub path and FQN path.

txtCurrentLocation.Text = CurrentLocation ?? @"C:\";
const string DEFAULT_TEXT_SUBFOLDER = "Text";
const string DEFAULT_IMAGE_SUBFOLDER = "Image";
string TextDefaultDir = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Classes\Directory\shell\Paste Into File\TextDefaultDir", "", null) ?? DEFAULT_TEXT_SUBFOLDER;
string ImageDefaultDir = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Classes\Directory\shell\Paste Into File\ImageDefaultDir", "", null) ?? DEFAULT_IMAGE_SUBFOLDER;
if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
{
    string DefaultDir = (Clipboard.ContainsText()) ? TextDefaultDir : ImageDefaultDir;
    txtCurrentLocation.Text = (DefaultDir.IndexOf(":") > 0) ? DefaultDir : txtCurrentLocation.Text + @"\" + DefaultDir;
}

The Save_Action function listed below, has a change which I think should be added even without the above changes, because if the user adds a sub folder manually in the "Current Location" field, this code will create the folder if it doesn't exist.

if (!Directory.Exists(location))
    Directory.CreateDirectory(location);

The only other changes are the command line options, which are not absolutely required, but makes it easier for the user to make the registry key changes.

if (args.Length>0)
{
    if ...
    else if (string.Equals(args[0], "/TextDefaultDir", StringComparison.CurrentCultureIgnoreCase) && args.Length > 1)
    {
        var key = OpenDirectoryKey().CreateSubKey("shell").CreateSubKey("Paste Into File");
        key = key.CreateSubKey("TextDefaultDir");
        key.SetValue("", args[1]);
        return;
    }
    else if (string.Equals(args[0], "/ImageDefaultDir", StringComparison.CurrentCultureIgnoreCase) && args.Length > 1)
    {
        var key = OpenDirectoryKey().CreateSubKey("shell").CreateSubKey("Paste Into File");
        key = key.CreateSubKey("ImageDefaultDir");
        key.SetValue("", args[1]);
        return;
    }

FYI:

In my update for EslaMx7/PasteIntoFile, I switch the keys to have the shift key do the no-popup, but when I tried to implement the right mouse button, I couldn't figure out how to notify the program that the right mouse button was used in the context menu. I tried to google it, but I couldn't find anything on the topic. Do you have any idea how to get right mouse button notification from the context menu?

eltos commented 2 years ago

I prepared a PR: #7
Also enabled template variables for the subdirectory, which might be useful

The Save_Action function listed below, has a change which I think should be added even without the above changes, because if the user adds a sub folder manually in the "Current Location" field, this code will create the folder if it doesn't exist.

Already implemented a while ago

Do you have any idea how to get right mouse button notification from the context menu?

No idea, I don't think this is possible

eltos commented 2 years ago

Hi @David-Maisonave What do you think about #7, do you have any comments or should I go ahead and merge?