Community
    • Login

    PasteSpecial - revisited

    Scheduled Pinned Locked Moved Blogs
    16 Posts 3 Posters 2.5k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Alan KilbornA
      Alan Kilborn @PeterJones
      last edited by

      @PeterJones

      Some questions:

      I see the utility of a “grab of HTML”. However, what is the utility in getting CF_BITMAP for example, and how would this paste into a text editor? Would it be converted into textual representation of the bytes of the bitmap before pasting? I imagine so, but how often is that a useful thing?

      I wanted to make it at least use notepad->prompt()

      Just what IS “notepad prompt”?
      I always thought of it as a Pythonscript-specific thing, but is it a Notepad++ thing that Pythonscript is calling into?

      PeterJonesP 1 Reply Last reply Reply Quote 0
      • PeterJonesP
        PeterJones @Alan Kilborn
        last edited by PeterJones

        @Alan-Kilborn said,

        what is the utility in getting CF_BITMAP for example, and how would this paste into a text editor? Would it be converted into textual representation of the bytes of the bitmap before pasting? I imagine so, but how often is that a useful thing?

        No usefulness that I know of. the CF_…() constants are predefined in the Win32::Clipboard library in Perl, and I already had code that I copy/pasted to populate the %map with all the pre-existing clipboard types.

        I basically wanted to list all formats available, so that the user can make an informed decision – which helps give some information, even if it cannot be usefully pasted in Notepad++. If I copy something from Visio, and I see it has both a CF_BITMAP and an HTML Format, as well as its native Visio format(s), that would give me more insight into what is on the clipboard.

        After that last paragraph, I realized I should have stated, in my reasons for wanting this tool, it goes beyond Notepad++ specifics. I want something that tells me more about what’s in the clipboard, while at the same time making it easier to paste a specific reasonable component of the clipboard into Notepad++.

        I wanted to make it at least use notepad->prompt()

        Just what IS “notepad prompt”?
        I always thought of it as a Pythonscript-specific thing, but is it a Notepad++ thing that Pythonscript is calling into?

        It technically was PythonScript-specific, but since I was trying to replicate as much of PythonScript as possible in “PerlScript”, I included it.

        notepad->messageBox was easier to implement, because there is a standard MessageBox function in the API; there isn’t a standard prompt or InputBox function in the main API (which annoys me, because Visual Basic (for Applications) does implement InputBox).

        IIRC, the Python library that PythonScript used already had its own prompt, and PS just put it in a wrapper to automatically instantiate it as a child of the Notepad object’s hWnd. The Perl library I was using didn’t have a similar implementation, so I had to adapt some code I found on the internet for another language that I cobbled into a not-overly-pretty prompt box for Perl.

        Alan KilbornA EkopalypseE 2 Replies Last reply Reply Quote 2
        • Alan KilbornA
          Alan Kilborn @PeterJones
          last edited by

          @PeterJones

          While we’re sort of on the subject, Pythonscript’s notepad.prompt annoys me for at least a few reasons:

          • it could be larger (when one tries to use it for a UI that is a bit more than “get one scrap of input”, one is soon feeling “pinched”)
          • its font size could be larger (okay, I guess “larger” in general is the theme of my complaint)
          1 Reply Last reply Reply Quote 1
          • EkopalypseE
            Ekopalypse @PeterJones
            last edited by

            @PeterJones said in PasteSpecial - revisited:

            IIRC, the Python library that PythonScript used already had its own prompt

            Nope, that is cpp code.

            By the way, what does the RegisterClipboardFormat do?
            I mean, I know what it is supposed to do but I don’t understand
            it in the context of your script.

            PeterJonesP 1 Reply Last reply Reply Quote 1
            • PeterJonesP
              PeterJones @Ekopalypse
              last edited by

              @Ekopalypse said in PasteSpecial - revisited:

              cpp code

              makes me feel better that it wasn’t a python-bonus. :-)

              By the way, what does the RegisterClipboardFormat do?
              in the context of your script

              Not sure it’s strictly necessary. I never experimented on retrieving one of the high-number formats without it – by the description, it’s required for it to be a “valid clipboard format”. But I don’t know if that’s only necessary when populating the clipboard, or also when retrieving the clipboard. Maybe some day I’ll play with that some more.

              EkopalypseE 1 Reply Last reply Reply Quote 1
              • EkopalypseE
                Ekopalypse @PeterJones
                last edited by

                @PeterJones

                But I don’t know if that’s only necessary when populating the clipboard, or also when retrieving the clipboard.

                My understanding is that it is needed only when you want to register
                your own format but not when you enumerate or retrieve a registered format.

                PeterJonesP 1 Reply Last reply Reply Quote 2
                • PeterJonesP
                  PeterJones @Ekopalypse
                  last edited by

                  @Ekopalypse said in PasteSpecial - revisited:

                  My understanding is that it is needed only when you want to register your own format

                  You are correct. I was able to take out the RegisterClipboardFormat, and it still worked.

                  PeterJonesP 1 Reply Last reply Reply Quote 1
                  • PeterJonesP
                    PeterJones @PeterJones
                    last edited by PeterJones

                    Speaking of working, here is an updated version… one that works well enough (in my tests) to be called v1.0.

                    It no longer requires inputting your choice on STDIN, which was the primary failing in the original.

                    Rather than fixing the bug in PerlScript’s notepad->prompt() (which will be done, but will take time to prove and release), I instead just instantiated the code to build my own custom dialog box in this script (which is cleaner in the long run than a hacked prompt-base solution, anyway).

                    To run it from NppExec, make sure to use cmd /c perl "c:\path\to\pasteSpecial.pl" – the cmd /c makes sure NppExec calls the process correctly, so that it can open dialog windows.

                    pasteSpecial.pl - v1.0

                    #!/usr/bin/env perl
                    ################################################
                    # PasteSpecial for Notepad++
                    #   List formats currently on the clipboard
                    #   Allows you to choose one of those formats
                    #   Will paste the selected type (UTF8-encoded)
                    #   at the current location in the active file
                    ################################################
                    
                    use 5.010;
                    use warnings;
                    use strict;
                    use Win32::Clipboard;
                    use Win32::GUI;
                    use Win32::GUI::Constants qw/CW_USEDEFAULT/;
                    use Encode;
                    use Win32::Mechanize::NotepadPlusPlus 0.004 qw/:main/;
                    
                    our $VERSION = 1.0; # this works even with W32MNPP v0.004
                    
                    BEGIN {
                        binmode STDERR, ':utf8';
                        binmode STDOUT, ':utf8';
                    }
                    
                    my %map = (
                        CF_TEXT()           => 'CF_TEXT',
                        CF_BITMAP()         => 'CF_BITMAP',
                        CF_METAFILEPICT()   => 'CF_METAFILEPICT',
                        CF_SYLK()           => 'CF_SYLK',
                        CF_DIF()            => 'CF_DIF',
                        CF_TIFF()           => 'CF_TIFF',
                        CF_OEMTEXT()        => 'CF_OEMTEXT',
                        CF_DIB()            => 'CF_DIB',
                        CF_PALETTE()        => 'CF_PALETTE',
                        CF_PENDATA()        => 'CF_PENDATA',
                        CF_RIFF()           => 'CF_RIFF',
                        CF_WAVE()           => 'CF_WAVE',
                        CF_UNICODETEXT()    => 'CF_UNICODETEXT',
                        CF_ENHMETAFILE()    => 'CF_ENHMETAFILE',
                        CF_HDROP()          => 'CF_HDROP',
                        CF_LOCALE()         => 'CF_LOCALE',
                    );
                    my %rmap; @rmap{values %map} = keys %map;
                    
                    my $CLIP = Win32::Clipboard;
                    
                    my @f = $CLIP->EnumFormats();
                    #printf STDERR "Formats active in clipboard:\n";
                    foreach my $format (sort {$a <=> $b} @f) {
                        $map{$format} //= $CLIP->GetFormatName($format) // '<unknown>';
                        $rmap{ $map{$format} } = $format;
                        #printf STDERR "%-8d => '%s'\n", $format, $map{$format};
                    }
                    if(0){
                    my $selection;
                    while(!defined $selection) {
                        printf STDERR "choose one: ";
                        $selection = 13;
                        chomp $selection;
                        $selection = $rmap{$selection} if exists $rmap{$selection}; # selection was a format name; now converted to format number
                        last if exists $map{$selection};    # selection is a valid format number
                        undef $selection;
                    }
                    printf STDERR "final selection: %d => %s\n", $selection, $map{$selection};
                    my $get = $CLIP->GetAs($selection);
                    if($selection == CF_UNICODETEXT()) {
                        $get = Encode::decode( "UTF16-LE", $get );
                    }
                    #printf STDERR "got => '%s'\n", $get;
                    }
                    
                    my $answer = runDialog(\@f, \%rmap);
                    #printf STDERR "answer => '%s'\n", $answer;
                    #printf STDERR "answer => '%s'\n", Encode::encode('UTF8', $answer);   # double-encoded (once by Encode, once by binmode :utf8)
                    editor->addText(Encode::encode("UTF8", $answer)) if defined $answer;
                    
                    exit;
                    
                    sub runDialog {
                        my @formats = @{ shift() };
                        my %rmap = %{ shift() };
                        my %map; @map{ values %rmap } = keys %rmap;
                    
                        my $clipboard;
                    
                        my $dlg = Win32::GUI::Window->new(
                            -title          => 'Notepad++ Paste Special',
                            -left           => CW_USEDEFAULT,
                            -top            => CW_USEDEFAULT,
                            -size           => [580,300],
                            -resizable      => 0,
                            -maximizebox    => 0,
                            -toolwindow     => 1,
                        );
                    
                        my $lb = $dlg->AddListbox(
                            -name           => 'LB',
                            -pos            => [10,10],
                            -size           => [230, $dlg->ScaleHeight()-10],
                            -vscroll        => 1,
                            -onSelChange    => sub {
                                                    my $self = shift;
                                                    my $value = $self->GetText($self->GetCurSel());
                                                    my $f=$rmap{$value};
                                                    #printf STDERR "%-15s => %d\n", $value, $f;
                                                    $clipboard = $CLIP->GetAs($f);
                                                    $clipboard = Encode::decode('UTF16-LE', $clipboard) if $f == CF_UNICODETEXT();
                                                    #printf STDERR "%-15s => '%s'\n", clipboard => $clipboard;
                                                    (my $preview = $clipboard) =~ s/([^\x20-\x7F\r\n])/sprintf '\x{%02X}', ord $1/ge;
                                                    $preview =~ s/\R/\r\n/g;
                                                    $self->GetParent()->PREVIEW->Text( $preview );
                                                    return 1;
                                                },
                        );
                        $dlg->LB->Add( @map{ sort {$a<=>$b} @formats } );
                    
                        $dlg->AddButton(
                            -name    => 'OK',
                            -text    => 'Paste',
                            -size    => [80,25],
                            -left    => $dlg->ScaleWidth()-90-90,
                            -top     => $dlg->LB->Top()+$dlg->LB->Height()-25,
                            -onClick => sub{-1;},
                        );
                    
                        $dlg->AddButton(
                            -name    => 'CANCEL',
                            -text    => 'Cancel',
                            -size    => [80,25],
                            -left    => $dlg->ScaleWidth()-90,
                            -top     => $dlg->LB->Top()+$dlg->LB->Height()-25,
                            -onClick => sub{ $clipboard=undef; -1; },
                        );
                    
                        $dlg->AddGroupbox(
                            -name  => 'GB',
                            -title => 'Preview',
                            -pos   => [250,10],
                            -size  => [$dlg->ScaleWidth()-260, $dlg->OK->Top()-20],
                        );
                    
                        $dlg->AddLabel(
                            -name           => 'PREVIEW',
                            -left           => $dlg->GB->Left()+10,
                            -top            => $dlg->GB->Top()+20,
                            -width          => $dlg->GB->ScaleWidth()-20,
                            -height         => $dlg->GB->ScaleHeight()-40,
                        );
                    
                        #$dlg->PREVIEW->Text("<Please choose a format>");
                    
                        $dlg->Show();
                        Win32::GUI::Dialog();
                        return $clipboard;
                    }
                    
                    EkopalypseE 1 Reply Last reply Reply Quote 1
                    • EkopalypseE
                      Ekopalypse @PeterJones
                      last edited by

                      @PeterJones

                      just out of curiosity, is this dialog modal?
                      If not, can you run a small test and press CTRL+C in an open document while the dialog is still running?

                      PeterJonesP 1 Reply Last reply Reply Quote 0
                      • PeterJonesP
                        PeterJones @Ekopalypse
                        last edited by

                        @Ekopalypse said in PasteSpecial - revisited:

                        just out of curiosity, is this dialog modal?
                        If not, can you run a small test and press CTRL+C in an open document while the dialog is still running?

                        It is not modal. And it does appear to be live: if I leave it open and copy something new, when I click again on the type, it will update:

                        EkopalypseE 1 Reply Last reply Reply Quote 1
                        • EkopalypseE
                          Ekopalypse @PeterJones
                          last edited by

                          @PeterJones

                          Thanks, the reason for my question is that under certain circumstances, the cause of which I have not yet been able to find out, it is possible that a control character is added when pressing CTRL+C while a non-modal dialog is open.
                          Closing the dialog will reset everything back to normal.

                          PeterJonesP 1 Reply Last reply Reply Quote 1
                          • PeterJonesP
                            PeterJones @Ekopalypse
                            last edited by

                            @Ekopalypse ,

                            Hmm, I haven’t seen ^C added. Sorry.

                            I did find that “live” is a bit of an overstatement: it isn’t updating the list of types when the clipboard changes, so if you originally had a normal text copy, then copy from a webpage, the listbox won’t show the HTML version. Something for v2.0

                            PeterJonesP 1 Reply Last reply Reply Quote 1
                            • PeterJonesP
                              PeterJones @PeterJones
                              last edited by

                              pasteSpecial.pl - v2.0

                              • Add REFRESH button to update the ListBox
                              • Defaults to selecting/displaying the first Clipboard variant; will try to keep the same selection even after refresh
                              • PERSIST checkbox allows dialog to stay open for multiple pastes
                              #!/usr/bin/env perl
                              ################################################
                              # PasteSpecial for Notepad++
                              #   List formats currently on the clipboard
                              #   Allows you to choose one of those formats
                              #   Will paste the selected type (UTF8-encoded)
                              #   at the current location in the active file
                              ################################################
                              # HISTORY
                              #   v0.1: STDIN-based choice
                              #   v1.0: DialogBox choice
                              #   v2.0: Add REFRESH button to update the ListBox
                              #         Defaults to selecting/displaying the first Clipboard variant
                              #         Persist checkbox allows dialog to stay open for multiple pastes
                              ################################################
                              
                              use 5.010;
                              use warnings;
                              use strict;
                              use Win32::Clipboard;
                              use Win32::GUI;
                              use Win32::GUI::Constants qw/CW_USEDEFAULT/;
                              use Encode;
                              use Win32::Mechanize::NotepadPlusPlus 0.004 qw/:main/;   # this works even with v0.004, even without bugfix for prompt()
                              
                              our $VERSION = 'v2.0';
                              
                              BEGIN {
                                  binmode STDERR, ':utf8';
                                  binmode STDOUT, ':utf8';
                              }
                              
                              my %map = (
                                  CF_TEXT()           => 'CF_TEXT',
                                  CF_BITMAP()         => 'CF_BITMAP',
                                  CF_METAFILEPICT()   => 'CF_METAFILEPICT',
                                  CF_SYLK()           => 'CF_SYLK',
                                  CF_DIF()            => 'CF_DIF',
                                  CF_TIFF()           => 'CF_TIFF',
                                  CF_OEMTEXT()        => 'CF_OEMTEXT',
                                  CF_DIB()            => 'CF_DIB',
                                  CF_PALETTE()        => 'CF_PALETTE',
                                  CF_PENDATA()        => 'CF_PENDATA',
                                  CF_RIFF()           => 'CF_RIFF',
                                  CF_WAVE()           => 'CF_WAVE',
                                  CF_UNICODETEXT()    => 'CF_UNICODETEXT',
                                  CF_ENHMETAFILE()    => 'CF_ENHMETAFILE',
                                  CF_HDROP()          => 'CF_HDROP',
                                  CF_LOCALE()         => 'CF_LOCALE',
                              );
                              my %rmap; @rmap{values %map} = keys %map;
                              
                              my $CLIP = Win32::Clipboard;
                              
                              my $answer = runDialog();
                              #editor->addText(Encode::encode("UTF8", $answer)) if defined $answer;   #v1.3: moved to the PASTE button, below
                              exit;
                              
                              sub formats {
                                  my @f = $CLIP->EnumFormats();
                                  foreach my $format (sort {$a <=> $b} @f) {
                                      $map{$format} //= $CLIP->GetFormatName($format) // '<unknown>';
                                      $rmap{ $map{$format} } = $format;
                                  }
                                  return @f;
                              }
                              
                              sub runDialog {
                                  my $clipboard;
                                  my $persist = 1;
                              
                                  my $dlg = Win32::GUI::Window->new(
                                      -title          => sprintf('Notepad++ Paste Special %s', $VERSION),
                                      -left           => CW_USEDEFAULT,
                                      -top            => CW_USEDEFAULT,
                                      -size           => [580,300],
                                      -resizable      => 0,
                                      -maximizebox    => 0,
                                      -hashelp => 0,
                                      -dialogui => 1,
                                  );
                                  my $icon = Win32::GUI::Icon->new(100);              # v1.1: change the icon
                                  $dlg->SetIcon($icon) if defined $icon;
                              
                                  my $update_preview = sub {
                                      my $self = shift // return -1;
                                      my $value = $self->GetText($self->GetCurSel());
                                      my $f=$rmap{$value};
                                      $clipboard = $CLIP->GetAs($f);
                                      $clipboard = Encode::decode('UTF16-LE', $clipboard) if $f == CF_UNICODETEXT();
                                      (my $preview = $clipboard) =~ s/([^\x20-\x7F\r\n])/sprintf '\x{%02X}', ord $1/ge;
                                      $preview =~ s/\R/\r\n/g;
                                      $self->GetParent()->PREVIEW->Text( $preview );
                                      return 1;
                                  };
                                  my $lb = $dlg->AddListbox(
                                      -name           => 'LB',
                                      -pos            => [10,10],
                                      -size           => [230, $dlg->ScaleHeight()-10],
                                      -vscroll        => 1,
                                      -onSelChange    => $update_preview,             # v1.2: externalize this callback so it can be run from elsewhere
                                  );
                              
                                  my $refresh_formats = sub {
                                      my $lb = $dlg->LB;
                                      my $selected_idx = $lb->GetCurSel() // 0;
                                      my $selected_txt = ((0<=$selected_idx) && ($selected_idx < $lb->Count)) ? $lb->GetText($selected_idx) : '';
                                      $lb->RemoveItem(0) while $lb->Count;
                                      $lb->Add( @map{ sort {$a<=>$b} formats() } );
                                      my $new_idx = $selected_txt ? $lb->FindStringExact($selected_txt) : undef;
                                      $new_idx = undef unless defined($new_idx) && (0 <= $new_idx) && ($new_idx < $lb->Count);
                                      $lb->Select( $new_idx//0 );
                                      $update_preview->( $lb );
                                  };
                              
                                  my $button_top = $dlg->LB->Top()+$dlg->LB->Height()-25;
                              
                                  $dlg->AddButton(                                    # v1.2: add this button
                                      -name    => 'REFRESH',
                                      -text    => 'Refresh',
                                      -size    => [80,25],
                                      -left    => $dlg->ScaleWidth()-90*3,
                                      -top     => $button_top,
                                      -onClick => sub{
                                          $refresh_formats->();
                                          1;
                                      },
                                  );
                              
                                  $dlg->AddButton(
                                      -name    => 'OK',
                                      -text    => 'Paste',
                                      -size    => [80,25],
                                      -left    => $dlg->ScaleWidth()-90*2,
                                      -top     => $button_top,
                                      -onClick => sub{                # v1.3: allow to persist after paste: TODO: move the editor->addText here
                                          editor->addText( Encode::encode("UTF8", $clipboard) ) if defined $clipboard;
                                          return $persist ? 1 : -1;
                                      },
                                  );
                              
                                  $dlg->AddButton(
                                      -name    => 'CANCEL',
                                      -text    => 'Cancel',
                                      -size    => [80,25],
                                      -left    => $dlg->ScaleWidth()-90*1,
                                      -top     => $button_top,
                                      -onClick => sub{ $clipboard=undef; -1; },
                                  );
                              
                                  $dlg->AddGroupbox(
                                      -name  => 'GB',
                                      -title => 'Preview',
                                      -pos   => [250,10],
                                      -size  => [$dlg->ScaleWidth()-260, $button_top-20],
                                  );
                              
                                  $dlg->AddLabel(
                                      -name           => 'PREVIEW',
                                      -left           => $dlg->GB->Left()+10,
                                      -top            => $dlg->GB->Top()+20,
                                      -width          => $dlg->GB->ScaleWidth()-20,
                                      -height         => $dlg->GB->ScaleHeight()-40,
                                  );
                              
                                  $dlg->AddCheckbox(
                                      -name => 'CB',
                                      -text => 'Persist',
                                      -pos => [$dlg->GB->Left(), $button_top],
                                      -onClick => sub {
                                          $persist = !$persist;
                                          1;
                                      },
                                  );
                              
                                  $dlg->CB->SetCheck($persist);
                                  $refresh_formats->();
                                  $dlg->Show();
                                  Win32::GUI::Dialog();
                                  return $clipboard;
                              }
                              
                              1 Reply Last reply Reply Quote 1
                              • PeterJonesP
                                PeterJones
                                last edited by PeterJones

                                This post is deleted!
                                1 Reply Last reply Reply Quote 0
                                • PeterJonesP
                                  PeterJones
                                  last edited by PeterJones

                                  pasteSpecial.pl - v2.1

                                  Updates:

                                  • Fix “bitmap” bug (if a bitmap was in the clipboard, trying to preview would cause script to crash)

                                  Requirements:

                                  • Perl
                                  • Install “PerlScript” module

                                  Usage

                                  • Notepad++ menu: Run > Run: "c:\path\to\perl.exe" "c:\path\to\pasteSpecial.pl"
                                  #!/usr/bin/env perl
                                  ################################################
                                  # PasteSpecial for Notepad++
                                  #   List formats currently on the clipboard
                                  #   Allows you to choose one of those formats
                                  #   Will paste the selected type (UTF8-encoded)
                                  #   at the current location in the active file
                                  ################################################
                                  # HISTORY
                                  #   v0.1: STDIN-based choice
                                  #   v1.0: DialogBox choice
                                  #   v2.0: Add REFRESH button to update the ListBox
                                  #         Defaults to selecting/displaying the first Clipboard variant
                                  #         Persist checkbox allows dialog to stay open for multiple pastes
                                  #   v2.1: Fix the "bitmap" bug (having bitmaps is clipboard caused crash)
                                  ################################################
                                  
                                  use 5.010;
                                  use warnings;
                                  use strict;
                                  use Win32::Clipboard;
                                  use Win32::GUI;
                                  use Win32::GUI::Constants qw/CW_USEDEFAULT/;
                                  use Encode;
                                  use Win32::Mechanize::NotepadPlusPlus 0.004 qw/:main/;   # this works even with v0.004, even without bugfix for prompt()
                                  
                                  our $VERSION = 'v2.1';
                                  
                                  BEGIN {
                                      binmode STDERR, ':utf8';
                                      binmode STDOUT, ':utf8';
                                  }
                                  
                                  my %map = (
                                      CF_TEXT()           => 'CF_TEXT',
                                      CF_BITMAP()         => 'CF_BITMAP',
                                      CF_METAFILEPICT()   => 'CF_METAFILEPICT',
                                      CF_SYLK()           => 'CF_SYLK',
                                      CF_DIF()            => 'CF_DIF',
                                      CF_TIFF()           => 'CF_TIFF',
                                      CF_OEMTEXT()        => 'CF_OEMTEXT',
                                      CF_DIB()            => 'CF_DIB',
                                      CF_PALETTE()        => 'CF_PALETTE',
                                      CF_PENDATA()        => 'CF_PENDATA',
                                      CF_RIFF()           => 'CF_RIFF',
                                      CF_WAVE()           => 'CF_WAVE',
                                      CF_UNICODETEXT()    => 'CF_UNICODETEXT',
                                      CF_ENHMETAFILE()    => 'CF_ENHMETAFILE',
                                      CF_HDROP()          => 'CF_HDROP',
                                      CF_LOCALE()         => 'CF_LOCALE',
                                  );
                                  my %rmap; @rmap{values %map} = keys %map;
                                  
                                  my $CLIP = Win32::Clipboard;
                                  
                                  my $answer = runDialog();
                                  #editor->addText(Encode::encode("UTF8", $answer)) if defined $answer;   #v1.3: moved to the PASTE button, below
                                  exit;
                                  
                                  sub formats {
                                      my @f = $CLIP->EnumFormats();
                                      foreach my $format (sort {$a <=> $b} @f) {
                                          $map{$format} //= $CLIP->GetFormatName($format) // '<unknown>';
                                          $rmap{ $map{$format} } = $format;
                                      }
                                      return @f;
                                  }
                                  
                                  sub runDialog {
                                      my $clipboard;
                                      my $persist = 1;
                                  
                                      my $dlg = Win32::GUI::Window->new(
                                          -title          => sprintf('Notepad++ Paste Special %s', $VERSION),
                                          -left           => CW_USEDEFAULT,
                                          -top            => CW_USEDEFAULT,
                                          -size           => [580,300],
                                          -resizable      => 0,
                                          -maximizebox    => 0,
                                          -hashelp => 0,
                                          -dialogui => 1,
                                      );
                                      my $icon = Win32::GUI::Icon->new(100);              # v1.1: change the icon
                                      $dlg->SetIcon($icon) if defined $icon;
                                  
                                      my $update_preview = sub {
                                          my $self = shift // return -1;
                                          my $value = $self->GetText($self->GetCurSel());
                                          my $f=$rmap{$value};
                                          $clipboard = $CLIP->IsBitmap() ? $CLIP->GetBitmap() :
                                                       $CLIP->IsFiles()  ? ($CLIP->GetFiles())[0] :
                                                                           $CLIP->GetAs($f);
                                          $clipboard = Encode::decode('UTF16-LE', $clipboard) if $f == CF_UNICODETEXT();
                                          (my $preview = $clipboard) =~ s/([^\x20-\x7F\r\n])/sprintf '\x{%02X}', ord $1/ge;
                                          $preview =~ s/\R/\r\n/g;
                                          $preview = substr($preview,0,297)."..." if length($preview)>300;
                                          $self->GetParent()->PREVIEW->Text( $preview );
                                          return 1;
                                      };
                                      my $lb = $dlg->AddListbox(
                                          -name           => 'LB',
                                          -pos            => [10,10],
                                          -size           => [230, $dlg->ScaleHeight()-10],
                                          -vscroll        => 1,
                                          -onSelChange    => $update_preview,             # v1.2: externalize this callback so it can be run from elsewhere
                                      );
                                  
                                      my $refresh_formats = sub {
                                          my $lb = $dlg->LB;
                                          my $selected_idx = $lb->GetCurSel() // 0;
                                          my $selected_txt = ((0<=$selected_idx) && ($selected_idx < $lb->Count)) ? $lb->GetText($selected_idx) : '';
                                          $lb->RemoveItem(0) while $lb->Count;
                                          $lb->Add( @map{ sort {$a<=>$b} formats() } );
                                          my $new_idx = $selected_txt ? $lb->FindStringExact($selected_txt) : undef;
                                          $new_idx = undef unless defined($new_idx) && (0 <= $new_idx) && ($new_idx < $lb->Count);
                                          $lb->Select( $new_idx//0 );
                                          $update_preview->( $lb );
                                      };
                                  
                                      my $button_top = $dlg->LB->Top()+$dlg->LB->Height()-25;
                                  
                                      $dlg->AddButton(                                    # v1.2: add this button
                                          -name    => 'REFRESH',
                                          -text    => 'Refresh',
                                          -size    => [80,25],
                                          -left    => $dlg->ScaleWidth()-90*3,
                                          -top     => $button_top,
                                          -onClick => sub{
                                              $refresh_formats->();
                                              1;
                                          },
                                      );
                                  
                                      $dlg->AddButton(
                                          -name    => 'OK',
                                          -text    => 'Paste',
                                          -size    => [80,25],
                                          -left    => $dlg->ScaleWidth()-90*2,
                                          -top     => $button_top,
                                          -onClick => sub{                # v1.3: allow to persist after paste: TODO: move the editor->addText here
                                              editor->addText( Encode::encode("UTF8", $clipboard) ) if defined $clipboard;
                                              return $persist ? 1 : -1;
                                          },
                                      );
                                  
                                      $dlg->AddButton(
                                          -name    => 'CANCEL',
                                          -text    => 'Cancel',
                                          -size    => [80,25],
                                          -left    => $dlg->ScaleWidth()-90*1,
                                          -top     => $button_top,
                                          -onClick => sub{ $clipboard=undef; -1; },
                                      );
                                  
                                      $dlg->AddGroupbox(
                                          -name  => 'GB',
                                          -title => 'Preview',
                                          -pos   => [250,10],
                                          -size  => [$dlg->ScaleWidth()-260, $button_top-20],
                                      );
                                  
                                      $dlg->AddLabel(
                                          -name           => 'PREVIEW',
                                          -left           => $dlg->GB->Left()+10,
                                          -top            => $dlg->GB->Top()+20,
                                          -width          => $dlg->GB->ScaleWidth()-20,
                                          -height         => $dlg->GB->ScaleHeight()-40,
                                      );
                                  
                                      $dlg->AddCheckbox(
                                          -name => 'CB',
                                          -text => 'Persist',
                                          -pos => [$dlg->GB->Left(), $button_top],
                                          -onClick => sub {
                                              $persist = !$persist;
                                              1;
                                          },
                                      );
                                  
                                      $dlg->CB->SetCheck($persist);
                                      $refresh_formats->();
                                      $dlg->Show();
                                      Win32::GUI::Dialog();
                                      return $clipboard;
                                  }
                                  
                                  1 Reply Last reply Reply Quote 3
                                  • First post
                                    Last post
                                  The Community of users of the Notepad++ text editor.
                                  Powered by NodeBB | Contributors