CopyAndPasteItemFXChain pl
From CockosWiki
(Difference between revisions)
Line 1: | Line 1: | ||
- | <source lang= | + | <source kjkjkj lang=perl> |
# | # | ||
# CopyAndPasteItemFXChain.pl | # CopyAndPasteItemFXChain.pl |
Revision as of 13:36, 29 January 2010
# # CopyAndPasteItemFXChain.pl # Mike Lacey # You run this script twice, once to "get" the FX Chain you want and then again # to Paste it to another Item or Items # 1 Select the Item containing the FX Chain you want to copy to other items # 2 Run the script # 3 Select the Item(s) you want to copy the FX Chain to # 4 Run the script # int CountSelectedMediaItems(ReaProject* proj) # bool GetSetItemState(MediaItem* item, char* str, int maxlen) # MediaItem* GetSelectedMediaItem(ReaProject* proj, int selitem) use strict; use warnings; use Win32::Clipboard; my $Clipboard = Win32::Clipboard(); use constant CURR_PROJ => 0; use constant FIRST_SEL => 0; use constant MAXLEN => (16 * 1024); use constant ACTION_NAME => "Copy And Paste Item FX Chain"; use constant MSGBOX_OKONLY => 0; use constant MSGBOX_YESNO => 4; use constant MSGBOX_YES => 6; use constant MSGBOX_NO => 7; use constant COPY => 0; use constant PASTE => 1; my $it; my $chunk; my $result; my $maxlen; my $indent; my $item; my ($before, $after, $section, $takefx); my $run_mode; my $report = " " . localtime() . "\n"; my $num_selected_items; # prototype(s) sub extract_section($$$); sub FXChainInClipBoard(); $report .= "initialised\n"; # get number of selected items my $prompt_str=''; my $action; my $nothing; $num_selected_items = RPR_CountSelectedMediaItems(CURR_PROJ); if($num_selected_items == 0){ $prompt_str = "No Items Selected.\n\nThis script needs to be run twice." . " The first run, with one Item selected, copies the Item FX Chain" . " (if any) into the Windows Clipboard.\n\n" . "A second run, with one or more Items selected, and a valid" . " FX Chain from a previous run of this script in the Windows Clipboard," . " will Paste that FX Chain into the selected Items.\n\n" . "No action will be taken now; press OK to return to REAPER\n"; RPR_MB($prompt_str, ACTION_NAME, MSGBOX_OKONLY); exit(0); }elsif($num_selected_items >= 1){ if(FXChainInClipBoard()){ $prompt_str = "One or more Items Selected and (what looks like...) an FX Chain" . " in the Windows Clipboard.\n\n" . "This will Paste the FX Chain into the selected Item or Items\n\n" . "Do you want to continue?"; ($action, $nothing, $nothing, $nothing) = RPR_MB($prompt_str, ACTION_NAME, MSGBOX_YESNO); $run_mode = PASTE if $action == MSGBOX_YES; } else { $prompt_str = "One or more Items Selected and no FX Chain in the Windows" . " Clipboard.\n\n" . "This will Copy the FX Chain of the selected Item into the" . " Windows Clipboard.\n\n" . "Do you want to continue?"; ($action, $nothing, $nothing, $nothing) = RPR_MB($prompt_str, ACTION_NAME, MSGBOX_YESNO); $run_mode = COPY if $action == MSGBOX_YES; } } if($run_mode == COPY){ # Get the FX chain from the selected item $it = RPR_GetSelectedMediaItem(CURR_PROJ, FIRST_SEL); $chunk = ""; # because I want to read the state of the first item ($result, $it, $chunk, $maxlen) = RPR_GetSetItemState($it, $chunk, MAXLEN); # pick out first TAXFEX section ($before, $takefx, $after) = extract_section($chunk, '<TAKEFX', 0); # remove the FXID lines $takefx =~ s/^FXID.+\n//mg; if($takefx){ $takefx = "REAPER-FXCHAIN-DATA\n" . $takefx; $Clipboard -> Set($takefx); } else { RPR_MB("No FX Chain in First Selected Item", ACTION_NAME, MSGBOX_OKONLY); } } elsif($run_mode == PASTE){ # Items Loop # copy that TAKEFX section into every selected item, replacing any # existing TAKEFX section in that item my $NewItemStr=''; $takefx = $Clipboard -> Get(); $takefx =~ s/^REAPER-FXCHAIN-DATA\n//; for $item ( 0 .. $num_selected_items - 1){ $chunk=""; $it = RPR_GetSelectedMediaItem(CURR_PROJ, $item); ($result, $it, $chunk, $maxlen) = RPR_GetSetItemState($it, $chunk, MAXLEN); ($before, $section, $after) = extract_section($chunk, '<TAKEFX', 0) if $result; unless($section){ $NewItemStr = substr $before, 0, -2; $NewItemStr .= "\n" . $takefx . ">\n"; } else { $NewItemStr = $before . $takefx . $after } $Clipboard -> Set($NewItemStr); ($result, $it, $chunk, $maxlen) = RPR_GetSetItemState($it, $NewItemStr, MAXLEN); } } exit(0); # subroutines below here sub extract_section($$$){ my($chunk, $name, $index) = @_; my @chunk; # to hold $chunk split into lines my $cline; # individual lines from @chunk my $indent; # to keep track in a multiline section my ($before, $section, $after); # return values my $inner_state = 0; # 0=before section, 1=in section, 2=after my $multiline = 0; # boolean, single line sections have no < my $occurrence = 0; $multiline = 1 if $name =~ /^</; # a multiline section? $before = $section = $after = ''; # just in case @chunk = split(/\n/,$chunk); # populate @chunk foreach $cline (@chunk){ # and loop through it if($inner_state == 0){ # "before" section if($cline =~ /^\s*$name(\s|$)/){ # correct section name - correct occurrence? if($occurrence == $index){ # Yes $indent++; # keep track of indents $inner_state = 1; # might be multiline... $section .= "$cline\n"; # build up return variable $inner_state = 2 # done unless unless $multiline; # it's a multiline section } else { # No, wrong occurrence $occurrence++; # keep looking last # unless already gone past it if $occurrence > $index; } } else { # still before the section we're looking for $before .= "$cline\n"; # so build up return variable } } elsif($inner_state == 1){ # in a multiline section $section .= "$cline\n"; # so build up return variable $indent++ if $cline =~ /</; # keep track of indents $indent-- if $cline =~ />/; # keep track of indents $inner_state = 2 if $indent == 0; # and get out if we're done } elsif($inner_state == 2){ # "after" section $after .= "$cline\n"; # so build up return variable } } return($before, $section, $after); } sub FXChainInClipBoard(){ use constant TRUE => 1; use constant FALSE => 0; my $CB; $CB = $Clipboard -> Get(); if($CB =~ /^REAPER-FXCHAIN-DATA\n/){ return(TRUE); } else { return(FALSE); } }