wxAuiManager::SavePerspective() Problem

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2293
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

wxAuiManager::SavePerspective() Problem

Post by evstevemd » Wed Oct 06, 2010 6:24 am

Hi,
I need to retrieve and save All AUI perspective and according to wxDocs, the said method is supposed to do it. now when I use in my XML settings, the app crashes. If I replace the SavePerspective thing with literal wxString, app saves everything well. I'm puzzled as Docs indicates that it returns wxString.

I use wxWidgets 2.8 (that comes with Codelite) and wxWidgets XML Library. Code to retrieve and write XML file is shown below

Code: Select all

wxString AuiSettings = myAuiManager.SavePerspective();
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 19.04/Windows 10 Pro/MacOS 10.13 - GCC/MinGW/Clang, CodeLite IDE]

jfouche
Super wx Problem Solver
Super wx Problem Solver
Posts: 442
Joined: Tue May 06, 2008 4:52 pm
Location: France

Post by jfouche » Wed Oct 06, 2010 7:57 am

Hello

I do not have problems with perspectives. Here is how I use it :

Code: Select all

static const wxString CFG_AUI_PERSPECTIVE = wxT("gui/aui");

MyFrame::MyFrame(wxWindow* parent, ...)
: wxFrame(...)
{
   // Create AUI panes
   ...

   wxString auiPerspective;
   if (wxConfig::Get()->Read(CFG_AUI_PERSPECTIVE, &auiPerspective)) {
      m_aui.LoadPerspective(auiPerspective, false);
   }
   m_aui.Update();
}

MyFrame::~MyFrame()
{
   wxConfig::Get()->Write(CFG_AUI_PERSPECTIVE, m_aui.SavePerspective());
   m_aui.UnInit();
}
I do not use xml to store informations, but wxConfig. If this work, your pb probably come from your xml management.

FYI, if you want to use wxConfig, i suggest you to set AppName and Vendor name :

Code: Select all

bool MyApp::OnInit()
{
   SetAppName(wxT("MyAppName"));
   SetVendorName(wxT("MyCompany"));
   ...
}
Jérémie

User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2293
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

Post by evstevemd » Wed Oct 06, 2010 8:03 am

I use it on app's wxApp::OnExit().
May be I should shift it to Destructor of wxFrame
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 19.04/Windows 10 Pro/MacOS 10.13 - GCC/MinGW/Clang, CodeLite IDE]

jfouche
Super wx Problem Solver
Super wx Problem Solver
Posts: 442
Joined: Tue May 06, 2008 4:52 pm
Location: France

Post by jfouche » Wed Oct 06, 2010 8:44 am

in wxApp::OnExit(), your frame is already destroyed
Jérémie

User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2293
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

Post by evstevemd » Wed Oct 06, 2010 10:42 am

jfouche wrote:in wxApp::OnExit(), your frame is already destroyed
:shock:
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 19.04/Windows 10 Pro/MacOS 10.13 - GCC/MinGW/Clang, CodeLite IDE]

User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2293
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

Post by evstevemd » Wed Oct 06, 2010 11:17 am

Now, I get the strings and I try to set them but It doesn't display any pane at all. I can retrieve the string and set it and call Update but I get No Pane at all.

Here is how I get it loaded (Debugger showed me perspective strings are there)

Code: Select all

void MainFrame::readConfig(){	
	wxString settingsFileName=wxT("generalsettings.config");
	GeneralSettings* settings = GeneralSettings::Instance(settingsFileName);
	wxString auiSettings = settings->readConf(wxT("AUI"));
	appMgr.LoadPerspective(auiSettings, false);//Load AUI settings
	
	
	//Unload settings
	GeneralSettings::Release();
	
}
and In Constructor I do this

Code: Select all

//Add Panes

//conf loadig
this->readConfig();	
appMgr.Update();
I don't know where I do things wrong
Attachments
bigbug.PNG
bigbug.PNG (15.91 KiB) Viewed 3162 times
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 19.04/Windows 10 Pro/MacOS 10.13 - GCC/MinGW/Clang, CodeLite IDE]

jfouche
Super wx Problem Solver
Super wx Problem Solver
Posts: 442
Joined: Tue May 06, 2008 4:52 pm
Location: France

