Esempio n. 1
0
void EnvVars::OnProjectClosed(CodeBlocksEvent& event)
{
#if TRACE_ENVVARS
  Manager::Get()->GetLogManager()->DebugLog(F(_T("OnProjectClosed")));
#endif

  wxString prj_envvar_set = wxEmptyString;

  if (IsAttached())
  {
    prj_envvar_set = m_ProjectSets[event.GetProject()];

    // If there is an envvar set connected to this project...
    if (!prj_envvar_set.IsEmpty())
      // ...make sure it's being discarded
      nsEnvVars::EnvvarSetDiscard(prj_envvar_set);

    m_ProjectSets.erase(event.GetProject());
  }

  // Apply default envvar set (but only, if not already active)
  nsEnvVars::EnvvarSetApply(wxEmptyString,
                            prj_envvar_set.IsEmpty() ? false : true);

  event.Skip(); // Propagate the event to other listeners
}// OnProjectClosed
void IncrementalSearch::OnEditorEvent(CodeBlocksEvent& event)
{
    if (!m_pToolbar) // skip if toolBar is not (yet) build
    {
        event.Skip();
        return;
    }
    m_pEditor = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
    m_pTextCtrl->Enable(m_pEditor && m_pEditor->GetControl());
    wxMenuBar* mbar = Manager::Get()->GetAppFrame()->GetMenuBar();
    mbar->Enable(idIncSearchFocus, m_pTextCtrl->IsEnabled());

    m_pToolbar->EnableTool(XRCID("idIncSearchClear"), !m_SearchText.empty());

    if (m_pTextCtrl->IsEnabled())
    {
        m_SearchText=m_pTextCtrl->GetValue();
        m_pToolbar->EnableTool(XRCID("idIncSearchPrev"), !m_SearchText.empty() && ((m_flags & wxSCI_FIND_REGEXP) == 0));
        m_pToolbar->EnableTool(XRCID("idIncSearchNext"), !m_SearchText.empty());
        m_NewPos=m_pEditor->GetControl()->GetCurrentPos();
        m_OldPos=m_NewPos;
    }
    else
    {
        m_pToolbar->EnableTool(XRCID("idIncSearchPrev"), false);
        m_pToolbar->EnableTool(XRCID("idIncSearchNext"), false);
    }
    m_pToolbar->Refresh();
    event.Skip();
}
Esempio n. 3
0
void ClangPlugin::OnEditorSave(CodeBlocksEvent& event)
{
    event.Skip();
#ifdef CLANGPLUGIN_TRACE_FUNCTIONS
    fprintf(stdout,"%s\n", __PRETTY_FUNCTION__);
#endif
    EditorManager* edMgr = Manager::Get()->GetEditorManager();
    cbEditor* ed = edMgr->GetBuiltinEditor(event.GetEditor());
    if (!ed)
    {
        return;
    }
    if ( m_TranslUnitId == -1 )
        return;
    std::map<wxString, wxString> unsavedFiles;
    // Our saved file is not yet known to all translation units since it's no longer in the unsaved files. We update them here
    unsavedFiles.insert(std::make_pair(ed->GetFilename(), ed->GetControl()->GetText()));
    for (int i = 0; i < edMgr->GetEditorsCount(); ++i)
    {
        cbEditor* editor = edMgr->GetBuiltinEditor(i);
        if (editor && editor->GetModified())
            unsavedFiles.insert(std::make_pair(editor->GetFilename(), editor->GetControl()->GetText()));
    }
    ClangProxy::ReparseJob job( cbEVT_CLANG_ASYNCTASK_FINISHED, idClangReparse, m_TranslUnitId, m_CompileCommand, ed->GetFilename(), unsavedFiles, true);
    m_Proxy.AppendPendingJob(job);
}
Esempio n. 4
0
// Code::Blocks events
void ClangDiagnostics::OnEditorActivate(CodeBlocksEvent& event)
{
    event.Skip();
    if (!IsAttached())
        return;

    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(event.GetEditor());
    if (ed)
    {
        wxString fn = ed->GetFilename();

        ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("ClangLib"));
        m_bShowInline  = cfg->ReadBool(wxT("/diagnostics_show_inline"),   true);
        m_bShowWarning = cfg->ReadBool(wxT("/diagnostics_show_warnings"), true);
        m_bShowError   = cfg->ReadBool(wxT("/diagnostics_show_errors"),   true);

        m_TranslUnitId = m_pClangPlugin->GetTranslationUnitId(fn);
        cbStyledTextCtrl* stc = ed->GetControl();
        stc->StyleSetBackground(51, Manager::Get()->GetColourManager()->GetColour(wxT("diagnostics_popup_warnbg")));
        stc->StyleSetForeground(51, Manager::Get()->GetColourManager()->GetColour(wxT("diagnostics_popup_warntext")));
        stc->StyleSetBackground(52, Manager::Get()->GetColourManager()->GetColour(wxT("diagnostics_popup_errbg")));
        stc->StyleSetForeground(52, Manager::Get()->GetColourManager()->GetColour(wxT("diagnostics_popup_errtext")));
    }
    m_Diagnostics.clear();
}
Esempio n. 5
0
void ClangPlugin::OnEditorClose(CodeBlocksEvent& event)
{
    event.Skip();
#ifdef CLANGPLUGIN_TRACE_FUNCTIONS
    fprintf(stdout,"%s\n", __PRETTY_FUNCTION__);
#endif
    int translId = m_TranslUnitId;
    EditorManager* edm = Manager::Get()->GetEditorManager();
    if (!edm)
    {
        event.Skip();
        return;
    }
    cbEditor* ed = edm->GetBuiltinEditor(event.GetEditor());
    if (ed)
    {
        if (ed != m_pLastEditor)
        {
            translId = m_Proxy.GetTranslationUnitId(m_TranslUnitId, event.GetEditor()->GetFilename());
        }
    }
    ClangProxy::RemoveTranslationUnitJob job( cbEVT_CLANG_ASYNCTASK_FINISHED, idClangRemoveTU, translId);
    m_Proxy.AppendPendingJob(job);
    if (translId == m_TranslUnitId)
    {
        m_TranslUnitId = wxNOT_FOUND;
        m_ReparseNeeded = 0;
    }
}
Esempio n. 6
0
void ClangPlugin::OnEditorActivate(CodeBlocksEvent& event)
{
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(event.GetEditor());
    if (ed && !m_EdOpenTimer.IsRunning())
        m_EdOpenTimer.Start(ED_ACTIVATE_DELAY, wxTIMER_ONE_SHOT);
    event.Skip();
}
Esempio n. 7
0
void cbDebuggerPlugin::OnEditorOpened(CodeBlocksEvent& event)
{
    // when an editor opens, look if we have breakpoints for it
    // and notify it...
    EditorBase* ed = event.GetEditor();
    if (ed)
    {
        ed->RefreshBreakpointMarkers();

        if (IsRunning())
        {
            wxString filename;
            int line;
            GetCurrentPosition(filename, line);

            wxFileName edFileName(ed->GetFilename());
            edFileName.Normalize();

            wxFileName dbgFileName(filename);
            dbgFileName.Normalize();
            if (dbgFileName.GetFullPath().IsSameAs(edFileName.GetFullPath()) && line != -1)
            {
                ed->SetDebugLine(line - 1);
            }
        }
    }
    event.Skip(); // must do
}
Esempio n. 8
0
void ClangPlugin::OnEditorOpen(CodeBlocksEvent& event)
{
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(event.GetEditor());
    if (ed)
        m_EdOpenTimer.Start(ED_OPEN_DELAY, wxTIMER_ONE_SHOT);
    event.Skip();
}
Esempio n. 9
0
void cbDebuggerPlugin::OnProjectActivated(CodeBlocksEvent& event)
{
    // allow others to catch this
    event.Skip();

    if(this != Manager::Get()->GetDebuggerManager()->GetActiveDebugger())
        return;
    // when a project is activated and it's not the actively debugged project,
    // ask the user to end debugging or re-activate the debugged project.

    if (!IsRunning())
        return;

    if (event.GetProject() != GetProject() && GetProject())
    {
        wxString msg = _("You can't change the active project while you 're actively debugging another.\n"
                        "Do you want to stop debugging?\n\n"
                        "Click \"Yes\" to stop debugging now or click \"No\" to re-activate the debuggee.");
        if (cbMessageBox(msg, _("Warning"), wxICON_WARNING | wxYES_NO) == wxID_YES)
        {
            Stop();
        }
        else
        {
            Manager::Get()->GetProjectManager()->SetProject(GetProject());
        }
    }
}
Esempio n. 10
0
void cbDebuggerPlugin::OnProjectClosed(CodeBlocksEvent& event)
{
    // allow others to catch this
    event.Skip();

    if(this != Manager::Get()->GetDebuggerManager()->GetActiveDebugger())
        return;
    CleanupWhenProjectClosed(event.GetProject());

    // when a project closes, make sure it's not the actively debugged project.
    // if so, end debugging immediately!
    if (!IsRunning())
        return;

    if (event.GetProject() == GetProject())
    {
        AnnoyingDialog dlg(_("Project closed while debugging message"),
                           _("The project you were debugging has closed.\n"
                             "(The application most likely just finished.)\n"
                             "The debugging session will terminate immediately."),
                            wxART_WARNING, AnnoyingDialog::OK);
        dlg.ShowModal();
        Stop();
        ResetProject();
    }
}
Esempio n. 11
0
void EnvVars::OnProjectActivated(CodeBlocksEvent& event)
{
#if TRACE_ENVVARS
  Manager::Get()->GetLogManager()->DebugLog(F(_T("OnProjectActivated")));
#endif

  if (IsAttached())
  {
    wxString prj_envvar_set = m_ProjectSets[event.GetProject()];
    if (prj_envvar_set.IsEmpty())  // There is no envvar set to apply...
      // Apply default envvar set (but only, if not already active)
      nsEnvVars::EnvvarSetApply(wxEmptyString, false);
    else                           // ...there is an envvar set setup to apply.
    {
      if (nsEnvVars::EnvvarSetExists(prj_envvar_set))
      {
        EV_DBGLOG(_T("EnvVars: Discarding envvars set '")
                 +nsEnvVars::GetActiveSetName()+_T("'."));
        nsEnvVars::EnvvarSetDiscard(wxEmptyString); // Remove currently active envvars
        if (prj_envvar_set.IsEmpty())
          EV_DBGLOG(_T("EnvVars: Setting up default envvars set."));
        else
          EV_DBGLOG(_T("EnvVars: Setting up envvars set '")+prj_envvar_set
                   +_T("' for activated project."));
        // Apply envvar set always (as the old one has been discarded above)
        nsEnvVars::EnvvarSetApply(prj_envvar_set, true);
      }
      else
        EnvvarSetWarning(prj_envvar_set);
    }
  }

  event.Skip(); // propagate the event to other listeners
}// OnProjectActivated
Esempio n. 12
0
//TODO: Tooltips for error messages
void CodeChecker::OnTooltip(CodeBlocksEvent& e)
{
    EditorBase *edb=e.GetEditor();
    if(!edb->IsBuiltinEditor())
        return;
    cbEditor *ed=(cbEditor *)edb;
    int lexer=ed->GetControl()->GetLexer();
    if(m_commands.find(lexer)==m_commands.end())
        return;
    /* NOTE: The following 2 lines of codes can fix [Bug #11785].
    *       The solution may not the best one and it requires the editor
    *       to have the focus (even if C::B has the focus) in order to pop-up the tooltip. */
    if (wxWindow::FindFocus() != static_cast<wxWindow*>(ed->GetControl()))
        return;
    int pos = ed->GetControl()->PositionFromPointClose(e.GetX(), e.GetY());
    if(pos==wxSCI_INVALID_POSITION)
        return;
    int line = ed->GetControl()->LineFromPosition(pos);
    if(m_issues.find(ed->GetFilename())==m_issues.end())
        return;
    CodeIssues &ci=m_issues[ed->GetFilename()];
    for(CodeIssues::iterator it=ci.begin();it!=ci.end();++it)
        if(line==it->line)
        {
            if (ed->GetControl()->CallTipActive())
                ed->GetControl()->CallTipCancel();
//            LogMessage(wxString::Format(_("Tooltip dear: X - %i, Y - %i, pos - %i"),e.GetX(),e.GetY(),pos));
            wxString msg=it->msg;//_T("Goodnight Dear");
            ed->GetControl()->CallTipShow(pos, msg);
        }
}
Esempio n. 13
0
void DebuggerManager::OnSettingsChanged(CodeBlocksEvent& event)
{
    if (event.GetInt() == cbSettingsType::Compiler || event.GetInt() == cbSettingsType::Debugger)
    {
        if (m_useTargetsDefault)
            FindTargetsDebugger();
    }
}
Esempio n. 14
0
void ReopenEditor::OnProjectOpened(CodeBlocksEvent& event)
{
    cbProject* prj = event.GetProject();
    int index = m_ClosedProjects.Index(prj);
    if(index != wxNOT_FOUND)
        m_ClosedProjects.RemoveAt(index);
    event.Skip();
}
Esempio n. 15
0
void lib_finder::OnProjectClose(CodeBlocksEvent& event)
{
    event.Skip();
    cbProject* Proj = event.GetProject();
    ProjectMapT::iterator i = m_Projects.find(Proj);
    if ( i == m_Projects.end() ) return;
    delete i->second;
    m_Projects.erase(i);
}
Esempio n. 16
0
void ClangCodeCompletion::OnEditorClose(CodeBlocksEvent& event)
{
    EditorManager* edm = Manager::Get()->GetEditorManager();
    if (!edm)
    {
        event.Skip();
        return;
    }
    event.Skip();
}
Esempio n. 17
0
void PythonDebugger::OnValueTooltip(CodeBlocksEvent& event)
{
    event.Skip();
    if (!m_DebuggerActive)
        return;
    if (!IsStopped())
        return;

    EditorBase* base = event.GetEditor();
    cbEditor* ed = base && base->IsBuiltinEditor() ? static_cast<cbEditor*>(base) : 0;
    if (!ed)
        return;

    if(ed->IsContextMenuOpened())
    {
    	return;
    }

	// get rid of other calltips (if any) [for example the code completion one, at this time we
	// want the debugger value call/tool-tip to win and be shown]
    if(ed->GetControl()->CallTipActive())
    {
    	ed->GetControl()->CallTipCancel();
    }

    const int style = event.GetInt();
    if (style != wxSCI_P_DEFAULT && style != wxSCI_P_OPERATOR && style != wxSCI_P_IDENTIFIER && style != wxSCI_P_CLASSNAME)
        return;

    wxPoint pt;
    pt.x = event.GetX();
    pt.y = event.GetY();
    int pos = ed->GetControl()->PositionFromPoint(pt);
    int start = ed->GetControl()->WordStartPosition(pos, true);
    int end = ed->GetControl()->WordEndPosition(pos, true);
    while(ed->GetControl()->GetCharAt(start-1)==_T('.'))
        start=ed->GetControl()->WordStartPosition(start-2, true);
    wxString token;
    if (start >= ed->GetControl()->GetSelectionStart() &&
        end <= ed->GetControl()->GetSelectionEnd())
    {
        token = ed->GetControl()->GetSelectedText();
    }
    else
        token = ed->GetControl()->GetTextRange(start,end);
    if (token.IsEmpty())
        return;

    wxString cmd;
    cmd+=_T("pw ")+token+_T("\n");
    DispatchCommands(cmd,DBGCMDTYPE_WATCHTOOLTIP,true);
    m_watch_tooltip_pos=pos;
}
Esempio n. 18
0
void AutoVersioning::OnProjectClosed(CodeBlocksEvent& event)
{
    if (IsAttached())
    {
        m_ProjectMap.erase(event.GetProject());
        m_ProjectMapVersionState.erase(event.GetProject());
        m_IsVersioned.erase(event.GetProject());
        if(m_Project == event.GetProject())
        {   // should always be the case (??? we hope ??)
            m_Project = 0;
        }
    }
}// OnProjectClosed
Esempio n. 19
0
// cbEVT_EDITOR_DEACTIVATED
void CCManager::OnDeactivateEd(CodeBlocksEvent& event)
{
    DoHidePopup();
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(event.GetEditor());
    if (ed)
    {
        cbStyledTextCtrl* stc = ed->GetControl();
        if (stc->CallTipActive())
            stc->CallTipCancel();
        m_CallTipActive = wxSCI_INVALID_POSITION;
    }
    event.Skip();
}
Esempio n. 20
0
void ClangPlugin::OnProjectOptionsChanged(CodeBlocksEvent& event)
{
    event.Skip();
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(event.GetEditor());
    if (ed)
    {
        int compileCommandChanged = UpdateCompileCommand(ed);
        if (compileCommandChanged)
        {
            std::cout<<"OnProjectOptionsChanged: Calling reparse (compile command changed)"<<std::endl;
            RequestReparse();
        }
    }
}
Esempio n. 21
0
void CodeBlocksApp::OnAppActivate(wxActivateEvent& event)
{
    // allow others to process this event
    event.Skip();

    if (s_Loading)
        return; // still loading; we can't possibly be interested for this event ;)

    Manager *manager = Manager::Get();
    if (!manager || manager->IsAppShuttingDown())
        return;

    // Activation & De-Activation event
    CodeBlocksEvent cbEvent;
    if (event.GetActive())
        cbEvent.SetEventType(cbEVT_APP_ACTIVATED);
    else
        cbEvent.SetEventType(cbEVT_APP_DEACTIVATED);
    Manager::Get()->ProcessEvent(cbEvent);

    if (!event.GetActive())
        return;

    // fix for bug #18007: In batch build mode the following is not needed
    if (  !m_Batch
        && Manager::Get()->GetEditorManager()
        && Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/check_modified_files"), true))
    {
        // for some reason a mouse up event doesn't make it into scintilla (scintilla bug)
        // therefore the workaround is not to directly call the editorManager, but
        // take a detour through an event
        // the bug is when the file has been offered to reload, no matter what answer you
        // give the mouse is in a selecting mode, adding/removing things to it's selection as you
        // move it around
        // so : idEditorManagerCheckFiles, EditorManager::OnCheckForModifiedFiles just exist for this workaround
        wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, idEditorManagerCheckFiles);
        wxPostEvent(Manager::Get()->GetEditorManager(), evt);
        cbProjectManagerUI *prjManUI = m_Frame->GetProjectManagerUI();
        if (prjManUI)
            static_cast<ProjectManagerUI*>(prjManUI)->CheckForExternallyModifiedProjects();
    }
    cbEditor* ed = Manager::Get()->GetEditorManager()
                 ? Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor() : nullptr;
    if (ed)
    {
        // hack for linux: without it, the editor loses the caret every second activate o.O
        Manager::Get()->GetEditorManager()->GetNotebook()->SetFocus();
        ed->GetControl()->SetFocus();
    }
}
Esempio n. 22
0
void ClangCodeCompletion::OnEditorActivate(CodeBlocksEvent& event)
{
    event.Skip();
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(event.GetEditor());
    if (ed)
    {
        wxString fn = ed->GetFilename();

        ClTranslUnitId id = m_pClangPlugin->GetTranslationUnitId(fn);
        if (m_TranslUnitId != id )
        {
        }
        m_TranslUnitId = id;
    }
}
Esempio n. 23
0
void ToDoList::OnReparseCurrent(CodeBlocksEvent& event)
{
    bool forced = (event.GetEventType() == cbEVT_EDITOR_OPEN || event.GetEventType() == cbEVT_EDITOR_SAVE);
    if (m_InitDone && m_AutoRefresh && !(ProjectManager::IsBusy()))
    {
        if (m_ParsePending)
        {
            m_ParsePending = false;
            Parse();
        }
        else
            ParseCurrent(forced);
    }
    event.Skip();
}
Esempio n. 24
0
void AutoVersioning::OnCompilerFinished(CodeBlocksEvent& event)
{
    if (m_Project && IsAttached() && m_IsVersioned[event.GetProject()])
    {
        ++(GetVersionState().Values.BuildCount);
    }
} // end of OnCompilerFinished
Esempio n. 25
0
void lib_finder::OnCompilerFinished(CodeBlocksEvent& event)
{
    event.Skip();

    // We don't need target bindings anymore
    m_Targets.clear();
}
Esempio n. 26
0
// ----------------------------------------------------------------------------
void JumpTracker::OnEditorUpdateEvent(CodeBlocksEvent& event)
// ----------------------------------------------------------------------------
{
    event.Skip();

    if ( m_bShuttingDown )
        return;
    if (m_bJumpInProgress)
        return;

    cbEditor* ed =  Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
    if(not ed)
        return;

    wxString edFilename = ed->GetFilename();
    cbStyledTextCtrl* edstc = ed->GetControl();
    if(edstc->GetCurrentLine() == wxSCI_INVALID_POSITION)
        return;

    long edLine = edstc->GetCurrentLine();
    long edPosn = edstc->GetCurrentPos();

    long topLine = edstc->GetFirstVisibleLine();
    long scnSize = edstc->LinesOnScreen();
    long botLine = (topLine+scnSize)-1; // In keeping with top line == 0 origin
    botLine = (botLine < 0) ? 0 : botLine;
    botLine = (botLine > edstc->GetLineCount()) ? edstc->GetLineCount() : botLine;

    #if defined(LOGGING)
    //LOGIT( _T("JT OnEditorUpdateEvent Filename[%s] line[%ld] pos[%ld] "), edFilename.c_str(), edLine, edPosn);
    //LOGIT( _T("JT \ttopLine[%ld] botLine[%ld] OnScrn[%ld] "), topLine, botLine, edstc->LinesOnScreen());
    #endif

    // New editor activated?
    if (m_FilenameLast not_eq edFilename)
    {
        m_PosnLast = edPosn;
        m_FilenameLast = edFilename;
        //if ( m_Cursor not_eq JumpDataContains(edFilename, edPosn) )
            JumpDataAdd(edFilename, edPosn, edLine);
    }

    // If new line within half screen of old line, don't record current line
    long lineLast = edstc->LineFromPosition(m_PosnLast);
    //bool bIsVis = ( edstc->GetLineVisible(lineLast) ); doesnt work
    //if ( (lineLast >= topLine) &&                      doesnt work
    //    (lineLast < botLine) )
    int halfPageSize = edstc->LinesOnScreen()>>1;
    if ( halfPageSize > abs(edLine - lineLast))
        return;

    // record new posn
    m_PosnLast = edPosn;
    m_FilenameLast = edFilename;
    //if ( m_Cursor not_eq JumpDataContains(edFilename, edPosn) )
        JumpDataAdd(edFilename, edPosn, edLine);

    return;
}//OnEditorUpdateEvent
Esempio n. 27
0
void ClangPlugin::OnProjectActivate(CodeBlocksEvent& event)
{
    event.Skip();
#ifdef CLANGPLUGIN_TRACE_FUNCTIONS
    fprintf(stdout,"%s\n", __PRETTY_FUNCTION__);
#endif
    return;
}
Esempio n. 28
0
void ClangDiagnostics::OnEditorClose(CodeBlocksEvent& event)
{
    event.Skip();
    if (!IsAttached())
        return;
    m_Diagnostics.clear();
    m_TranslUnitId = -1;
}
Esempio n. 29
0
// ----------------------------------------------------------------------------
void JumpTracker::OnProjectActivatedEvent(CodeBlocksEvent& event)
// ----------------------------------------------------------------------------
{
    event.Skip();

    // NB: EVT_PROJECT_ACTIVATE is occuring before EVT_PROJECT_OPEN
    // NB: EVT_EDITOR_ACTIVATE event occur before EVT_PROJECT_ACTIVATE or EVT_PROJECT_OPEN

    event.Skip();
    if (m_bShuttingDown) return;
    if (not IsAttached()) return;

    // Previous project was closing
    if (m_bProjectClosing)
        m_bProjectClosing = false;

}//OnProjectActivatedEvent
Esempio n. 30
0
void ProjectManager::OnAppDoneStartup(CodeBlocksEvent& event)
{
    // we do not send the workspace loaded event yet because: a) We don't know
    // if there's a workspace yet, and b) app.cpp hasn't finished init'ing yet.
    // We'll let app.cpp send the workspace changed for us when it's done.
    m_CanSendWorkspaceChanged = true;
    event.Skip();
}