-
Notifications
You must be signed in to change notification settings - Fork 548
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
Overhaul of models, views, data management #3497
Conversation
- Move ModelRefreshed signal to outer class (now a QObject subclass) - Move mimeData() to proxy model, where it needs to be for views - (This allowed dropping the inner Files and Transitions model classes entirely, replaced with a stock `QStandardItemModel`. All of the special logic is in the custom proxy model class. - Add a persistent QItemSelectionModel to all three models, shared by both views. Selection is no longer lost when switching view. - Track the currently visible view for 'foo' (either fooListView or fooTreeView) in main_window, access as `get_app().window.fooView`
- Selection is now managed completely in the Files model (outer class), directly from the persistent QItemSelectionModel. - Helper functions in both files_model and main_window ease transition - updateSelection() is also gone, as there's no selection cache. Selection data always comes live from the selection model. - Also greatly simplify drag-and-drop code, using proxy & selection models
Major overhaul to the code for adding items to the file model. - `add_file()` is gone from both views - files_model's new `add_files()` (<= note the plural) takes a list of paths, instead of churning over them one at a time - Image sequence management is also consolidated into files_model - Two helper methods in main_window handle communication with the user (in the form of popup questions / message boxes) for `add_files()` Also, QPersistentModelIndex()es are stored in the custom model outer classes' in-memory hashes, and can be used to locate a given item's row for later modification (or deletion, specifically). No more having to iterate over all the items to find one! (This is done for Transitions as well, though it's currently not used there.)
(I just wanted to reiterate that in big, flashing letters on the side of a mountain, so to speak.) This is a big set of changes, and I'm not going to pretend that I think every line is bug-free, nor will I lie and say that I've personally tested every possible scenario myself before submitting. I haven't. Not even remotely. That's why I opened this PR, to get other eyes on the code / other testing experiences, so hopefully the remaining bugs can be shaken out.) |
@ferdnyc Wow! Nice work on this! I'll grab this branch and do some testing today for sure! I'll let you know what I find shortly. |
If there's one thing that makes me the most nervous, it's the multiple inheritance in But it was necessary to transfer the Swapping those inner model classes over to just the stock I still want to make another pass through the table structure for the base models, in fact, and experiment with defining some User Roles so that more data can be moved from hidden columns over to the first ("main") cell in the row — like I did with the Emoji model. Unless we're either: (1) displaying, or (2) sorting by, a piece of data, there's no reason for it to have a separate column of its own — the lookups get far simpler if it's all stored in the same table cell (under different Roles). Then it can all be accessed using the same |
...And it seems to work just fine, is the real point. I said it makes me nervous, not that it causes any actual problems. Even though I kept half-expecting to hit some. But despite my misgivings, it all seems to work out as it should. (Though, that new Qt aspect to the outer |
@ferdnyc don't forget that proxy models can be sorted by name, date etc. Indexes wouldn't be preserved. Proxy needed only for sorting, nothing else. Unsorted is also an option. |
@ferdnyc Testing Feedback (so far):
However, the Files Details view still works when dragging on non-icon columns. |
|
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.
Accidentally started a review... ughh 😆
if not cur or not cur.isValid() and self.selection_model.hasSelection(): | ||
cur = self.selection_model.selectedIndexes()[0] | ||
|
||
if cur and cur.isValid(): |
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.
@ferdnyc What if this doesn't find a valid ID, and thus does not return a value?
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.
Up to the callers. if it's being called in an assignment context, (f = self.current_file_id()
), then f
will be None
. I generally test it with an if not f:
after.
If it's being passed to some other function (do_something_with(self.current_file_id())
, then that function needs to be able to deal with a possible None
argument.
|
||
def current_file(self): | ||
""" Get the File object for the current files-view item, or the first selection """ | ||
cur_id = self.current_file_id() |
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.
Same question, what if this doesn't get a value returned? And what if current_file() doesn't return a File object?
disadvantages:
All 3 published solutions that modifies files model: #3497, #3366, #3264 has bottle-neck in thumbnails creation. This is most resource demanding task. Only one solution uses asynchronous update of generated thumbnails (total time required to draw all new icons is the same). Other two waits for thumbnails during model creation. To fix p.2:
to
|
Well, exactly. That's why everything has to be looked up on the fly, by pulling up the But it would be even easier if, when we got the (The reason I store a |
Agreed, and while it's much faster now (and loading 766 PNG files isn't something a sane person should be doing anyway), you are left wondering what's happening. Some sort of progress would be good — even if it's just that the Project Files list keeps itself scrolled down to the last item added, so you can watch it populating.
Good catch, I missed/forgot that properties was creating its own files model. It needs to not. IIRC both the Title Editor and the Animated Title Editor have their own
I noticed that one too, however with the new persistent model indexing it should be trivially fixable. It just needs to request deletion of the new entry on drag abort. |
I also feel like "Add to Timeline" (which right now constructs its own model out of the selected files) should be able to work directly off the |
Oh! No, that's my fault. I know how to fix it, but it ultimately comes down to an issue with our action triggers: All of the functions are specced wrong. Every single one. They all have the form I'll fix the title editor, and fix all of our triggered functions to |
... Maybe AFTER the emoji branch is merged. If I do it here, it'll make it even harder to merge with |
The two commits I just pushed should fix both Edit Title, and dragging from non-icon columns for all views. (Had that one half-fixed in my source tree, turns out; just forgot to commit it! And I decided to change all of the view files to use the same code; cleaner — even if it is still copy-pastey.) |
I was correct in thinking that both title editors had their own |
- properties_tabelview will pull data directly from files_model and transition_model on the get_app().window object. - A connection to both models' ModelRefreshed signals that forces a menu data reset replaces the previous update_model() calls
- When passed, OpenShot will attempt to load QAbstractItemModelTester into the files, emoji, effects, and transition models (base and all proxy models). This requires Qt 5.11 or higher. - By default, if the environment variable `QT_LOGGING_RULES` is not set, it will be set to "qt.modeltest.debug=true", which causes quite a lot of console spew. It can be set to something less verbose before launching OpenShot, e.g. "qt.modeltest.warning=true".
Properties table migratedI just finished getting the Properties table off of its own QAbstractItemModelTesterThe other commit I just pushed is a new By default, if the environment variable |
- Switch from TitleFileName-N for numbered filenames, to Windows-esque "TitleFileName (N)", because the previous value would trigger the image sequence import logic
Ohh-kay. I now have both title editors using Along the way, I changed the naming pattern for title SVG files from "TitleFileName-N.svg" (where N is a counter) to the very Windows-ey "TitleFileName (N).svg". This is for extremely pragmatic reasons: With the previous naming, once you had more than one title And I incorporated some of my changes from #3357 (but most of it is still on hold) |
@jonoomph At this point I believe I've got things here working well enough that I'd suggest we merge this to at least the There are still a few more things I should do, and even more things I'd like to do, but they're relatively small and can just as easily be done directly on that branch. The |
@ferdnyc I've been merging |
As invited by @jonoomph (careful what you wish for), this PR against the in-progress
emojis
branch builds on the model/view changes there, extending some nice performance improvements into a fairly extensive overhaul of the entire way data is managed for project asset lists.TODO for merge
add_file()
implementations fromtitle_editor.py
,animated_title.py
, that won't work anymoreThere are probably some bugs, still, but I've finally got it to a point where it doesn't keel over as soon as I start testing it, so I wanted to get it out there in the world. The major benefits are:
Speed
I just imported a set of (what I subsequently discovered was) 776 image files, mostly PNGs, into a new project as Project Media. It wasn't instantaneous, but it took... maybe a minute? A bit more? The way the OpenShot code through 2.5.1 implemented that sort of thing, it would've quickly ground to a halt and taken possibly an hour or more, with each individual file causing a several-minutes-long rebuild of the full model on each addition. With the new code, not only did the import run at ~ 10 files/second right through to the end, but I was able to delete a random 7 of them instantaneously.
Reduced
datacode duplicationadd_file()
andget_image_sequence_data()
or whatever have moved out of the two view classes and into thefiles_model
. Not only does that elmiinate duplication, but it allows for some strreamlining — for example, the method is now calledadd_files()
, and it takes an entire list of files (like from a File Open dialog) instead of having to be spun over them one-by-oneImproved user experience
My focus was also on eliminating some long-standing pain points for the users
Selection is now preserved in all lists,
alwaysalmost alwaysThere's a persistent
QItemSelectionModel
that's created with each MODEL class, and applied to both of the views (shared between them) when they're set up. You can switch modes and etc., you still won't lose your selected items.(I notice that selections are lost if the selected items are filtered out of the list, then restored to visibility again. So, that's a bug that I'd like to fix, if possible.)
Image Sequence import is less brain-dead
One of the advantages to
add_files()
is that it can be smarter about groups of files, when discovering for image sequences. Now, when you import a group of images that could be a sequence:There's a bunch more stuff, too — see the commit messages, and beyond that, the code.
I'm hopeful that, among many others, this...
fixes #3372, fixes #2557, fixes #2341, fixes #2031, fixes #1288