Copy ListView Items to a ListView on another form

Copy ListView Items to a ListView on another form

Post by Jack Mill » Sun, 13 Jun 2004 18:40:15


How to copy selected items in a ListView to a ListView on a different form.
Both ListView's have the same amount of Sub Items.

Thanks for any help.
Jack
 
 
 

Copy ListView Items to a ListView on another form

Post by Team » Mon, 14 Jun 2004 04:04:47


form.

TListItem *SelectedItem = Form1->ListView1->Selected;
while( SelectedItem )
{
Form2->ListView1->Items->Add()->Assign(SelectedItem);
SelectedItem = Form1->ListView1->GetNextItem(SelectedItem, sdAll,
TItemStates() << isSelected);
}


Gambit

 
 
 

Copy ListView Items to a ListView on another form

Post by Jack Mill » Mon, 14 Jun 2004 17:15:48

Thanks Gambit
Unfortunately I didn't describe my needs adequately. I don't know the Form
name.
I have 2 forms open (2 instances of the same form ? with different data)
with different names e.g. EM 2 & EM 35, the Form names are not fixed. I want
to select a few rows on the one form & paste them into the other.

Jack
 
 
 

Copy ListView Items to a ListView on another form

Post by Team » Tue, 15 Jun 2004 10:08:57


The code I showed you earlier still applies. All you need is *pointers* to
the desired forms, or even just the ListViews themselves. Without those,
you pretty much can't do anything anyway. How you get those pointers is up
to you, depending on what you are actually trying to do.


Gambit
 
 
 

Copy ListView Items to a ListView on another form

Post by Jack Mill » Tue, 15 Jun 2004 23:04:47

Thanks Gambit.
Unfortunately I still need more help with the pointer side of things.
The 2 forms containing the ListViews I create like this from FormA.

TEM_PatForm *EM_Pattern;
EM_Pattern = new TEM_PatForm(this);

EM_Pattern->Query1->DatabaseName = Query1->DatabaseName;
EM_Pattern->Query1->Tag = ListView2->Selected->Index + 1; // the EM
number
EM_Pattern->Show();

The newly created form then uses a query based on the number in Tag, to fill
in its own ListView.

How do I point to the other instance of the same form ? Form1= Form2 =
EMPattern ?

TListItem *SelectedItem = Form1->ListView1->Selected;
while( SelectedItem )
{
Form2->ListView1->Items->Add()->Assign(SelectedItem);
SelectedItem = Form1->ListView1->GetNextItem(SelectedItem, sdAll,
TItemStates() << isSelected);
}

Thanks
Jack
 
 
 

Copy ListView Items to a ListView on another form

Post by Team » Wed, 16 Jun 2004 02:39:15


Which ListView are you actually copying from? Which ListView are you
actually copying to?


Gambit
 
 
 

Copy ListView Items to a ListView on another form

Post by Jack Mill » Wed, 16 Jun 2004 16:54:54

Hi Gambit

I want to able to copy from any EM ListView to any other EM ListView.

FormA opens multiple instances (normally 2, but could be more) of the
EMPattern form which contains the ListView.
The form instance EMPattern, contains information about a particular EM,
there are 256 potential EM's, I want the ability to open any 2 EM's & copy
information between the 2.
Hope I've described that ok.

Jack
 
 
 

Copy ListView Items to a ListView on another form

Post by JD » Wed, 16 Jun 2004 17:59:55


You *must* have some way to disinguish between the source and
destination controls. Are there ever more than 2 open at a
time? How does the GUI initiate the copy?

If you can't workout a method to indicate which 2 controls to use, you'll have to do some sort of drag-n-drop.

~ JD
 
 
 

Copy ListView Items to a ListView on another form

Post by Jack Mill » Wed, 16 Jun 2004 21:27:40

Thanks JD

destination controls.

I will think upon what you have said, because that appears to be the root
cause of my problem using this approach.
The Caption of each instance contains a unique identifier e.g EM 5, EM 9
etc.


There could be.


If I understand the question correctly.
The user would select the items to be copied in the one ListView, choose
copy from a menu,
then select an item in the other ListView & choose paste.

Thanks to all, for the help.

Jack
 
 
 

Copy ListView Items to a ListView on another form

Post by Team » Thu, 17 Jun 2004 02:35:46


It is your responsibilty to keep track of which ListViews are selected at
the time the "Copy" and "Paste" items are clicked.

Is your EM form an MDI child form? Is your menu a popup menu on the
ListView itself, or on a menu bar of a form? If a form, then which one?
These are important questions as they dictate how the code can work exactly.


Gambit
 
 
 

Copy ListView Items to a ListView on another form

Post by JD » Thu, 17 Jun 2004 02:41:28


You can work with what you have but it gets messy.

When the user selects copy from the menu, itterate the currently
open ListViews. If none of them or more than one of them has
selected items, report an error. Otherwise save a pointer to
the source ListView (or the name).

When the user selects paste, first check that the source is
still available and still has selected items. Then itterate
the open controls again looking for another control with a
selected item - again ensuring that only one other control has
selected item(s) and that only one item is selected as the
destination.

Your other option is to create a custom clipboard format and
copy something that points to the source to the clipboard.
When paste is selected, check the clipboard format before
proceeding.

~ JD
 
 
 

Copy ListView Items to a ListView on another form