Post by jfouche » Wed Oct 06, 2010 12:54 pm

Maybe the pb comes from the fact that the 1st time, you do not have perspective, so you probably load an empty string :

Code: Select all

wxString auiSettings = settings->readConf(wxT("AUI"));
doesn't tell you if auiSettings are loaded. So you try applying bad settings to perspective.

That's why I do :

Code: Select all

   if (wxConfig::Get()->Read(CFG_AUI_PERSPECTIVE, &auiPerspective)) {
      m_aui.LoadPerspective(auiPerspective, false);
   }
   m_aui.Update();
Jérémie

User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2293
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

Post by evstevemd » Wed Oct 06, 2010 6:37 pm

the puzzle is, I can see looong string via debugger, but may be it hav some little problem. I'm confused
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 19.04/Windows 10 Pro/MacOS 10.13 - GCC/MinGW/Clang, CodeLite IDE]

User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2293
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

Post by evstevemd » Thu Oct 07, 2010 7:05 am

Strange enough it saves well and it seems to load them well.
I don't know what I'm going wrong
here is the string:
layout2|name=00ce99f84cad6fe10000060a00000001;caption=BookShelf;state=2044;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=011949384cad6fe10000060a00000002;caption=Book;state=2044;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=196;besth=195;minw=196;minh=195;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=01198a004cad6fe10000060a00000003;caption=Comments;state=2044;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=196;besth=195;minw=196;minh=195;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=0122bb984cad6fe10000060a00000004;caption=Dictionary;state=2044;dir=3;layer=0;row=0;pos=1;prop=100000;bestw=196;besth=195;minw=196;minh=195;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(5,0,0)=22|dock_size(2,0,0)=507|dock_size(3,0,0)=214|
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 19.04/Windows 10 Pro/MacOS 10.13 - GCC/MinGW/Clang, CodeLite IDE]

Kerry
Experienced Solver
Experienced Solver
Posts: 58
Joined: Fri Mar 07, 2008 5:44 pm

Post by Kerry » Mon Oct 18, 2010 1:08 am

I'm having exactly the same problem (sorry to hijack this post, but it appears we're having the same problem at the same time).

When I save a perspective I get this long string (1295 chars). I save it to a config file where I see all 1295 chars. I close the app. When I restart it, I check for the config and try to find the perspective string. If it's there (yes, with an if.. - so I don't load an empty perspective string) I load it. All I see is one toolbar. The other 5 panes that are supposed to be managed by wxAuiManager don't appear.

Strangely enough, if I save/load perspectives within one session (without closing/restarting my app) everything works fine. I can drag panes around then load a perspective and they jump right back to their saved positions.

I've also tried writing and reading the perspective string using the clipboard. From within one session, I save the perspective to the clipboard and paste it into a text editor. I select the text in the editor and copy it. I drag some panes around, then load the perspective from the clipboard - everything works properly. Now I exit the app and restart. When I try to load the perspective from the clipboard (which is still on the clipboard unchanged - verified by pasting it into a text editor again) all of my panes disapear, just like when I read and load it from file.

I verified that the string still contains 1295 chars after it's been loaded the second time.

Here's my code:

Code: Select all

	wxFileConfig *ConfigurationFile = new wxFileConfig(_T(""), _T(""),
		wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPathWithSep() + "config.ini", _T(""),
		wxCONFIG_USE_RELATIVE_PATH);

	// Write GUI configuration from to file
	ConfigurationFile->Write(_T("/GUI/LayoutString"), Manager.SavePerspective());
and to load the saved perspective:

Code: Select all

wxFileConfig *ConfigurationFile = new wxFileConfig(_T(""), _T(""),
		wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPathWithSep() + "config.ini", _T(""),
		wxCONFIG_USE_RELATIVE_PATH);

	// Read GUI configuration from file
	wxString LayoutString;
	if (ConfigurationFile->Read(_T("/GUI/LayoutString"), &LayoutString))
		Manager.LoadPerspective(LayoutString);
In case it's useful, I've attached screenshots of the perspective as-saved, and as-loaded.

