News:

Accounts with zero posts and zero activity during the last months will be deleted periodically to fight SPAM!

Main Menu

BrowseTracker : toolbar button to jump to previously edited location

Started by christo, September 09, 2025, 07:25:48 PM

Previous topic - Next topic

christo

Changes to add a button to jump to previously edited location is available in my github fork : https://github.com/josephch/codeblocks/commit/029005671abfeb6d7c3c07390030605448a09dff

I think it is a good idea to add this feature as it is very helpful for navigation during code editing. Button images are generated via chatgpt and might not be the most aesthetic.

Pecan

I cannot figure out how to save that page so I can copy the code out of it. I tried save as html, save as jpg, save as ptf, etc. and none of them allow me to mark and copy from them

Any one know how to capture the code out of that page?

christo

Hi Pecan, you can download it as a patch by adding .patch after commit hash.

https://github.com/josephch/codeblocks/commit/029005671abfeb6d7c3c07390030605448a09dff.patch

If this is not sufficient, I'll attach a proper patch later after work.

Thanks

Pecan

Quote from: christo on September 11, 2025, 06:11:31 AM
Hi Pecan, you can download it as a patch by adding .patch after commit hash.

https://github.com/josephch/codeblocks/commit/029005671abfeb6d7c3c07390030605448a09dff.patch

If this is not sufficient, I'll attach a proper patch later after work.

Thanks

Thanks. That looks like I can use that for cut and paste. I appreciate it.

christo


Pecan

Quote from: christo on September 11, 2025, 02:01:17 PM
Hi Pecan, attaching modified files w.r.t svn revision 13733

Really nice mod. Thanks, I'll test it for a couple of day, then commit.

Pecan

@Christo

Unfortunately, this patch does not record the "last modified"
location in an editor.
It records the "first modified" in the editor and does not record any further mod locations for that editor until the modifed flag is cleared by a save.

This is because the event it is dependent upon (cbEVT_EDITOR_MODIFIED) is issued only on the first modification of an editor.

For example: Perform a mod in EditorA, then again in EditorB.
Go back to EditorA and make another mod.
If you click on "Jump to last modification" you'll end up in EditorB, not EditorA where the last mod was actually made because CB did not issue a second mod event for EditorA since the mod flag was already set.

I think this can be solved by depending on the editor hook instead of the CB event.

I'll look into it.

christo

Thank you @Pecan

Yes, I can also reproduce that issue. I always save files, that might be the reason I didn't notice it before. Sorry about that.

Pecan

@ christ

I've modified the code to use the scintilla editor hook rather than the CB editor modified event. It's working well.

