File manager context menus

Mark Gaiser markg85 at gmail.com
Sun Aug 17 13:55:51 BST 2014


On Sun, Aug 17, 2014 at 10:19 AM, David Faure <faure at kde.org> wrote:
> folderview seems to be using KonqPopupMenu,
> while dolphin is using its own popup menu implementation.
>
> This is the reason I started to factorize stuff out of KonqPopupMenu many
> years ago, leading to KFileItemListProperties, KFileItemActions,
> kabstractfileitemactionplugin.*, and other stuff now in kio, as well as
> KonqCopyToMenu in libkonq --> so that dolphin and konqueror can share bits of
> the context menu without sharing the toplevel context menu organization.
>
> The big question is: what should folderview do?
> Isn't it a bit weird that it uses the konqueror context menu rather than the
> dolphin context menu, given that most users will only see folderview and
> dolphin, and therefore will get an inconsistent experience? This being said,
> dolphin's context menu isn't in a shared library :)
>
> Konqueror's context menu is, but that's the source of the dependency issue in
> the frameworks world, workspace not being able to depend on apps.
>
> I think I can imagine three solutions out of this:
>
> 1) folderview assembles its own popupmenu implementation out of the individual
> bits offered by KIO (and I keep moving the necessary bits there). Solves the
> dependency issue, but leads to even more inconsistency.
>
> 2) KonqPopupMenu moves to KIO -- but then this begs the question, should
> dolphin use it (I guess so), and should even KFileDialog use it (I guess not).
>
> 3) A popupmenu implementation moves to KIO, made of the best stuff from
> dolphin and konqueror.
>
> Comparing the context menu in dolphin and konqueror, it seems to me that
> * 95% of it is the same, just possibly in a different order
> * Dolphin has a "Add To Places" action (for directories)
> * Konqueror has a "Preview In..." action
> Makes sense - different integration with the rest of the app.
>
> But we could just provide a way for the app to insert its own actions, while
> sharing all the rest of the code.
>
> Dolphin developers, Folderview developers, what do you think?

Just a little brainstorm of a possible implementation that might make
sense for all parties using a context menu.
Introduce a new KIO class for popup contexts and enum. An enum with
the possible context menu items.

The enum:

enum ContextElements
{
    CUT,
    COPY,
    PASTE,
    NEW,
    RENAME,
    MOVE_TO_TRASH,
    DELETE,
    OPEN_WITH,
    SPACER (the spacer would be.. just that, a spacer.)
    .... etc...
};


The class (within the KIO namespace):

class ContextMenu : public QMenu
{
public:
   explicit ContextMenu(ContextElements elements);
   void addAction(ContextElements element, QAction* action);
   void replaceAction(ContextElements find, ContextElements replace);
   void replaceAction(ContextElements find, QAction* action);
}

Then constructing it like:
ContextMenu* menu = new ContextMenu(ContextElements::CUT |
ContextElements::COPY | ContextElements::PASTE |
ContextElements::SPACER | ContextElements::....);

This would construct a context menu with those actions in the order
specified. I'm not quite sure if a bit field is the best approach
here. A QList<ContextElements> or QVector<ContextElements> might be
easier to implement.

The extra addAction (that takes a ContextElements element and a
QAction value) can be used to later on "inject" an action after an
already present ContextElements value.
Example:

QAction someAction = new QAction("Some custom action injected after PASTE");
menu->addAction(ContextElements::PASTE, someAction)

The replaceAction functions would replace any already defined
ContextElements (from the constructor) with either another predefined
ContextElements or with a custom QAction. I've added this because
dolphin replaces the "move to trash" action by "delete" if you press
SHIFT. A capability like that isn't in QMenu but would be neat to
have.

The only thing missing above is some way to set a signal/slot
connection on predefined actions. Perhaps something like:
void QAction* action(ContextElements element); (would be added in the
class, obviously)
connect(menu->action(ContextElements::PASTE), &QAction::triggered, this, ....)

I think the above would allow for all parties to be happy
"KIO::ContextMenu" users. Much of the shared actions can be
implemented in KIO under the ContextElements enum. Custom actions can
be easily implemented in those using this class and easily injected
anywhere in the context menu.

All of the above does imply that you can have all actions defined in
ContextElements, but only one of each type! Multiple
ContextElements::CUT in the same popup for instance should be
impossible. Otherwise functions like action and replaceAction would
not know which QAction object to return/replace.

Just my 5 cents :)




More information about the kfm-devel mailing list