Let me know if I should start my own post...

I'm using MSW, wxWidgets 2.8.10.

Thanks!

-Kerry
Attachments
pre_and_post_load_perspective.JPG

ngpaton
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 20, 2008 8:23 am

Post by ngpaton » Mon Oct 18, 2010 8:57 am

Hi,

The AUI perspective details how to layout existing AUI panes. It will not create the panes for you.

So before you load the perspective you need to create the panes. Then load the perspective. AUI will re-layout the panes to match the perspective.

So in my case I have unique names for all the possible panes. So before loading the perspective I search through the AUI perspective looking for the 'name=' field and then recreating all the required panes. Then I load the perspective. Would be handy if there was an AUI function to let you get info from a layout string rather than my code needing to know the format.

If you look in wxAuiManager::LoadPerspective() there is this code:

Code: Select all

        wxAuiPaneInfo& p = GetPane(pane.name);
        if (!p.IsOk())
        {
            // the pane window couldn't be found
            // in the existing layout -- skip it
            continue;
        }
This is probably where it is failing in your case. Would have been nice if there was a wxLogDebug() call here to let you know it was ignoring a section of the layout string. Even better would be a virtual function that we could implement that would allow us to generate the pane on demand.

Cheers

Nigel

User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2293
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

Post by evstevemd » Mon Oct 18, 2010 10:12 am

oh..thanks Nigel,
can you imagine I have wrestled with problem for so long as blind man looking for solution.
May God bless you. You have saved me alot of pain and make my progress
THANK YOU
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 19.04/Windows 10 Pro/MacOS 10.13 - GCC/MinGW/Clang, CodeLite IDE]

Kerry
Experienced Solver
Experienced Solver
Posts: 58
Joined: Fri Mar 07, 2008 5:44 pm

Post by Kerry » Mon Oct 18, 2010 10:49 pm

Ah yes, my problem as well!

Thanks for the help!

-Kerry

tulu
In need of some credit
In need of some credit
Posts: 5
Joined: Tue Jan 31, 2017 5:56 pm

Re: wxAuiManager::SavePerspective() Problem

Post by tulu » Wed Feb 22, 2017 9:12 pm

Fixed my issue too - 2 days of searching... thx

OrbWeaver
In need of some credit
In need of some credit
Posts: 2
Joined: Fri Feb 19, 2021 8:17 pm

Re: wxAuiManager::SavePerspective() Problem

Post by OrbWeaver » Sat Feb 20, 2021 9:53 am

Apologies for the thread necromancy, but having found this thread after investigating and Googling this exact problem, I thought it was worth detailing the ultimate solution.

You must give your panels consistent, deterministic wxAuiPanelInfo::Name() properties

If you do not specify a Name() when adding a panel, wxWidgets gives the panel an internal, pseudo-random name which changes between sessions. These names are written into the string exported with SavePerspective() and matched in the LoadPerspective() step; if names do not match, the panels will simply disappear (I would suggest this is still a bug: non-matching perspective strings should surely result in no change to the panels, not panels disappearing?).

Nigel's answer touches on this, but sort of implies that the only problem is that you need to create the panels first. This is indeed necessary, but not sufficient: the key fact is you need to create the panels with the same names as in the previous session. In hindsight, this seems somewhat obvious, however nothing in the documentation indicates that the Name() values are important or that LoadPerspective() depends on their values, and there is no error at runtime if the names fail to match, only the unhelpful change to panel visibility.

My suggestions for improvement:
  • The documentation should clearly specify that LoadPerspective() uses Name() values for matching, and will fail if consistent panel names are not specified when the wxAuiManager is populated. Similarly, the documentation for Name() should indicate what the internal name is used for, and should mention that without a user-specified name, an internal name will be generated which is only consistent within the lifetime of the wxAuiManager object.
  • If LoadPerspective() is called with a string containing names which cannot be matched with current panels, these names are ignored and unmatched panels do not change their properties in any way. Depending on whether it is considered valid to attempt to load a perspective with a mix of matching and unmatching names (perhaps if an application can be configured with various different panels), there could be either a warning to console or a wxASSERT in debug mode to alert the developer that something is wrong.

Post Reply