Implement support for categories on KfilesPlacesView
ClosedPublic

Authored by renatoo on Oct 11 2017, 12:48 PM.

Details

Summary

Organize PlacesViews in groups and show section headers similar as
dolphin.

Test Plan

From an kde app try to open/save a file.
It should show a new file dialog with categories on the places planel

Diff Detail

Repository
R241 KIO
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
There are a very large number of changes, so older changes are hidden. Show Older Changes
This revision now requires changes to proceed.Oct 12 2017, 3:04 PM
renatoo updated this revision to Diff 20650.Oct 12 2017, 3:31 PM
renatoo marked an inline comment as done.

Optimize sectionsCount to not use a QSet
Use static_cast when possible

renatoo marked an inline comment as done.Oct 12 2017, 3:32 PM
anthonyfieroni added inline comments.Oct 12 2017, 6:15 PM
src/filewidgets/kfileplacesview.cpp
421

So you mean sizeHint have a right height ? This height store looks like a workaround.

renatoo added inline comments.Oct 12 2017, 6:30 PM
src/filewidgets/kfileplacesview.cpp
421

I need a way query the header size height from "pointIsHeaderArea" to know if the user clicked on header or in the real item. Since I do not have access from "QStyleOptionViewItem" from there, I need to store it in a var to use it late if necessary.

I do not love the way that is implemented but, I can not find a better way to implement that.

renatoo updated this revision to Diff 20656.Oct 12 2017, 6:50 PM

Use QApplication::font() to determine the section header font size

renatoo marked 2 inline comments as done.Oct 12 2017, 6:52 PM
renatoo added inline comments.
src/filewidgets/kfileplacesview.cpp
421

Ok instead of use QStyleOptionViewItem information to check the font size of the header. Now I use QApplication::font, this give me flexibility to check the header size at any part of the code.

anthonyfieroni added inline comments.Oct 12 2017, 7:17 PM
src/filewidgets/kfileplacesview.cpp
168

Why you are sure that m_dragModeCount is 0 when indexIsSectionHeader? Why not when index.row() == 0 we can paint section header?

1149–1152

