eth-siplab / SVG2Keynote-gui

SVG2Keynote is a macOS tool to convert Scalable Vector Graphics to Apple Keynote documents. SVG2Keynote preserves shape information (path styles, fills), such that shapes can be edited in Keynote.
MIT License
82 stars 6 forks source link

Error pasting SVGs #1

Open bkgmc opened 2 years ago

bkgmc commented 2 years ago

Hi, thank you very much for your tools. Unfortunately, recently I ran into a small problem. Maybe you can help me out? After compiling the GUI as-is I could not paste SVGs into Keynote (PDF works, though). Apple's Clipboardviewer's TSPNativeMetadata showed a Version 11.1, but my Keynote is 11.2. So I compiled proto-dump and ran get-protos.sh and dump-mappings.sh, then I edited generateMetadataMessageList like so:

std::vector<MessageWrapper *> generateMetadataMessageList() {
    // generate TSP.PasteboardMetadata
    auto* pasteboardMetadata = new TSP::PasteboardMetadata();
    pasteboardMetadata->add_version(11);
    pasteboardMetadata->add_version(2);
    //pasteboardMetadata->add_version(2);
    pasteboardMetadata->set_allocated_app_name(new std::string("com.apple.Keynote 11.2"));
    pasteboardMetadata->add_read_version(11);
    pasteboardMetadata->add_read_version(2);
    //pasteboardMetadata->add_read_version(0);

    return std::vector<MessageWrapper *> {createMessageWrapper(pasteboardMetadata, 11007, 52)};
}

After recompiling the library and the GUI, I still could not paste SVGs into Keynote. I'd be happy if you could give me a hint that points me in the right direction to fix my mistakes...

Thanks and cheers!

jonath4ndev commented 2 years ago

Hello, Unfortunately I currently don't have access to a mac so this is only a suggestion on how I would move forward rather than a fix.

  1. Use the "Decode and Encode" functionality in the GUI. For this first copy something from keynote to clipboard, then press the button and paste. This will take the existing clipboard and rebuild it within the library.
  2. If this works then I would add logging convertListOfMessagesToProtoStream in the library. You should be able to use protoMessage->DebugString() to print all the data in the for loop. This should help you see if there were any further changes to TSP.PasteboardMetadata which you need to consider.

Hope this helps, Regards Jonathan

bkgmc commented 2 years ago

Hi Jonathan, thank you for your support. I did not know what the Decode/Encode functionality was about. Thanks, very helpful!

Unfortunately, I am still stuck. I have to admit that I am very clumsy when it comes to Mac/XCode issues and that I do not entirely grasp what is going on in your code. I'll have to do some more reading and learning. So please(!) do not feel obliged to help me any further, but if you have another idea for me, I'd be very grateful.

This is what I got so far:

Copying a simple square shape from Keynote and de/encoding it works fine and I can paste it back to keynote with no issues. I printed the all the archive and message info (with prepended "Message: " and "Archive: ") to decodeEncodeSquareShape.txt decodeEncodeSquareShape.txt

The SVG conversion still does not work. The corresponding output is in convertSVGToKeynote.txt. convertSVGToKeynote.txt

I also took screenshots of the Metadata in the ClipboardVierwer.

keynoteMeta svgMeta

There are some minor changes in my regenerated ProtoMapping.cpp, but I don't think they are relevant, because the old entries have not been renamed: ProtoMapping.txt

Again, please do not spend too much time on this, but if you quickly find something, your help will be greatly appreciated.

Cheers and happy holidays!

jonath4ndev commented 2 years ago

Hello,

I would suggest making a quick change to the DecodeAndEncodeSwift Function

func decodeAndEncodeSwift () -> Void {
    let pasteboard = NSPasteboard.general;
    let data = pasteboard.data(forType: NSPasteboard.PasteboardType("com.apple.iWork.TSPNativeData"))
    CPP_Wrapper().decodeAndEncodeClip(data);
}

change to:

func decodeAndEncodeSwift () -> Void {
    let pasteboard = NSPasteboard.general;
    let data = pasteboard.data(forType: NSPasteboard.PasteboardType("com.apple.iWork.TSPNativeMetadata"))
    CPP_Wrapper().decodeAndEncodeClip(data);
}

So that you can log the metadata Messages.

Then compare the message with type 11, which is already available in your convertSVGToKeynote.txt Regards Jonathan

bkgmc commented 2 years ago

Awesome! It seems to work now! This is how I had to change the generateMetadataMessageList function:

std::vector<MessageWrapper *> generateMetadataMessageList() {
    // generate TSP.PasteboardMetadata
    auto* pasteboardMetadata = new TSP::PasteboardMetadata();
    pasteboardMetadata->add_version(11);
    pasteboardMetadata->add_version(2);
    pasteboardMetadata->add_version(9);
    pasteboardMetadata->set_allocated_app_name(new std::string("com.apple.Keynote 11.2"));
    pasteboardMetadata->add_read_version(2);
    pasteboardMetadata->add_read_version(0);
    pasteboardMetadata->add_read_version(0);

    return std::vector<MessageWrapper *> {createMessageWrapper(pasteboardMetadata, 11007, 52)};
}

Thank you so much, Jonathan!