https://bugs.kde.org/show_bug.cgi?id=453800

--- Comment #5 from Raphaël Jakse <raphael....@jakse.fr> ---
So, from reading the source code with naive eyes that haven't seen much Qt/KDE
code.

Recent files are managed with a KRecentFilesAction (subclass of KSelectAction,
itself a subclass of QWidgetAction, itself a subclass of QAction) object stored
in the m_fileOpenRecent member of KateMainWindow. This object is initialized
using inline/template function KStandardAction::openRecent. 

    m_fileOpenRecent = KStandardAction::openRecent(m_viewManager,
SLOT(openUrl(QUrl)), this);

I've noticed that KateMainWindow has a slotOpenDocument slot, that isn't used
anywhere. This one calls m_viewManager->openUrl(url, QString(), true);. It
seems like it should be used in the previous line instead of calling directly
KateViewManager::openUrl like this:

    m_fileOpenRecent = KStandardAction::openRecent(this,
&KateMainWindow::slotOpenDocument, this);

Anyway, I tried and it does not fix the issue. Slot openUrl of KateViewManager
(m_viewManager) is supposed to be called when KRecentFilesAction's urlSelected
signal is emitted. This happens in KRecentFilesActionPrivate::urlSelected, a
function called when signal KSelectAction::triggered is  emitted.

It lead me to explore KRecentFileAction's code, and in particular its addUrl
where the problem seem to happen.

More specifically:

    using Info = KRecentFilesActionPrivate::RecentActionInfo;
    // Reverse iterators because the most recent actions are at the end of
m_recentActions
    auto it = std::find_if(d->m_recentActions.rbegin(),
d->m_recentActions.rend(), [&url](const Info &info) {
        return info.url == url;
    });

    if (it != d->m_recentActions.rend()) { // url already has an action in the
menu
        // Remove the action...
        QAction *act = removeAction(it->action);
        // ... move the relevant object to the end of m_recentActions
        std::rotate(d->m_recentActions.rbegin(), it, it + 1);
        // ... prepend the action to the menu
        menu()->insertAction(menu()->actions().value(0), act);
        return; // All done
    }

If the URL is already in the menu, it moves it around by removing the
associated action, and reinserting the action. But reinserting the action does
not seem to work (anymore?). At this point, I suspect a bug in Qt, or a method
should be called to make the action work again. But I repeat, I didn't know
QAction before yesterday.

This version of the code works:

    auto it = d->findByUrl(url);

    if (it != d->m_recentActions.cend()) {
        // Remove the action...
        delete removeAction(it->action);
        d->m_recentActions.erase(it);
        addUrl(url, name);
        return; // All done
    }

It recreates the action from scratch. I'd also suggest defining a removeAction
method that takes the iterator and calls erase automatically because this is
what is done everywhere in this file. I'll submit a patch.

There's still a bug somewhere, so someone more experimented than me may want to
investigate why reusing the action does not work.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to