This calculation makes no sense to me. We have ((x - (y/2) * rowCount) / rowCount so rowCount can be removed no?

anthonyfieroni added inline comments.Oct 12 2017, 7:19 PM
src/filewidgets/kfileplacesview.cpp
1149–1152

Now i see i'm in wrong :)

renatoo marked an inline comment as done.Oct 12 2017, 7:27 PM
renatoo added inline comments.
src/filewidgets/kfileplacesview.cpp
168

m_dragModeCount is used as workaround to draw items on floating window during the drag.

When drag starts it save the number of selected items and until we draw all selected items once we do not draw the section header (we do not want this to appear on the dragging item), because this paint event will be used to represent the floating item.

Based on: https://github.com/KDE/zanshin/commit/ce6a5120

anthonyfieroni added inline comments.Oct 12 2017, 7:46 PM
src/filewidgets/kfileplacesview.cpp
168

Ok i understaind the workaround, but did you know what is the value of opt.index.row() ?

renatoo added inline comments.Oct 12 2017, 8:01 PM
src/filewidgets/kfileplacesview.cpp
168

Humm I did not know about this opt.index property. Did some debug here and it is always -1 .

Sorry but I am not sure why should I care about opt.index? Checking the "index" arg is not enough?

I am checking it with "indexIsSectionHeader" which checks if we should draw the section header or not. (it will return "true" for index 0)

anthonyfieroni added inline comments.Oct 13 2017, 7:52 AM
src/filewidgets/kfileplacesview.cpp
168

I think in to move away from workarounds. Cause we want to draw header only ones i you ask to check a QStyleOptionViewItem index if you can use it insetad of dragcount.

ervin requested changes to this revision.Oct 13 2017, 8:39 AM

You probably missed my comment on the previous iteration:
"Note that the summary part of the commit is now wrong (it still refers to KCategorizedView).
Also, KFilePlacesModelTest needs to be adjusted to take into account the new behavior."

Please address those too.

This revision now requires changes to proceed.Oct 13 2017, 8:39 AM
ervin added a comment.Oct 13 2017, 8:58 AM

A couple more changes needed.

src/filewidgets/kfileplacesitem.cpp
152–153

Nitpicking a bit (and sorry for not realizing it earlier) but I think I'd try to keep the structure of the method before that patch and so go for:

if (role == KFilePlacesModel::GroupRole)
...
else if (role != KFilePlacesModel::HiddenRole ...)
...
else

Probably returnData can go away though and just return from the branches of the if instead.

src/filewidgets/kfileplacesview.cpp
122

OK, for that one you can probably get away with a bool instead (let's call it m_dragStarted maybe?). The counter was for a more generic case of more than one item being draggable at the same time, but that won't be the case here since it's a single selection list.

168

@anthonyfieroni Well, at paint time you need to determine if a drag is ongoing or not. There's no way the index can tell you that.

renatoo updated this revision to Diff 20674.Oct 13 2017, 11:28 AM
renatoo marked 8 inline comments as done.
renatoo edited the summary of this revision. (Show Details)

updated comit summary
renamed m_dragModeCount to m_dragStart
refactory 'KFilePlacesItem::data' function

renatoo updated this revision to Diff 20675.Oct 13 2017, 1:05 PM

Updated unit test

Screenshots, my man! Screenshots! Add them to the Summary section so people can see what they're getting if this gets merged. :)

renatoo edited the summary of this revision. (Show Details)Oct 17 2017, 9:03 PM

FWIW, I don't have a lot to offer on the code itself, but I strongly support the change itself. It's always bothered me that Open/Save dialogs were lacking these very useful sections

ngraham added a reviewer: VDG.Oct 17 2017, 9:07 PM
dfaure requested changes to this revision.Oct 18 2017, 5:54 AM
dfaure added inline comments.
autotests/kfileplacesmodeltest.cpp
323

too -> to

src/filewidgets/kfileplacesitem.cpp
127

Q_UNREACHABLE() exists for this purpose

src/filewidgets/kfileplacesview.cpp
122

move this bool next to the other one (m_showHoverIndication), to save on padding.

124

Please move all these methods before the member variables.

This file was doing it correctly, with member vars at the end of the class, I'd like this to be kept.
Otherwise it becomes hard to see all member vars, when they are in the middle of methods.

167

The grammar is a bit strange.
I'd say

"When drawing"

or

"If we are drawing"

and later on "do not draw".

177

this if() doesn't seem very useful to me.

353

boddy -> body

460

Use QApplication::fontMetrics() instead, it'll be much faster.

737–738

what if we click into an empty space? then it's neither header nor item, right?

If I'm right then the naming here is confusing, at least, and should be

const bool clickOverHeader = delegate->pointIsHeaderArea(event->pos());
if (!clickOverHeader && ....)
1259

Move rowCount to local variable. This is a non-inline virtual method, no way the compiler can know that it's constant.

1261

const

This revision now requires changes to proceed.Oct 18 2017, 5:54 AM
renatoo updated this revision to Diff 20939.Oct 18 2017, 11:44 AM
renatoo marked 11 inline comments as done.
renatoo edited the summary of this revision. (Show Details)

Fixed typo and code style

+1, looks good to me, implementation wise. I'll let someone else decide on the actual feature (e.g. retesting for bugs, like Kévin did).

I suspect that the use of QApplication::font/fontMetrics breaks when setting a font on that widget, but well, who would do that ;-)

renatoo updated this revision to Diff 20951.Oct 18 2017, 3:42 PM

Fixed places item size calculation

@renatoo, can you update any remaining Not Done inline comments that are done now (including the discussion ones)?

renatoo marked 2 inline comments as done.Oct 19 2017, 7:21 PM
markg added a subscriber: markg.Oct 20 2017, 11:40 AM

We have such a nice modular design with panels yet we keep cramming everything in the places panel... Why?
It's not just here, I've seen patches like this for Dolphin as well.

Imho, the places panel should only contain the top places - favorites if you will - that you might want to access quickly. Nothing else and should stay small.
Baloo -> new panel
Devices -> new panel
Remote devices -> Either in Devices or a new panel as well
etc..

Having more panels will give a whole different issues. Scrolling. Since each panel would be relatively small if you add many you will get scrollbars within the panels. Well, lets just get rid of the per panel scrollbar and merely have one for the whole "panel container" (like in macOS finder).

Just my 5 cents...

renatoo added a comment.EditedOct 20 2017, 12:31 PM
In D8243#157336, @markg wrote:

We have such a nice modular design with panels yet we keep cramming everything in the places panel... Why?
It's not just here, I've seen patches like this for Dolphin as well.

Imho, the places panel should only contain the top places - favorites if you will - that you might want to access quickly. Nothing else and should stay small.
Baloo -> new panel
Devices -> new panel
Remote devices -> Either in Devices or a new panel as well
etc..

Having more panels will give a whole different issues. Scrolling. Since each panel would be relatively small if you add many you will get scrollbars within the panels. Well, lets just get rid of the per panel scrollbar and merely have one for the whole "panel container" (like in macOS finder).

Just my 5 cents...

@markg, I never used macOs finder, but looking at the internet images. This is exactly what I am proposing and what we have on dolphin today. A single list with only one scrollbar split in sections.
I am just trying to keep the same visuals on both (dolphin and file dialog) to avoid confusion for users, they can get lost if you show different information.

Our final idea is that you will be able to hide sections that you do not want, For example the local devices and network.

In D8243#157336, @markg wrote:

We have such a nice modular design with panels yet we keep cramming everything in the places panel... Why?
It's not just here, I've seen patches like this for Dolphin as well.

Imho, the places panel should only contain the top places - favorites if you will - that you might want to access quickly. Nothing else and should stay small.
Baloo -> new panel
Devices -> new panel
Remote devices -> Either in Devices or a new panel as well
etc..

Having more panels will give a whole different issues. Scrolling. Since each panel would be relatively small if you add many you will get scrollbars within the panels. Well, lets just get rid of the per panel scrollbar and merely have one for the whole "panel container" (like in macOS finder).

Just my 5 cents...

@markg, I never used macOs finder, but looking at the internet images. This is exactly what I am proposing and what we have on dolphin today. A single list with only one scrollbar split in sections.

I am just trying to keep the same visuals on both (dolphin and file dialog) to avoid confusion for users,  they can get lost if you show different information.

Our final idea is that you will be able to hide sections that you do not want, For example the local devices and network.

You "intend" to, yes :)
But with your changes you get the situation where you have multiple scrollbars if you have multiple panels enabled, one scrollbar in each panel.
In Finder, you have 1 scrollbar for the whole panel area.