I removed the RegisterEventSink() to your cbEVT_EDITOR_MODIFIED event and added code to simply emulate the event with a call to OnEditorModifiedEvent() when scintilla indicates a mod has been made(BrowseTracker.cpp:2724 see the line marked // (ph 25/09/17)) . Easy change.


// ----------------------------------------------------------------------------
void BrowseTracker::OnEditorEventHook(cbEditor* pcbEditor, wxScintillaEvent& event)
// ----------------------------------------------------------------------------
{
    // Catch changes to the source and queue editor and line to update browse locations

    // **Debugging**
    //    wxString txt = _T("OnEditorModified(): ");
    //    int flags = event.GetModificationType();
    //    if (flags & wxSCI_MOD_CHANGEMARKER) txt << _T("wxSCI_MOD_CHANGEMARKER, ");
    //    if (flags & wxSCI_MOD_INSERTTEXT) txt   << _T("wxSCI_MOD_INSERTTEXT, ");
    //    if (flags & wxSCI_MOD_DELETETEXT) txt   << _T("wxSCI_MOD_DELETETEXT, ");
    //    if (flags & wxSCI_MOD_CHANGEFOLD) txt   << _T("wxSCI_MOD_CHANGEFOLD, ");
    //    if (flags & wxSCI_PERFORMED_USER) txt   << _T("wxSCI_PERFORMED_USER, ");
    //    if (flags & wxSCI_MOD_BEFOREINSERT) txt << _T("wxSCI_MOD_BEFOREINSERT, ");
    //    if (flags & wxSCI_MOD_BEFOREDELETE) txt << _T("wxSCI_MOD_BEFOREDELETE, ");
    //    if (flags == wxEVT_SCI_MODIFIED)    txt << _T("wxSCI_MODIFIED, ");
    //    if (flags == wxEVT_SCI_UPDATEUI)    txt << _T("wxEVT_SCI_UPDATEUI, ");
    //    txt << _T("EventFlags=")
    //        << wxString::Format(_T("%d"), flags)
    //        << _T(" pos=")
    //        << wxString::Format(_T("%d"), event.GetPosition())
    //        << _T(", line=")
    //        << wxString::Format(_T("%d"), event.GetLine())
    //        << _T(", linesAdded=")
    //        << wxString::Format(_T("%d"), event.GetLinesAdded());
    //    Manager::Get()->GetLogManager()->DebugLog(txt);
    //
    //    if      (event.GetEventType() == wxEVT_SCI_CHARADDED)
    //    {   Manager::Get()->GetLogManager()->DebugLog(_T("-- > OnEditorHook: wxEVT_SCI_CHARADDED")); }
    //    else if (event.GetEventType() == wxEVT_SCI_CHANGE)
    //    {   Manager::Get()->GetLogManager()->DebugLog(_T("-- > OnEditorHook: wxEVT_SCI_CHANGE")); }
    //    else if (event.GetEventType() == wxEVT_SCI_MODIFIED)
    //    {   Manager::Get()->GetLogManager()->DebugLog(_T("-- > OnEditorHook: wxEVT_SCI_MODIFIED")); }
    //    else if (event.GetEventType() == wxEVT_SCI_AUTOCOMP_SELECTION)
    //    {   Manager::Get()->GetLogManager()->DebugLog(_T("-- > OnEditorHook: wxEVT_SCI_AUTOCOMP_SELECTION")); }
    //    else if (event.GetEventType() == wxEVT_SCI_AUTOCOMP_CANCELLED)
    //    {   Manager::Get()->GetLogManager()->DebugLog(_T("-- > OnEditorHook: wxEVT_SCI_AUTOCOMP_CANCELLED")); }

    event.Skip();

    if (not IsBrowseMarksEnabled())
        return;

    cbStyledTextCtrl* control = pcbEditor->GetControl();
    if( m_bProjectIsLoading) return;

    if (event.GetEventType() != wxEVT_SCI_MODIFIED)
        return;

    // Record action in line only once
    if (control->GetCurrentLine() == m_EditorHookCurrentLine)
        return;

    //if ( event.GetEventType() != wxEVT_SCI_MODIFIED )
   // if ( event.GetEventType() == wxEVT_SCI_MODIFIED )
   if (event.GetEventType() == wxEVT_SCI_MODIFIED)
    {
        // Whenever event.GetLinesAdded() != 0, we must re-set BrowseMarks for lines greater
        // than LineFromPosition(event.GetPosition())
        int flags = event.GetModificationType();
        bool changed = false;
        changed |= flags & wxSCI_MOD_INSERTTEXT;
        changed |= flags & wxSCI_MOD_DELETETEXT;
        changed |= flags & wxSCI_PERFORMED_USER;
        changed |= (event.GetEventType() == wxEVT_SCI_CHARADDED);

        int linesAdded = event.GetLinesAdded();
        // **Debugging**
        //    if (linesAdded)
        //        Manager::Get()->GetLogManager()->DebugLog(wxString::Format("EditorHook Lines Added linesAdded:%d", linesAdded));

        if (changed or linesAdded)
        {
            #if defined(LOGGING)
            //LOGIT( _T("BT EditorEventHook isAdd[%d]isDel[%d]lines[%d]"), isAdd, isDel, linesAdded );
            #endif
            // rebuild BrowseMarks from scintilla marks
            m_EditorHookCurrentLine = control->GetCurrentLine();
            //RebuildBrowse_Marks( pcbEditor, isAdd );
            // Function to add an item to the map
            //std::lock_guard<std::mutex> lock(m_EditorHookmapMutex);  // Lock the mutex
            if (m_EditorHookmapMutex.try_lock())
            {
                // Mutex was successfully locked
                m_EditorHookFileLineMap.insert({pcbEditor, control->GetCurrentLine()});
                m_EditorHookmapMutex.unlock();
            } else {
                // Mutex is already locked, handle accordingly
                m_EditorHookCurrentLine = -1; //try again next later.
            }

            // Tell JumpTracker that this editor has been modified // (ph 25/09/17)
            if (m_pJumpTracker.get())
            {
                CodeBlocksEvent evt(cbEVT_EDITOR_MODIFIED);
                evt.SetEditor(pcbEditor);
                m_pJumpTracker->OnEditorModifiedEvent(evt);
            }

        }//endif changed
    }//endif wxEVT_SCI_MODIFIED

    // wxSCI_MOD_CHANGEMARKER is an extremely expensive call. It's called
    // for each line during a file load, and for every change to every
    // margin marker in the known cosmos. So here we allow a "one shot only"
    // to catch the marker changed by a margin context menu.
    // cf: CloneBookMarkFromEditor() and OnMarginContextMenu()
    //if ( event.GetEventType() == wxEVT_SCI_MODIFIED )
    if (event.GetEventType() == wxEVT_SCI_MODIFIED)
    do{
        if ( m_OnEditorEventHookIgnoreMarkerChanges )
            break;
        int flags = event.GetModificationType();
        if (flags & wxSCI_MOD_CHANGEMARKER )
        {
            m_OnEditorEventHookIgnoreMarkerChanges = true;
            int line = event.GetLine();
            #if defined(LOGGING)
            //LOGIT( _T("BT wxSCI_MOD_CHANGEMARKER line[%d]"), line );
            #endif
            CloneBookMarkFromEditor( line );
        }
    }while(false);

}//OnEditorEventHook


Your mod to BrowseTracker is a pleasing addition.
Will commit after using for some days.

Pecan



christo

Hi Pecan, on the latest trunk, jump to previous position does not work if bookmark tracking is disabled. Also some unrelated events can cause last edited state to be changed. Attaching a patch for these two issues. Thanks

Pecan

Quote from: christo on September 29, 2025, 02:03:16 PM
Hi Pecan, on the latest trunk, jump to previous position does not work if bookmark tracking is disabled. Also some unrelated events can cause last edited state to be changed. Attaching a patch for these two issues. Thanks

@Christo
Acknowledge, and will apply and test a few days.

Pecan