Copy / paste

Hello,
I’d like to override the copy paste function to actualize my data-structure.

Then I made my own CommandHandler to override CopyToClipboard and PasteFromClipboard.

But I get the following error :

Une exception de première chance de type 'System.OutOfMemoryException' s'est produite dans PresentationCore.dll
System.OutOfMemoryException: Mémoire insuffisante pour continuer l'exécution du programme.
   à System.Runtime.InteropServices.ComTypes.IDataObject.GetData(FORMATETC& format, STGMEDIUM& medium)
   à System.Windows.DataObject.OleConverter.GetDataInner(FORMATETC& formatetc, STGMEDIUM& medium)
   à System.Windows.DataObject.OleConverter.GetDataFromOleHGLOBAL(String format, DVASPECT aspect, Int32 index)
   à System.Windows.DataObject.OleConverter.GetDataFromBoundOleDataObject(String format, DVASPECT aspect, Int32 index)
   à System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert, DVASPECT aspect, Int32 index)
   à System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert)
   à System.Windows.DataObject.GetData(String format, Boolean autoConvert)
   à System.Windows.Clipboard.GetDataInternal(String format)
   à System.Windows.Clipboard.GetData(String format)
   à Northwoods.GoXam.CommandHandler.PasteFromClipboard()
   à SphinxV6.Concept.QDiagram.QD_CommandHandler.PasteFromClipboard() dans C:\dvlp\Project\WPF4\SphinxV6\Concept\QDiagram\Code\QD_DragSelectingTool.cs:ligne 78
   à Northwoods.GoXam.CommandHandler.Paste()

I use GoWPF, v1.1.3.3.
To help you understanding, here’s my code :

public class QD_CommandHandler : CommandHandler
    {
        protected override void CopyToClipboard(IDataCollection coll) 
        {
            base.CopyToClipboard(coll);
            List<QD_Node> lForDelete = new List<QD_Node>();
            IEnumerable<SphPart> oSphPart = null;
            try
            {
                oSphPart = (IEnumerable<SphPart>)coll.Nodes.Where(n => ((QD_Node)n).QDCategory == QD_Node.ECategory.Part).Select(n => (SphPart)((QD_Node)n).Item);
            }
            catch { }
            foreach (QD_Node  oNode in coll.Nodes)
            {
                switch (oNode.QDCategory)
                {
                    case QD_Node.ECategory.Note:
                        oNode.Note = (SphNote)oNode.Note.Clone();
                        break;
                    case QD_Node.ECategory.Restriction:
                        lForDelete.Add(oNode);
                        break;
                    default:
                        if (oSphPart != null && oNode.Item.GetParentParts().Intersect(oSphPart).Any() == false)
                            oNode.Item = oNode.Item.Clone();                    
                        break;
                }
            }
            if (lForDelete.Count > 0)
            {
                MessageBox.Show("Les restrictions ne seront pas copiées.", "Restriction", MessageBoxButton.OK, MessageBoxImage.Information);
                foreach (QD_Node oNode in lForDelete)
                {
                    coll.RemoveNode(oNode);
                }
            }

            List<QD_Link> lLinkForDelete = new List<QD_Link>();
            foreach (QD_Link oLink in coll.Links)
            {
                if (oLink.QDCategory != QD_Link.ECategory.Belongs)
                {
                    lLinkForDelete.Add(oLink);
                }
            }
            if (lLinkForDelete.Count > 0)
            {
                foreach (QD_Link oLink in lLinkForDelete)
                {
                    coll.RemoveLink(oLink);
                }
            }
        }

        protected override IDataCollection PasteFromClipboard()
        {
            IDataCollection oColl =  base.PasteFromClipboard();
            foreach (QD_Node oNode in oColl.Nodes)
            {
                switch (oNode.QDCategory)
                {
                    case QD_Node.ECategory.Note:
                        Session.Survey.Notes.Add(oNode.Note);
                        break;
                    case QD_Node.ECategory.Restriction:
                        //TODO
                        break;
                    default:
                        Session.Survey.Items.Add(oNode.Item);
                        break;
                }
            }            
            return oColl;
        }
    }

Thanks for your help
Aurore

I can look at this more carefully later, but my first impression is that the “Edit Copy” operation ought not to delete nodes or otherwise modify the current Diagram by cloning data.

Should your code logic work when the user repeatedly types Control-C?

To precise my issue,