I like the goal! I want to get there as well! But it would be my preference to get there with individual panels. That would also make the code much simpler.
Anyhow, that's just a "i would like..." opinion. It's not a critic to slow you down or stop this patch.

@markg

Ultimately I think everyone is in agreement in wanting the "single scrollbar" approach for items in whatever you call the default list on Dolphin's left side. Splitting everything into distinct panels and embedding all the panels in a single scrollview is one way to get there. Putting all the features people want in the Places panel is another way. I don't have super strong feelings on the approach taken, because I think either one will get where we want to go, but I do see a lot more activity and excitement in the "add things to the Places panel" approach. Since you prefer the "make everything its own panel" approach, maybe you can submit a patch so we can judge the different approaches somewhere separate and we don't have to have the same discussion every time someone proposes adding something to the places panel. :)

@renatoo, there are still a few Not Done comments. Any chance you can resolve them so we can push this forward?

renatoo marked 3 inline comments as done.Oct 23 2017, 11:24 AM

@dfaure and @ervin, is this acceptable now?

dfaure added inline comments.Oct 24 2017, 8:00 AM
src/filewidgets/kfileplacesview.cpp
1150

typo (total)

1151

different typo (total) ;-)

renatoo updated this revision to Diff 21226.Oct 24 2017, 11:11 AM

Fixed typo

renatoo marked 2 inline comments as done.Oct 24 2017, 11:12 AM

Guys, is that ready? Do you need any other change/fix?

ervin added a comment.Oct 30 2017, 2:51 PM

Looks fine code wise now, just a couple more tweaks to make those sections look closer to what Dolphin got.

src/filewidgets/kfileplacesmodel.cpp
476

Either reorder the enum or change for a different (more explicit not relying on enum storage) comparison operator to have the "right" order. By right order I assume the goal was to align with Dolphin which does: Places / Recently Saved / Search For / Devices.

Currently we have a different order: Places / Search For / Recently Saved / Devices.

src/filewidgets/kfileplacesview.cpp
460

With again the goal to get closer to Dolphin's rendering, its section headers are higher. The text size you use is correct during drawing but they happen to have much more white space before and a bit more after giving it some more breath.

renatoo added inline comments.Oct 30 2017, 3:05 PM
src/filewidgets/kfileplacesmodel.cpp
476

Are you fine If I set values for enums? Something like:

enum GroupType
{
    PlacesType = 100,
    RecentlySavedType = 200,
    SearchForType = 300,
    DevicesType = 400,
    RemovableDeviceType = 500,
    NetworkType = 600
};
renatoo updated this revision to Diff 21582.Oct 30 2017, 6:33 PM

Updated visuals to match dolphin

renatoo marked 3 inline comments as done.Oct 30 2017, 6:34 PM
renatoo added inline comments.
src/filewidgets/kfileplacesmodel.cpp
476

Fixed enum order and set values for it.

ervin accepted this revision.Oct 31 2017, 9:00 AM

Great work BTW, this looks really nice now.

dfaure accepted this revision.Oct 31 2017, 11:50 AM
This revision is now accepted and ready to land.Oct 31 2017, 11:50 AM
ngraham accepted this revision.Oct 31 2017, 1:00 PM
Closed by commit R241:7a6eff3fce41: Implement support for categories on KfilesPlacesView (authored by Renato Araujo Oliveira Filho <renato.araujo@kdab.com>, committed by ngraham). · Explain WhyOct 31 2017, 1:05 PM
This revision was automatically updated to reflect the committed changes.

Can we expose the group type enum in the model in addition to the name, so I can do some filtering in e.g. task manager?

Can we expose the group type enum in the model in addition to the name, so I can do some filtering in e.g. task manager?

This will be exposed by this mr: https://phabricator.kde.org/D8367#change-GqgZlwb2MzB8