Skip to content
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

Implement file sorting in thumbnail view #6449

Merged
merged 4 commits into from
Jan 2, 2023
Merged

Conversation

haasn
Copy link
Contributor

@haasn haasn commented Mar 27, 2022

For simplicity, I decided to only implement the attributes that I could
verily easily reach from the existing metadata exported by Thumbnail -
which is the name (as usual), the datetime string (which should
effectively be the same as sorting by the actual date), the rank, and -
because it was there - the EXIF line. Ideally, I would also like to be
able to sort by "last modified" but I'm not sure of the best way to
reach this from this place in the code.

It's worth pointing out that, with the current implementation, the list
will not dynamically re-sort itself until you re-select the sorting
method - even if you make changes to the files that would otherwise
affect the sorting (e.g. changing the rank while sorting by rank). One
might even call this a feature, not a bug, since it prevents thumbnails
from moving around while you're trying to re-label them. You can always
re-select "sort by ..." from the context menu to force a re-sort.

Fixes #3317

@haasn
Copy link
Contributor Author

haasn commented Mar 27, 2022

sort_screenshot

@haasn
Copy link
Contributor Author

haasn commented Mar 27, 2022

For reference, I modeled the design after the pcmanfm context menu, which looks similar. Only difference is that it also has small radial ("option" style) checkboxes next to each option highlighting which one is currently in effect. That would be nice-to-have for us as well, but I got lazy. Maybe on a rainy day.

@Lawrence37
Copy link
Collaborator

Good to see someone working on the file browser sorting!

Regarding the automatic re-sorting, the current file browser will re-sort after a file name change. The image actually disappears then reappears, but it gets placed in a new location. I do agree that it may be better to not update the order after changing the rating or color label.

It seems you are using the date-time string that appears below the thumbnail? This might be problematic because the date format can be changed from the default year-month-day, so the sorting won't work as expected if it is set to month-day-year, for example.

Possible improvements either in this PR or in the future:

  • Consider the time zone. This can be challenging because each make puts the time zone in a different place or excludes it all together.
  • Add sorting widgets to the top toolbar so it is easy to discover and use.

@haasn
Copy link
Contributor Author

haasn commented Mar 28, 2022

Re: date sorting I think the proper solution would be to convert everything to UTC (e.g. via Glib::DateTime intermediary) for comparison sake. I'll have to look into how the plumbing for that works, so I can ideally bypass the string altogether.

I'll probably continue hacking at it $tomorrow or something, mostly submitted this to start getting feedback in and because I reached a limit of how much I wanted to explore this codebase for a day. Definitely also plan on adding a widget to the toolbar, should be easy enough to make an icon for it (the usual one is two arrows pointing in opposite directions).

@haasn
Copy link
Contributor Author

haasn commented Mar 30, 2022

Okay, I got some more time to hack on this. I made the following changes:

  1. Stop sorting based on the datetime string and start propagating a Glib::DateTime directly, to get around string-sorting limitations.
  2. Implement metadata plumbing for timezone information (as a string), which we can pull from EXIF (WIP: still need to do the actual EXIF loading/writing)
  3. Stop manually generating the DateTime string in favor of using DateTime::format, which allows the use of all recognized date/time formats.

1 is a clear improvement, 2 is a work-in-progress, and 3 is something I'm not sure you actually want. (Since it's not backwards compatible, and also the translations need to be updated...)

@haasn haasn changed the title Implement file sorting in thumbnail view WIP: Implement file sorting in thumbnail view Mar 30, 2022
@Lawrence37
Copy link
Collaborator

For 3, we can check the program version in the options file or use a new key to store the new format, and convert from the old format one time.
By the way, the AppImage build failed. Maybe there's a missing #include.

@haasn
Copy link
Contributor Author

haasn commented Apr 14, 2022

By the way, the AppImage build failed. Maybe there's a missing #include.

Yeah, needs an #include <timezone.h> as well. Should be fixed now.

@haasn
Copy link
Contributor Author

haasn commented Apr 14, 2022

So, I wanted to look into this again (specifically the timezone stuff) but it seems that at least my camera doesn't actually write any tags that could be used to determine the timezone from. So for the time being I think I'll scrap this approach/commit and simply go back to storing only the timestamp itself, without timezone information.