I don’t clone diagram model but only my hierarchical structure.

because our clone function copy all the branch, if user select the parent and some child I need to delete childs from copy because it will be re-added after parent clone…

In others terms, if you select the parent node, it will be copy all the branch, and then create appropriated node in the diagram model.

I don’t understand your question :

[Quote]
Should your code logic work when the user repeatedly types Control-C?
[\quote]

Our interrogation is “can we let the user repeatedly types Control-V ?” (one Ctrl-C, several Ctrl-V).
If you have some arguments to help us decide…

I have think of the problem this end of week, I can probably do the action in an other way. I probably can make my logic paste for my structure in AddedNode model function. But I’m not sure you call this. I read in your documentation that IDiagramModel.AddCollectionCopy is called.
But I didn’t arrive to override this function in my custumized diagram model.

============= 2 hours later…
well I try the following :
I don’t override CopyToClipboard,
I override PasteToClipboard :

[Code]
((QD_GraphLinkModel)this.Diagram.Model).eTransaction = ETransaction.PASTE;
IDataCollection oColl = null;
//try
{
oColl = base.PasteFromClipboard();
}
//catch (Exception excp)
//{
//}
((QD_GraphLinkModel)this.Diagram.Model).eTransaction = ETransaction.NONE;
return oColl;
[\code]

And code my paste logic in insertnode’s function in diagram model.

results :

I still have errors

Une exception de première chance de type 'System.Runtime.Serialization.SerializationException' s'est produite dans mscorlib.dll
Une exception de première chance de type 'System.OutOfMemoryException' s'est produite dans PresentationCore.dll
System.OutOfMemoryException: Mémoire insuffisante pour continuer l'exécution du programme.
   à System.Runtime.InteropServices.ComTypes.IDataObject.GetData(FORMATETC& format, STGMEDIUM& medium)
   à System.Windows.DataObject.OleConverter.GetDataInner(FORMATETC& formatetc, STGMEDIUM& medium)
   à System.Windows.DataObject.OleConverter.GetDataFromOleHGLOBAL(String format, DVASPECT aspect, Int32 index)
   à System.Windows.DataObject.OleConverter.GetDataFromBoundOleDataObject(String format, DVASPECT aspect, Int32 index)
   à System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert, DVASPECT aspect, Int32 index)
   à System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert)
   à System.Windows.DataObject.GetData(String format, Boolean autoConvert)
   à System.Windows.Clipboard.GetDataInternal(String format)
   à System.Windows.Clipboard.GetData(String format)
   à Northwoods.GoXam.CommandHandler.PasteFromClipboard()
   à SphinxV6.Concept.QDiagram.QD_CommandHandler.PasteFromClipboard() dans C:\dvlp\Project\WPF4\SphinxV6\Concept\QDiagram\Code\QD_DragSelectingTool.cs:ligne 94
   à Northwoods.GoXam.CommandHandler.Paste()

first one, due to copy, second one due to paste…

can you tell me what are the requirements on Data structure to be used in your copy/paste functions ?

One funny thing is that if I catch the error on PasteFromClipboard (comments in the above code), coll is null, paste is not made.
If the error is not catched, it seems to work… the node in the diagram is created, my structure is updated too.

Aurore

My first guess is that some class(es) of yours don’t have a [Serializable] attribute.

Frankly, I don’t know exactly what is causing that exception. If you search the web you may find additional suggestions on what might be wrong. It’s unfortunate that Microsoft doesn’t provide more useful error messages, nor does it provide more useful documentation on clipboard data requirements.

Your right, it was in my data structure.

I made change to be able to serialize my datas.

Now this code works

   Clipboard.SetData("MyQD_Node", coll.Nodes.ElementAt(0));
   QD_Node oNode = Clipboard.GetData("MyQD_Node") as QD_Node;

but i still have an error using

   base.CopyToClipboard(coll);        

Can you just confirm that I am on the right way.
Thanks for all your ideas.

Aurore

So now your node data is serializable, but what about your link data? (It appears you are using GraphLinksModel.)

All DataCollections and the predefined …Data classes are already declared [Serializable] in GoWPF.

My link data are serialisable.
And for the moment in my test I select no link…

I made a test with my structures in your sample demo project, all is ok.
I serialize and deserialize as I need your and my structure.

I will continue to search what’s the difference between my application project and other tests i’ve done.

Thanks
Aurore