-
-
Notifications
You must be signed in to change notification settings - Fork 419
PICARD-2287: Copy and Paste multiple Tags #2613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
If there are multiple cells selected in the tags table, build a JSON string that represents all the selected rows.
If the clipboard contains JSON, interpret it as a set of new tag values.
c4aa758
to
dcccfcc
Compare
Apart coding style issues, please create a matching ticket, and be sure to prefix PR title with PICARD-xxxx (it creates a link between jira tickets & github PRs). |
Also, is this something that should be included / documented in the Picard User Guide? If so, please add a documentation ticket with a reference to this PR. (I noticed that you removed that part of the PR template for this PR.) Thanks. |
dcccfcc
to
1075aa1
Compare
Sorry - I meant to mark this as draft, while garnering feedback! |
I did have a trawl through the documentation and didn't see anywhere that stood out as an obvious place to update the information. Perhaps a whole new section of documentation, but I'm not sure (at this stage) whether this warrants it - feedback welcomed if it's non-obvious functionality. |
The current code (at the time of this comment) appears to be designed to meet the individual use case of @StevilKnevil, and as such is great as a proof of concept but it is not IMO generically applicable and should not be merged into Picard in its current form. I have copied the following comments I made from the Matrix / IRC discussion with my concerns:
Addendum:
|
1075aa1
to
84d3c93
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR. First off this works really well, and it is a very welcomed feature. I noticed I had even already created a ticket for this a long time ago. I updated the PR to link to PICARD-2287 instead and closed the newer one as a duplicate.
I have a few coding comments. But my main concern about right now is use experience when pasting. While this is a very powerful feature, it also can lead to some unwanted surprise if a paste suddenly overwrites a large number of tags, where the user maybe expected just to paste a value. This is especially bad as Picard does not yet support any undo functionality.
I see two possible solutions:
- Make copying the full tags an explicit option. At least then the user is aware they copied multiple values. But copying is less convenient.
- When pasting full tags, show a warning dialog that multiple tags would be overwritten. We could have an option to not show this dialog, which would allow advanced users who use this often to skip it. Ideally the dialog would also show which tags will get overwritten or even show a preview of the changes.
Even though more complex, I think the second option would work best.
@Sophist-UK You can store multiple representations of the data in the clipboard. So the JSON would be for internal use. The code can also fill in a plain text representation that by default would be pasted in other applications. Right now in the implementation this also contains the JSON structure, but I think it shouldn't. See my comment above.
That's actually rather easy, as the spreadsheet tools all support tab separated values. And this also makes for a nice default text representation of multiple tags, as pasting this to a text editor is also nice. Supporting a proper plain text representation is definitely something that needs to be considered here. Other formats can of course be added, but this is definitely outside the scope of this PR. Let's focus on what this PR tries to enable: Copy and pasting multiple tags between files inside Picard. |
@phw Philipp Steve and I have been discussing this privately on Discord, the gist of which was very similar to your comment - except we were thinking CSV rather than TSV. And we were thinking monospaced tabular as a default text representation rather than TSV - but your idea might work better. |
I looked a bit what other tagging tools are doing. A lot don't really support a table view like Picard and just have some text fields. MP3Tag generally shows all files with their tags in a spreadsheet like view, but doesn't allow selecting multiple specific values. It kind of supports copying the tags from one file to another internally, but to the system clipboard it only writes a plain/text list of compact info about the files:
Kid3 does have a spreadsheet like view for the metadata, but does not allow selecting multiple rows or fields. You can only edit a single field and copy data from there. Puddletag is interesting, as it writes a JSON structure to the normal text clipboard. See the selection in below screenshot. This gives the following structure: [
{
"title": [
"Hells Bells"
],
"album": [
"Back in Black"
],
"track": [
"1/10"
],
"__length": "05:12"
},
{
"title": [
"Shoot to Thrill"
],
"album": [
"Back in Black"
],
"track": [
"2/10"
],
"__length": "05:17"
}
] Very similar to ours. But I still think the approach from this PR with custom mime data and as discussed a separate text representation with spreadsheet compatibility is the better solution. App specific JSON data in plaintext clipboard is not that useful. |
This is all really good input - thanks everyone, it's what I'd hoped to get from raising this PR. I'm going to iterate again taking the above into account. I reckon I'm about 20% done so far :) My focus is to get copy and paste working inside Picard, and for Copy to other apps. There's definitely a follow up PR for paste from other apps. |
a25cdc4
to
1dbdc08
Compare
@StevilKnevil please fix style issues, it would ease reviews |
1dbdc08
to
93fdebf
Compare
10f74e6
to
ad035ad
Compare
…_from_json_clipboard()
…pdate_objects() - the idea is to be able to delay updates - _set_tag_values_delayed_updates() is a generator that lists modified objects - _update_objects() update passed objects
@StevilKnevil @phw I noticed we are updating File objects more than once when pasting multiple values. In order to avoid this I wrote StevilKnevil#1 Basically I split the code that update objects so we can delay the object.update() calls as well as ensuring we call that only once per object. Please have a look and tell me what you think. |
I see (and accept) your suggestion, and have a counter proposal: StevilKnevil#2. Essentially extend the mime data handling to have both a copy to mimedata from TagDiff and a populate metadatabox from mimedata function. That way the paste function just goes through the list (in order) and the first entry in that list that can handle one of the mimedatas on the clipboard is used to paste from the clipboard |
Rework Copy and Paste Actions to better support multiple mimetypes
586d0ad
to
7adbae4
Compare
7adbae4
to
de02cd7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@StevilKnevil This works now great and code looks good to me. I like how it also improves the general copy experience.
There is an accidentally committed bytecode file, but otherwise this is good to go.
test/__pycache__/test_mimedatahelper.cpython-311-pytest-8.3.5.pyc.36376
Outdated
Show resolved
Hide resolved
84f7014
to
ad4b168
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, thanks a lot
Summary
Multiple tags can be selected, and then copied and pasted between files.
PICARD-2287
Solution
When multiple tags are selected, copying them to the clipboard turns them into a JSON string with mimetype
application/json;contents=picard-tags
. Pasting this mimetype will iterate over all the tags in the JSON, and will apply thenew_value
to the current file. Ifnew_value
doesn't exist for the given tag in the clipboard then it will useoriginal_value
Example of the JSON on the clipboard:
This means that Copy and Paste now need to be added to the context menu when there is more than one cell selected.
The behaviour when a single cell is selected is unchanged, i.e. copy the value as plain text.