That also means we can (and probably should) split off the UI display change to a separate commit, if it's even desired at all.

@haasn haasn force-pushed the sorting branch 2 times, most recently from 368135d to 6f8c745 Compare April 14, 2022 22:34
@haasn
Copy link
Contributor Author

haasn commented Apr 14, 2022

Okay, I dropped the EXIF stuff for now and just implemented the sorting commit. I also switched from bare items to radio items, massively increasing quality of life in my mind.

I consider this commit now ready as-is.

@haasn haasn changed the title WIP: Implement file sorting in thumbnail view Implement file sorting in thumbnail view Apr 14, 2022
rtgui/thumbnail.cc Outdated Show resolved Hide resolved
rtgui/thumbnail.h Show resolved Hide resolved
haasn added a commit to haasn/RawTherapee that referenced this pull request May 13, 2022
As suggested in Beep6581#6449, with date-based sorting it can be useful to have
at least *some* sort of time-relevant information for EXIF-less files,
to prevent them from falling back to getting sorted alphabetically all
the time.

This commit simply defaults the file timestamp to the file's mtime as
returned by g_stat. For annoying reasons, it doesn't suffice to merely
forward the timestamp to the FileData structs - we also need to keep
track of it inside FilesData to cover the case of a file with 0 frames
in it.
@haasn
Copy link
Contributor Author

haasn commented May 13, 2022

Sorry for the delay. Should be fixed and updated now, and I confirmed that it works as expected in a mixed folder of valid, invalid and untagged (EXIF-less) image files, with a silent fallback to the modification date for EXIF-free files.

@Lawrence37
Copy link
Collaborator

Windows and Linux builds are failing...

https://github.com/Beep6581/RawTherapee/runs/6436307468?check_suite_focus=true#step:5:93

D:/a/RawTherapee/RawTherapee/rtengine/imagedata.cc:109:5: error: 'gmtime_r' was not declared in this scope; did you mean 'gmtime_s'?
  109 |     gmtime_r(&timeStamp, &time);
      |     ^~~~~~~~
      |     gmtime_s

https://github.com/Beep6581/RawTherapee/runs/6436307448?check_suite_focus=true#step:5:331

