BookmarkSubscribe
Choose Language Hide Translation Bar
pmroz
Super User

Copy Listbox Contents with LF delimiters Instead of Tabs?

If I copy the highlighted contents of a listbox I get a tab-delimited string.  However I want each selected entry to be on its own line.

nw = new window("test",
	lb = list box({"AAAAA", "BBBBB", "CCCCC", "DDDDD"}, width(100), 
		max selected(-1),
		nlines(8)
	)
);

If I highlight the last three entries and right-click copy

listbox.png

I get this string:

BBBBB	CCCCC	DDDDD

What I want is this:

BBBBB
CCCCC
DDDDD

I can create my own "Copy to Clipboard" button that will do the conversion, but is there an easier way?

0 Kudos
1 ACCEPTED SOLUTION

Accepted Solutions
gzmorgan0
Super User

Re: Copy Listbox Contents with LF delimiters Instead of Tabs?

@pmroz ,

Your solution is not so bad, except for management of button box and listbox. However, you could use relative object references: each Copy Button and ListBox are nested in a VListBox Container and for the ButtonBox, use <<Set Function(Function({this}...)) where the listbox can be referenced as  (this << sib) << get selected, etc. A script example called Copy_ButtonBoxSib.jsl is attached.  This is likely not new to you, just here as an FYI to others on the Community Blog.

 

A ListBox() has an option to <<Set Context Script(). With a context menu script, the copy button is not required.

 

I have not figured out if there is a method to reference itself in the menu script. Here is a simple script with 3 ListBox with a context menu script to copy:

  • Select items
  • Right click in the ListBox, Copy will appear, select it.
  • I placed a button to paste the text to test this

See the screenshot and script.

image.png

 

 

Names Default to Here(1);
lf = "\!N";

mylb =Function({usrlist}, {lb},
	lb = ListBox(usrlist, width(100), max selected(-1), nlines(8));
	lb
);

mycopy = Function({this}, {sel}, 
	sel = this << get selected;
	if(nitems(sel)>0, set clipboard(concat items(sel,lf)) )
);

mylist1 = {"AAAAA", "BBBBB", "CCCCC", "DDDDD"};
mylist2 = {"xxxxx", "yyyyy", "zzzzz", "wwwww"};
mylist3 = {"dog", "cat", "parrot", "hamster"};

lb1 = mylb(mylist1);
lb2 = mylb(mylist2);
lb3 = mylb(mylist3);
list_lb = {lb1, b2,lb3};

Names Default To Here( 1 );
New Window( "Example",
 VlistBox(
   HListbox(lb1,lb2,lb3),
   ButtonBox("show It", <<SetFunction(Function({this}, {cb},
   	  cb = get clipboard();
   	  (this<<sib) << Set Text(cb);
   ))),
   TextBox()
 )  

);

//I don't know how to specify "this" for Context Menu Script
//If there is a method, then the context menu script could be assigned 
//with the mylb() function
lb1 << Set Context Menu Script( {"Copy", mycopy(lb1)} );
lb2 << Set Context Menu Script( {"Copy", mycopy(lb2)} );
lb3 << Set Context Menu Script( {"Copy", mycopy(lb3)} );
0 Kudos
6 REPLIES 6
txnelson
Super User

Re: Copy Listbox Contents with LF delimiters Instead of Tabs?

you might try adding \!n to the end of each value and see if that gives you what you want. It would be a kluge, but it might get the job done
Jim
0 Kudos
pmroz
Super User

Re: Copy Listbox Contents with LF delimiters Instead of Tabs?

Interesting idea Jim, but the resulting listbox shows blanks.  When I highlight rows and hit CTRL-C the pasted results are on separate lines but the tabs are still there.

I have multiple listboxes that people want to copy from; I have a dedicated button at the top of each one that uses this logic:

lf = "
";

nw = new window("test",
	cb = button box("Copy to Clipboard", 
		selected_items = lb << get selected;
		if (nitems(selected_items) > 0,
			set clipboard(concat items(selected_items, lf)),
		),
	),
	lb = list box({"AAAAA", "BBBBB", "CCCCC", "DDDDD"}, width(100), 
		max selected(-1),
		nlines(8)
	)
);
0 Kudos
gzmorgan0
Super User

Re: Copy Listbox Contents with LF delimiters Instead of Tabs?

@pmroz ,

Your solution is not so bad, except for management of button box and listbox. However, you could use relative object references: each Copy Button and ListBox are nested in a VListBox Container and for the ButtonBox, use <<Set Function(Function({this}...)) where the listbox can be referenced as  (this << sib) << get selected, etc. A script example called Copy_ButtonBoxSib.jsl is attached.  This is likely not new to you, just here as an FYI to others on the Community Blog.

 

A ListBox() has an option to <<Set Context Script(). With a context menu script, the copy button is not required.

 

I have not figured out if there is a method to reference itself in the menu script. Here is a simple script with 3 ListBox with a context menu script to copy:

  • Select items
  • Right click in the ListBox, Copy will appear, select it.
  • I placed a button to paste the text to test this

See the screenshot and script.

image.png

 

 

Names Default to Here(1);
lf = "\!N";

mylb =Function({usrlist}, {lb},
	lb = ListBox(usrlist, width(100), max selected(-1), nlines(8));
	lb
);

mycopy = Function({this}, {sel}, 
	sel = this << get selected;
	if(nitems(sel)>0, set clipboard(concat items(sel,lf)) )
);

mylist1 = {"AAAAA", "BBBBB", "CCCCC", "DDDDD"};
mylist2 = {"xxxxx", "yyyyy", "zzzzz", "wwwww"};
mylist3 = {"dog", "cat", "parrot", "hamster"};

lb1 = mylb(mylist1);
lb2 = mylb(mylist2);
lb3 = mylb(mylist3);
list_lb = {lb1, b2,lb3};

Names Default To Here( 1 );
New Window( "Example",
 VlistBox(
   HListbox(lb1,lb2,lb3),
   ButtonBox("show It", <<SetFunction(Function({this}, {cb},
   	  cb = get clipboard();
   	  (this<<sib) << Set Text(cb);
   ))),
   TextBox()
 )  

);

//I don't know how to specify "this" for Context Menu Script
//If there is a method, then the context menu script could be assigned 
//with the mylb() function
lb1 << Set Context Menu Script( {"Copy", mycopy(lb1)} );
lb2 << Set Context Menu Script( {"Copy", mycopy(lb2)} );
lb3 << Set Context Menu Script( {"Copy", mycopy(lb3)} );
0 Kudos
pmroz
Super User

Re: Copy Listbox Contents with LF delimiters Instead of Tabs?

Thanks @gzmorgan0 that's a really cool technique.  Now I'll have to train my users to right click > Copy instead of using CTRL-C.

0 Kudos
Highlighted
vince_faller
Super User

Re: Copy Listbox Contents with LF delimiters Instead of Tabs?

You could evaluate the box in the function to send a self referential function.  

 

mylb =Function({usrlist}, {lb},
	lb = ListBox(usrlist, width(100), max selected(-1), nlines(8));
	Eval(Substitute(
		Expr(DV_LB << Set Context Menu Script({"Copy", mycopy(DV_LB)})), 
		Expr(DV_LB), lb
	));
	lb;
);

*CAVEAT* last I checked this method doesn't work when encrypted.  

Vince Faller - Predictum
gzmorgan0
Super User

Re: Copy Listbox Contents with LF delimiters Instead of Tabs?

Thank you @vince_faller.  This eliminates the need for a for loop. 

 

The substitute() passes the JMP parser, where assigning the property straight away did not work.  Nice work around. 

 

 

0 Kudos