Open wxtrac opened 14 years ago
aui_persp_merging.patch
(0.3 KiB)I'm not sure to understand what is this about but it doesn't seem 2.8.12-critical. Is this issue 2.8-specific or does it also appear in 2.9 BTW?
As usual, any opinions from more AUI-aware people would be welcome.
This is definitely an issue. Does your patch solve the problem? I believe that a small change to the API is necessary to facilitate this, which precludes 2.8 as a milestone.
The issue is still in 2.9 and needs to be fixed.
Hello, sorry being late to answer,
First: it is not critical that the patch makes its way to 2.8.12, thus I'd like it, because I have to patch Aui a lot on our wxWidget compilation. But if you can't integrate it, I can live without it.
Second: yes, the patch solves the problem in an easy way; you just have to strip away unwanted tags form the perspective sting before loading it to avoid destroying the concerned attributes. I use regular expression for this:
wxRegEx del_captions(_T("caption=[^;]*;"));
del_captions.ReplaceAll(&layout_str, wxEmptyString);
frameManager.LoadPerspective(layout_str, false);
The only problem I see it that it relies on the perspective string format and it may not be guarantied in the future. What API change may you propose ?
I have found this problem a pain in my side for a far too long time as well.
Rather than patching a few lines in wxWidgets, I made a workaround function to update captions in configuration string with current ones:
_/ Updates perspective captions with matching captions from panes._/
_/ \param[in ] mgr wxAUI manager_/ \param[inout] perspective Perspective string to update captions in
_/_/ \returns
_/ - \c true when update succeeded_/ - \c false otherwise
_/
bool wxAuiManagerUpdatePerspectiveCaptions(wxAuiManager& mgr, wxString& perspective)
{
wxString input = perspective;
wxString part;
// check layout string version
// 'layout1' = wxAUI 0.9.0 - wxAUI 0.9.2
// 'layout2' = wxAUI 0.9.2 (wxWidgets 2.8)
part = input.BeforeFirst(wxT('|'));
input = input.AfterFirst(wxT('|'));
part.Trim(true);
part.Trim(false);
if (part != wxT("layout2"))
return false;
wxString result;
result.Alloc(500);
result = wxT('layout2|');
// replace escaped characters so we can
// split up the string easily
input.Replace(wxT("\\|"), wxT("\a"));
input.Replace(wxT("\\;"), wxT("\b"));
while (1)
{
wxString pane_part = input.BeforeFirst(wxT('|'));
input = input.AfterFirst(wxT('|'));
pane_part.Trim(true);
// if the string is empty, we're done parsing
if (pane_part.empty())
break;
// Undo our escaping
pane_part.Replace(wxT("\a"), wxT("|"));
pane_part.Replace(wxT("\b"), wxT(";"));
if (pane_part.Left(9) == wxT("dock_size"))
{
result += pane_part + wxT('|');
continue;
}
wxAuiPaneInfo pane;
mgr.LoadPaneInfo(pane_part, pane);
wxAuiPaneInfo& p = mgr.GetPane(pane.name);
if (!p.IsOk())
{
// the pane window couldn't be found
// in the existing layout -- skip it
continue;
}
// Update caption.
pane.caption = p.caption;
// Re-generate and append pane info.
result += mgr.SavePaneInfo(pane) + wxT('|');
}
perspective = result;
return true;
}
The following helper class demonstrates an example how to restore the wxAUI configuration:
#define wxPERSIST_AUIMGR_KIND "AuiManager"
// names for persistent options
#define wxPERSIST_AUIMGR_PERSPECTIVE "perspective"
_/
_/ Supports saving/restoring wxAuiManager state
///
class wxPersistentAuiManager : public wxPersistentObject
{
public:
wxPersistentAuiManager(wxAuiManager *mgr) : wxPersistentObject(mgr)
{
}
virtual wxString GetKind() const
{
return wxT(wxPERSIST_AUIMGR_KIND);
}
virtual wxString GetName() const
{
// Borrow the name of wxAguiManager from its window.
return GetManager()->GetManagedWindow()->GetName();
}
virtual void Save() const
{
// Save perspective string to configuration.
SaveValue(wxT(wxPERSIST_AUIMGR_PERSPECTIVE), GetManager()->SavePerspective());
}
virtual bool Restore()
{
// Load perspective string from configuration.
wxString persp;
wxCHECK(RestoreValue(wxT(wxPERSIST_AUIMGR_PERSPECTIVE), &persp), false);
// Update captions (see http://trac.wxwidgets.org/ticket/12528).
wxAuiManager* mgr = GetManager();
wxCHECK(wxAuiManagerUpdatePerspectiveCaptions(*mgr, persp), false);
// Restore perspective.
return mgr->LoadPerspective(persp);
}
protected:
wxAuiManager *GetManager() const
{
return static_cast<wxAuiManager*>(GetObject());
}
private:
wxDECLARE_NO_COPY_CLASS(wxPersistentAuiManager);
};
_/
_/ wxAuiManager's instantiation of wxCreatePersistentObject template
///
inline wxPersistentObject *wxCreatePersistentObject(wxAuiManager *mgr)
{
return new wxPersistentAuiManager(mgr);
}
I suggest the wxAuiManager::LoadPerspective()
method to be extended to:
bool LoadPerspective(const wxString& perspective, bool update # true, bool ignore_captionsfalse);
In wxAuiManager::LoadPerspective()
method implementation before the p.SafeSet(pane);
is called one should add:
if (ignore_captions)
{
// Copy original caption before restoring pane info.
pane.caption = p.caption;
}
This solution would be:
Issue migrated from trac ticket # 12528
component: wxAui | priority: normal | keywords: wxAui perspective restoration
2010-09-29 15:48:27: @lpoujoulat created the issue
I ran into the following problem with wxAUI perspective saving: in a multilingual application, I set the language to french and I save the perspective. Then I set the language to english and restore the perspective:
All the pane title come back to french because titles are also stored in the perspective string.
I then strip the title tag out of the persepective string before restoring: this time I got a blank title wheras I expected to have the titles left untouched.
To solve this, I made a small change to Load Perspective() that instead of setting a default value for missing perspective tags, leaves the corresponding item untouched in the panes. This way, it is now possible to partially restore panes.
Patch for this is attached
Regards