/home/runner/work/RawTherapee/RawTherapee/rtgui/thumbnail.cc:753:9: error: no match for ‘operator!’ (operand type is ‘Glib::DateTime’)
     if (!dateTime || !cfs.timeValid) {
         ^~~~~~~~~

@haasn
Copy link
Contributor Author

haasn commented May 24, 2022

/home/runner/work/RawTherapee/RawTherapee/rtgui/thumbnail.cc:753:9: error: no match for ‘operator!’ (operand type is ‘Glib::DateTime’)
     if (!dateTime || !cfs.timeValid) {
         ^~~~~~~~~

I'm not familiar with C++. What's a good way of working around this? Should I use if (!static_cast<bool>(dateTime) || !cfs.timeValid)?

Edit: I suppose easiest is to just invert the condition to if (!(dateTime && cfs.timeValid))

As suggested in Beep6581#6449, with date-based sorting it can be useful to have
at least *some* sort of time-relevant information for EXIF-less files,
to prevent them from falling back to getting sorted alphabetically all
the time.

This commit simply defaults the file timestamp to the file's mtime as
returned by g_stat. For annoying reasons, it doesn't suffice to merely
forward the timestamp to the FileData structs - we also need to keep
track of it inside FilesData to cover the case of a file with 0 frames
in it.
@Lawrence37
Copy link
Collaborator

Lawrence37 commented May 24, 2022

I don't think Glib::DateTime can be cast into a bool. The class needs an operator bool() which is only present in glibmm >=2.62.0. I don't see any other method to check if the datetime is valid. The workaround is probably to get the underlying GDateTime with gobj() and check if it's null.

@Floessie
Copy link
Collaborator

Your could try to use Glib::DateTime::equal() with a default constructed object (i.e. if (dateTime.equal({}))). Don't know if this works, but seems logical...

@haasn
Copy link
Contributor Author

haasn commented May 26, 2022

The workaround is probably to get the underlying GDateTime with gobj() and check if it's null.

Undefined behavior on nullptr.

Edit: ah, no, it doesn't actually return a nullptr, it returns a DateTime that has gobject_ set to a nullptr. So yeah that should work.

haasn added 2 commits May 26, 2022 22:43
Putting it here facilitate easier sorting without having to re-construct
the DateTime on every comparison.

To simplify things moving forwards, use the Glib::DateTime struct right
away. This struct also contains timezone information, but we don't
currently care about timezone - so just use the local timezone as the
best approximation. (Nothing currently depends on getting the timezone
right, anyway)

In addition to the above, this commit also changes the logic to allow
generating datetime strings even for files with missing EXIF (which
makes sense as a result of the previous commit allowing the use of mtime
instead).
For simplicity, I decided to only implement the attributes that I could
verily easily reach from the existing metadata exported by Thumbnail.
Ideally, I would also like to be able to sort by "last modified" but I'm
not sure of the best way to reach this from this place in the code.

It's worth pointing out that, with the current implementation, the list
will not dynamically re-sort itself until you re-select the sorting
method - even if you make changes to the files that would otherwise
affect the sorting (e.g. changing the rank while sorting by rank). One
might even call this a feature, not a bug, since it prevents thumbnails
from moving around while you're trying to re-label them. You can always
re-select "sort by ..." from the context menu to force a re-sort.

Fixes Beep6581#3317
@Lawrence37
Copy link
Collaborator

Wonderful. I will give this another test run soon. It looks like it should work fine, although the gmtime issue still looks suspicious.

@Lawrence37
Copy link
Collaborator

Tested on Linux and it looks good. The modified times show up in UTC 0, but it's an improvement compared to what we currently have (incorrect date or no date at all). This and the EXIF time zone issues can be tackled later. If someone can confirm these changes work on Windows, I'm in support of merging for 6.0.

@Lawrence37
Copy link
Collaborator

I just tried it in Windows and it looks ok.

@fatso83
Copy link

fatso83 commented Oct 2, 2022

Just bumping this since it seems to have disappeared from view and looks merge-ready (I don't see any negatives not addressed?) and is highly sought after.

@Lawrence37
Copy link
Collaborator

@fatso83 The PR is indeed complete, but the dev branch is basically locked in preparation for the upcoming release. I anticipate this PR (and several others) to be merged shortly after the release.

@fatso83
Copy link

fatso83 commented Oct 3, 2022

@Lawrence37 Appreciate that info. Coming from the (nowadays) more common web release process (CI), one forgets about the normal static software release processes. Might be worth mentioning in the contributing guide?, though on second thought, I am not sure it would avoid drive by comments like mine 🙈.

@Lawrence37 Lawrence37 added this to the v6.0 milestone Oct 4, 2022
@Lawrence37 Lawrence37 modified the milestones: v6.0, v5.10 Dec 11, 2022
@haasn
Copy link
Contributor Author

haasn commented Dec 20, 2022

Ping

@fatso83
Copy link

fatso83 commented Dec 24, 2022

Workflows are usually set up as not to have releases block merging to the dev branch. Normal Git Flow solves this perfectly for versioned software.

  1. Branch release/v1234 off development
  2. Stabilize release/v1234, continuously backmerging fixes to development
  3. Release release/v1234 once deemed stable, tag and delete the branch

All while merging features into development (and/or daggy fixes).

@Thanatomanic
Copy link
Contributor

While this branch seems ready to merge, it will generate quite some conflicts for our exiv2 branch. This would make merging even harder... Ping @Lawrence37 for their opinion. Should we wait to merge this?

@Lawrence37
Copy link
Collaborator

We will have to deal with the merge conflicts eventually. Cherry-picking these commits into the exiv2 branch reveals the conflicts are not too difficult to resolve. I'm ok with merging this PR.

@Thanatomanic Thanatomanic merged commit 2101b84 into Beep6581:dev Jan 2, 2023
@Thanatomanic
Copy link
Contributor

Thanks @haasn for your contribution and @fatso83 for commentary. And both for your patience...

@haasn haasn deleted the sorting branch July 22, 2023 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add sorting to file browser
5 participants