OK:
I'm making a plugin right now. It adds all open and opened files to a list. In the list the file name and the project name of the file are displayed.
When the plugin is enabled and I open a project, the entries in the list show up fine with their file name correctly set, but with their project name empty. I believe this is due to the project not existing at the moment the files are opened. When a file gets opened, the plugin queries for its name and the name of the project. This is triggered by the EVT_EDITOR_OPEN. As the project does not exist at this time, the project name is retrieved as empty. Then the project comes to life, it has a name, and I would be forced to scan the open files to set the project name accordingly.
When the plugin is disabled, and I have a project open, and then enable the plugin the project name is displayed correctly.
I am able to make this work in my plugin, it just does not feel very straight forward.
Also having to query each time for this :
if ( !an_editor || !an_editor->VisibleToTree() || !an_editor->IsBuiltinEditor() )
return;
is quite ugly. I still accept the !an_editor part to check against NULL, but the other two are rather awkward, don't you think?
Regards
frithjofh
Yes, I looked how it is done in the openfilelist plugin. I copied from there. My code:
Entry::Entry(const EditorBase* editor) :
m_pEditor(editor), // no ownership
m_pAttribute(nullptr), // no ownership
m_AgeIndex(-1),
m_ImageIndex(0), // ascii
m_ShortName(m_pEditor->GetShortName()),
m_FileName(m_pEditor->GetFilename()),
m_ProjectName(wxEmptyString)
{
if (m_pEditor->GetModified()) m_ImageIndex = 1; // modified
else if (m_pEditor->IsReadOnly()) m_ImageIndex = 2; // read only
ProjectFile* prjf((static_cast<const cbEditor*>(m_pEditor))->GetProjectFile());
if(prjf)
{
cbProject* prj = prjf->GetParentProject();
if(prj)
m_ProjectName = prj->GetTitle();
}
}
Obviously this class is a sort of wrapper for the files information, some retrieved from c::b, other set by my plugin. Resulting behavior as to the moment is: when the plugin is active and I open a project, the projects name does not get caught. If I have the project already open and then enable the plugin the project name does get caught. Construction of Entry is triggered by EVT_EDITOR_OPEN.
I could listen for the EVT_PROJECT_OPEN and then set the project name to the Entries accordingly, that will work, but that seems very clumsy. This is first problem.
Second issue: no, I do not know right now how to avoid check IsBuiltinEditor(), but I think having to do this check raises the question if inheritance is used right here.
Third issue: I care for VisibleToTree() here (as does the openfilelist plugin) because of the presence of the start page.
regards and thank you for the attention :)
yes, this is the real code:
ProjectFile* prjf((static_cast<const cbEditor*>(m_pEditor))->GetProjectFile());
I do this a lot (shame on me for readability), but its not an assignment, but a construction, actually.
I think the issue is that on opening a project cbEVT_EDITOR_OPEN events are sent before the project actually exists. I will use the trailing cbEVT_PROJECT_OPEN to set the name of those editors afterward. This is a bit ugly, and not very intuitive, but I recon nobody (not me for sure) will change the way these events are fired.
For the moment I stay put. When the plugin is in any presentable shape, I'll post it. Its function will combine the OpenFileList and the ClosedFileList in one and add a visual history of files. The most of it is working already, but I not satisfied yet.
Thanks for all the attention and greetings from Asturias :)
Then how about putting the information inside the event object. It could have besides the generic GetEditor() function others that retrieve a specific editor, like GetBuiltinEditor() or so, returning NULL when it is not a built in and the editor if it is?
Well the SDK does not know special editors and should not know it (it e.g. knows nothing about wxSmith). So the SDK cannot return a special editor like that except if we integrate all special editors into the SDK which is simply impossible and also makes no sense.
Having another method GetBuiltinEditor() besides GetEditor() turns this:
if (event.GetEditor() && event.GetEditor()->IsBuiltIn())
...into:
if (event.GetBuiltInEditor())
Well - we can do this, but it means that in 90% of the cases you pass this overhead (each event object grows) but don't need it for what benefit?
In the end, if the SDK provides this method it also checks for both (event.GetEditor() && event.GetEditor()->IsBuiltIn()), so you could do yourself in your plugin a (static) method that does this, like (pseudo-code):
cbEditor * GetBuiltInEditor(cbEvent* evt)
{
if (evt && evt.GetEditor() && evt.GetEditor()->IsBuiltIn())
return static_cast<cbEditor>(evt.GetEditor());
return 0L;
}
Then you can use it easily as desired. In the end you as plugin developer (this applies to all) plugin developers) will always have special needs. If we put all this into the SDK it will sooner or later be bloated. This is why I am always asking, show me a use case where it makes really sense.