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

--- Comment #10 from RJVB <rjvber...@gmail.com> ---
Created attachment 121610
  --> https://bugs.kde.org/attachment.cgi?id=121610&action=edit
folded and non-unfoldable code at startup!

I stumbled onto a much more annoying glitch that I already thought to have
seen: see the screenshot.

This is a document in a KDevelop session I just started, one of those that are
opened on startup.

There is actually code being folded at the indicated location, except that this
location is not at all a proper place for a foldable block to start. The folded
block contains the end of the current class definition, and most of the
following class definition (see below). In other words: `addedContextMenu` is
part of the 1st class definition, `endoding` is a member of the other class.

What's really annoying here is that I cannot unfold it by clicking on the
folding carat. Fortunately "View/Code Folding/Unfold Toplevel Nodes" had the
desired effect.

There is no support for restoring folded sections after closing/reopening a
document that I can see, but apparently these sections are preserved across
restarts the editor, right? If so this could be an effect of changing the
document behind the editor's back.

That is not what can have happened here, but I do notice that folding is
preserved when the document is reloaded (automatically or manually) after an
external change. Evidently that gives weird results, so it'd be good if you
could opt not to preserve folding.

The hidden code (obtained by selecting lines labelled 126-284 in the
screenshot:

```
    // can share the same context menu instance.
    QMenu* addedContextMenu;
    QPointer<QMenu> lastShownMenu;
};

class TextDocumentPrivate
{
public:
    explicit TextDocumentPrivate(TextDocument *textDocument, ICore* core)
        : q(textDocument)
    {
        if (!contextMenuData) {
            contextMenuData = new
TextDocumentContextMenuData(core->uiController()->activeMainWindow());
        }
    }

    ~TextDocumentPrivate()
    {
        saveSessionConfig();
        delete document;
    }

    void setStatus(KTextEditor::Document* document, bool dirty)
    {
        QIcon statusIcon;

        if (document->isModified())
            if (dirty) {
                state = IDocument::DirtyAndModified;
                statusIcon = QIcon::fromTheme(QStringLiteral("edit-delete"));
            } else {
                state = IDocument::Modified;
                statusIcon = QIcon::fromTheme(QStringLiteral("document-save"));
            }
        else
            if (dirty) {
                state = IDocument::Dirty;
                statusIcon =
QIcon::fromTheme(QStringLiteral("document-revert"));
            } else {
                state = IDocument::Clean;
            }

        q->notifyStateChanged();
        Core::self()->uiControllerInternal()->setStatusIcon(q, statusIcon);
    }

    inline KConfigGroup katePartSettingsGroup() const
    {
        return KSharedConfig::openConfig()->group("KatePart Settings");
    }

    inline QString docConfigGroupName() const
    {
        return document->url().toDisplayString(QUrl::PreferLocalFile);
    }

    inline KConfigGroup docConfigGroup() const
    {
        return katePartSettingsGroup().group(docConfigGroupName());
    }

    void saveSessionConfig()
    {
        if(document && document->url().isValid()) {
            // make sure only MAX_DOC_SETTINGS entries are stored
            KConfigGroup katePartSettings = katePartSettingsGroup();
            // ordered list of documents
            QStringList documents = katePartSettings.readEntry("documents",
QStringList());
            // ensure this document is "new", i.e. at the end of the list
            documents.removeOne(docConfigGroupName());
            documents.append(docConfigGroupName());
            // remove "old" documents + their group
            while(documents.size() >= MAX_DOC_SETTINGS) {
                katePartSettings.group(documents.takeFirst()).deleteGroup();
            }
            // update order
            katePartSettings.writeEntry("documents", documents);

            // actually save session config
            KConfigGroup group = docConfigGroup();
            document->writeSessionConfig(group);
        }
    }

    void loadSessionConfig()
    {
        if (!document ||
!katePartSettingsGroup().hasGroup(docConfigGroupName())) {
            return;
        }

        document->readSessionConfig(docConfigGroup(),
{QStringLiteral("SkipUrl")});
    }

    // Determines whether the current contents of this document in the editor
    // could be retrieved from the VCS if they were dismissed.
    void queryCanRecreateFromVcs(KTextEditor::Document* document) const {
        IProject* project = nullptr;
        // Find projects by checking which one contains the file's parent
directory,
        // to avoid issues with the cmake manager temporarily removing files
from a project
        // during reloading.
        KDevelop::Path path(document->url());
        foreach ( KDevelop::IProject* current,
Core::self()->projectController()->projects() ) {
            if ( current->path().isParentOf(path) ) {
                project = current;
                break;
            }
        }
        if (!project) {
            return;
        }
        IContentAwareVersionControl* iface;
        iface = qobject_cast< KDevelop::IContentAwareVersionControl*
>(project->versionControlPlugin());
        if (!iface) {
            return;
        }
        if ( !qobject_cast<KTextEditor::ModificationInterface*>( document ) ) {
            return;
        }

        CheckInRepositoryJob* req = iface->isInRepository( document );
        if ( !req ) {
            return;
        }
        QObject::connect(req, &CheckInRepositoryJob::finished,
                            q, &TextDocument::repositoryCheckFinished);
        // Abort the request when the user edits the document
        QObject::connect(q->textDocument(),
&KTextEditor::Document::textChanged,
                            req, &CheckInRepositoryJob::abort);
    }

    void modifiedOnDisk(KTextEditor::Document *document, bool /*isModified*/,
        KTextEditor::ModificationInterface::ModifiedOnDiskReason reason)
    {
        bool dirty = false;
        switch (reason)
        {
            case KTextEditor::ModificationInterface::OnDiskUnmodified:
                break;
            case KTextEditor::ModificationInterface::OnDiskModified:
            case KTextEditor::ModificationInterface::OnDiskCreated:
            case KTextEditor::ModificationInterface::OnDiskDeleted:
                dirty = true;
                break;
        }

        // In some cases, the VCS (e.g. git) can know whether the old contents
are "valuable", i.e.
        // not retrieveable from the VCS. If that is not the case, then the
document can safely be
        // reloaded without displaying a dialog asking the user.
        if ( dirty ) {
            queryCanRecreateFromVcs(document);
        }
        setStatus(document, dirty);
    }

    TextDocument * const q;

    QPointer<KTextEditor::Document> document;
    IDocument::DocumentState state = IDocument::Clean;
    QString encoding;
```

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

Reply via email to