Post by Jack Mill » Thu, 17 Jun 2004 17:05:35

Not sure of the correct procedure so replying to both helpers in one
message.

Hi Gambit
Yes! (see below)

form?
Popup menu on the ListView!

Hi JD

I started yesterday looking at creating copy & paste functions on the Parent
form (whose name I know) & declaring a global pointer to a TList (Still
looking at that choice).
Calling the copy function on the parent from LV1 to copy the LV1 Items back
to the Parent form, then calling the parent paste function from LV2 to paste
from the Parent into LV2.

Not there yet, but thanks to your comments I am still making progress.

Thank you both for your help.

Jack
 
 
 

Copy ListView Items to a ListView on another form

Post by JD » Thu, 17 Jun 2004 21:54:51


Not sure why Gambit asked this but ...


I do know why Gambit asked this!! It's because the TPupupMenu
has a PopupComponent property which points back to the component
that is using the popup. If you assign the same popup to all
of the ListViews, you have a tidy solution available.

To be clear, that means that you assign the same block(s) of
code (the popup menu and it's associated functions) to each
ListView - not that each has identical copies of the code that
live inside each MDIChild form.

To do this, move the TPopupMenu from the MDIChild to the
MDIParent form. Then when you create the MDIChild, before you
pass control to it, simply assign the popup menu to the ListView:

TMyChild *ChildForm = new TMyChild( this );
ChildForm->ListView1->PopupMenu = ThePopupMenuName;

Now to make it do what you want, add an OnPopup event to the
menu where you do some checking to set the menu options. Here
the Tag property comes in handy to help keep track of the
source ListView:

void __fastcall TForm1::ListViewPopupMenuPopup(TObject *Sender)
{
TPopupMenu* pMenu = static_cast<TPopupMenu*>( Sender );
TListView* LV1 = dynamic_cast<TListView*>( pMenu->PopupComponent );
// disable both copy and paste menu options
if( LV1->SelCount > 0 )
{
// enable copy
// now check to see if you should enable paste
TListView* LV2 = reinterpret_cast<TListView*>( pMenu->Tag );
if( LV2 && LV2->SelCount > 0 && LV1->SelCount == 1 )
{
// enable paste
}
}
}
//-------------------------------------------------------------
void __fastcall TForm1::ListViewMenuCopyClick(TObject *Sender)
{
TPopupMenu* pMenu = static_cast<TPopupMenu*>( Sender );
pMenu->Tag = reinterpret_cast<int>( pMenu->PopupComponent );
}
//-------------------------------------------------------------
void __fastcall TForm1::ListViewMenuPasteClick(TObject *Sender)
{
TPopupMenu* pMenu = static_cast<TPopupMenu*>( Sender );
TListView* Source = reinterpret_cast<TListView*>( pMenu->Tag );
TListView* Destination = dynamic_cast<TListView*>( pMenu->PopupComponent );
// call the function to copy the Source to the Destination
}
//-------------------------------------------------------------

That's simple enough no? However, there's one more thing that
you need to account for. What if the user selects copy and
closes the form and then selects paste to another ListView?

That will cause an AV because the TPopupMenu::Tag will be
pointing to a no-longer-existing ListView. Handle this by
using the MDIChild's OnClose event to set Tag to zero when
it's needed:

void __fastcall TMyChild::FormClose(TObject *Sender, TCloseAction &Action)
{
TListView* LV = reinterpret_cast<TListView*>( ListView1->PopupMenu->Tag );
if( LV && LV == ListView1 )
{
ListView1->PopupMenu->Tag = 0;
}
}

~ JD
 
 
 

Copy ListView Items to a ListView on another form

Post by Team » Fri, 18 Jun 2004 02:04:46


Then that makes it a lot easier since TPopupMenu has a PopupComponent
property that points to the actual component instance that is displaying the
popup menu. As such, you can do something like the following:

TListView *SourceLV = NULL;

void __fastcall TForm1::CopyClick(TObject *Sender)
{
TListView *LV =
dynamic_cast<TListView*>(PopupMenu1->PopupComponent);
if( (LV) && (LV->SelCount > 0) )
SourceLV = LV;
}

void __fastcall TForm1::PasteClick(TObject *Sender)
{
if( SourceLV )
{
TListView *TargetLV =
dynamic_cast<TListView*>(PopupMenu1->PopupComponent);
if( TargetLV )
{
// copy items from SourceLV to TargetLV as shown earlier...
}
}
}


Gambit
 
 
 

Copy ListView Items to a ListView on another form

Post by Team » Fri, 18 Jun 2004 02:10:35


If the forms were MDI child forms, and the popup menu was on a toolbar, then
it would be easy to know which MDI child form was last active at the time
the menu is invoked, using the main form's ActiveMDIChild property. But if
the forms were not MDI children, then Jack would have to keep track of focus
shifting manually in order to know which form to look at when gaining access
to the appropriate ListView.


Because the location of the popup menu dictates how the menu handlers can
determine which ListView they are supposed to be acting upon.


I asked the question regarding where the popup menu was located because if
it were on a toolbar instead of a TPopupMenu, then that solution would not
work as you have described.


If you use dynamic_cast, then you must check the returned pointer for NULL.
Otherwise you risk an AccessViolation if the PopupComponent is not actually
a TListView to begin with.


Gambit