Author Topic: Tab shows file is not modified when using default code : fix  (Read 4787 times)

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Tab shows file is not modified when using default code : fix
« on: January 25, 2006, 12:17:45 am »
I have created a patch for the following bug :
http://sourceforge.net/tracker/index.php?func=detail&aid=1403630&group_id=126998&atid=707416

What happens is this :
0) have a project open
1) file menu -> new file
-> we end up in MainFrame::OnFileNewEmpty(), this calls EditorMgr::New() :
    a) which creates a new cbEditor, this in turn leads to SetModified(true) -> SetEditorTitle() --> *Untitled1
    b) then we have ed->SaveAs(), where we got asked to specify a file name -> SetEditorTitle() is called once more, the SaveAs also lead to SetModified(true) -> when in SetModified the value passed is already the value of the member m_Modified very little happens (most important no SetEditorTitle call), then SaveAs calls Save(), through OnEditorChange we end up twice in a call to SetModified, first SetModified(false) ->  SetEditorTitle() -> test.cpp (say that was the name we gave the file), secondly SetModified(true) -> SetEditorTitle() -> *test.cpp, and then Save() itself calss SetModified(false) -> SetEditorTitle() -> test.cpp
   c) add the default code -> again twice through OnEditorChange(), at first SetModified(false) -> was already false, secondly SetModified(true) -> SetEditorTitle() ->*test.cpp

Then back in the MainFrame::OnFileNewEmpty, we answer the question to add the new file to the project with yes --->end up with the following call ed->SetProjectFile(pf) (with second argument defaulted to false, I even tried with specifying it explicilty true, -> extra call to SetModified, but that does not help), and in this method we get a direct call to SetEditorTitle() -> test.cpp  (the file is still modified, that new default code, just like you would have typed it in manually, if you close the editor, you'll see you get a 'save/changed : yes/no dialog).

SO : a whole bunch of SetModified, SetEditorTitle calls ;-)
But the last one does no longer take into account that the file was modified, and that is the major cause of the bug. This also happens when the SetEditorTitle() method is called from cbEditor::SaveAs and cbEditor::SetEditorStyle()

SetModified will do either call SetEditorTitle with the m_ShortName (when not modified), or with "*"+m_ShortName (when modified), and it will only to this if it's argument (modified) is different from it's saved state (m_Modified).

Solution : The fact that the "*" should be prepended or not should not be judged in SetModified but in SetEditorTitle(), so that those other calls who don't take into account the 'modified -> *' mechanism also work correctly. You could also insert that logic at those call sites, but that's not good, the logic should be at the SetEditorTitle. And this logic that was part of SetModified can be removed there, it just call SetEditorTitle with the ShortName.

The patch just implements this fix :
https://sourceforge.net/tracker/index.php?func=detail&aid=1414110&group_id=126998&atid=707418

Note : that next to the cbEditor method's SetModified, SetEditorStyle, SaveAs, SetProjectFile, there's only one other (and even external) client of cbEditor, it is the link with the scripbindings. So it might be possible that if you would not allow through scripts that a EditorTITLE will be set, the method can become public, and then all those internal calls don't need to specify as an argument the m_ShortName, since it is accessible because it is a member. This has NOT been implemented by the patch.

Some 'new' code snippets :
Quote
void cbEditor::SetModified(bool modified)
{
    if (modified != m_Modified)
    {
        m_Modified = modified;
        if (!m_Modified)
        {
            m_pControl->SetSavePoint();
        }
      SetEditorTitle(m_Shortname);
        Manager::Get()->GetEditorManager()->RefreshOpenedFilesTree();
    }
    // visual state
    if (m_pProjectFile)
        m_pProjectFile->SetFileState(m_pControl->GetReadOnly() ? fvsReadOnly : (m_Modified ? fvsModified : fvsNormal));
}

void cbEditor::SetEditorTitle(const wxString& title)
{
   if(m_Modified)
   {
      SetTitle(g_EditorModified + title);
   }
   else
   {
      SetTitle(title);
   }
}

That's all folks,
Lieven
« Last Edit: January 25, 2006, 12:19:35 am by killerbot »