Hi, Peter,

I revised your patch and now it works fine (save restore on/off and
location). It works like this. The major problem is with
math/review/table toolbars. The logic is now:

1. if math is on when lyx exists, I assume it is always on
2. if math is off when lyx exists, I assume it is auto.

Now, we need to change lyx's behavior. Right now, "turn on math" is
not "always on". The math toolbar will disappear if I click on text.

JMarc, can I apply?
Bo
Index: src/session.C
===================================================================
--- src/session.C	(revision 15675)
+++ src/session.C	(working copy)
@@ -48,6 +48,7 @@
 string const sec_lastopened = "[last opened files]";
 string const sec_bookmarks = "[bookmarks]";
 string const sec_session = "[session info]";
+string const sec_toolbars = "[toolbars]";
 
 } // anon namespace
 
@@ -267,6 +268,51 @@
 }
 
 
+void ToolbarSection::read(istream & is)
+{
+	string tmp;
+	do {
+		char c = is.peek();
+		if (c == '[')
+			break;
+		getline(is, tmp);
+
+		// Read session info, saved as key/value pairs
+		// would better yell if pos returns npos
+		string::size_type pos = tmp.find_first_of(" = ");
+		// silently ignore lines without " = "
+		if (pos != string::npos) {
+			string key = tmp.substr(0, pos);
+			bool visible;
+			int location;
+			istringstream value(tmp.substr(pos + 3));
+			value >> visible;
+			value.ignore(1); // ignore " "
+			value >> location;
+			toolbars[key] = ToolbarInfo(visible, location);
+		}
+	} while (is.good());
+}
+
+
+void ToolbarSection::write(ostream & os) const
+{
+	os << '\n' << sec_toolbars << '\n';
+	for (ToolbarMap::const_iterator tb = toolbars.begin();
+		tb != toolbars.end(); ++tb) {
+		os << tb->first << " = "
+		  << tb->second.visible << " "
+		  << tb->second.location << '\n';
+	}
+}
+
+
+ToolbarSection::ToolbarInfo & ToolbarSection::load(string const & name)
+{
+	return toolbars[name];
+}
+
+
 void SessionInfoSection::read(istream & is)
 {
 	string tmp;
@@ -349,6 +395,8 @@
 			lastFilePos().read(is);
 		else if (tmp == sec_bookmarks)
 			bookmarks().read(is);
+		else if (tmp == sec_toolbars)
+			toolbars().read(is);
 		else if (tmp == sec_session)
 			sessionInfo().read(is);
 		else
@@ -368,6 +416,7 @@
 		lastOpened().write(os);
 		lastFilePos().write(os);
 		bookmarks().write(os);
+		toolbars().write(os);
 		sessionInfo().write(os);
 	} else
 		lyxerr << "LyX: Warning: unable to save Session: "
Index: src/frontends/Toolbars.C
===================================================================
--- src/frontends/Toolbars.C	(revision 15675)
+++ src/frontends/Toolbars.C	(working copy)
@@ -37,14 +37,77 @@
 {}
 
 
+void Toolbars::initFlags(ToolbarBackend::Toolbar & tbb)
+{
+	ToolbarSection::ToolbarInfo & info = LyX::ref().session().toolbars().load(tbb.name);
+
+	unsigned int flags = static_cast<int>(tbb.flags);
+	// remove position
+	unsigned int clean = ~ (ToolbarBackend::TOP | ToolbarBackend::BOTTOM
+				| ToolbarBackend::RIGHT | ToolbarBackend::LEFT);
+
+	bool valid_location = true;
+	// init tbb.flags with saved location
+	if (info.location == ToolbarSection::ToolbarInfo::top)
+		flags = flags & clean | ToolbarBackend::TOP;
+	else if (info.location == ToolbarSection::ToolbarInfo::bottom)
+		flags = flags & clean | ToolbarBackend::BOTTOM;
+	else if (info.location == ToolbarSection::ToolbarInfo::right)
+		flags = flags & clean | ToolbarBackend::RIGHT;
+	else if (info.location == ToolbarSection::ToolbarInfo::left)
+		flags = flags & clean | ToolbarBackend::LEFT;
+	else
+		valid_location = false;
+
+	// invalid location is for a new toolbar that has no saved information,
+	// so info.visible is not used for this case.
+	if (valid_location) {
+		// init tbb.flags with saved visibility,
+		if (info.visible) {
+			// if visible, all toolbars are set to ON, even for math etc
+			// clear one bit
+			flags &= ~ToolbarBackend::OFF;
+			// and set another
+			flags |= ToolbarBackend::ON;
+		} else if((flags & ToolbarBackend::MATH) || (flags & ToolbarBackend::REVIEW) || (flags & ToolbarBackend::TABLE)) {
+			// if not visible, math etc is still auto, do not set off
+			// clear both on and off bit
+			flags &= ~ToolbarBackend::ON;
+			flags &= ~ToolbarBackend::OFF;
+		} else {
+			// for others, set the toolbar off
+			flags &= ~ToolbarBackend::ON;
+			flags |= ToolbarBackend::OFF;
+		}
+	}
+	/*
+	std::cout << "FLAGS: " << flags
+		<< " ON " << (flags & ToolbarBackend::ON) 
+		<< " OFF " << (flags & ToolbarBackend::OFF)
+		<< " L " << (flags & ToolbarBackend::LEFT) 
+		<< " R " << (flags & ToolbarBackend::RIGHT) 
+		<< " T " << (flags & ToolbarBackend::TOP) 
+		<< " B " << (flags & ToolbarBackend::BOTTOM) 
+		<< " MA " << (flags & ToolbarBackend::MATH) 
+		<< " RE " << (flags & ToolbarBackend::REVIEW) 
+		<< " TB " << (flags & ToolbarBackend::TABLE) 
+		<< std::endl;
+	*/
+	// now set the flags
+	tbb.flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
+}
+
+
 void Toolbars::init()
 {
 	// extracts the toolbars from the backend
 	ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
 	ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
 
-	for (; cit != end; ++cit)
+	for (; cit != end; ++cit) {
+		initFlags(const_cast<ToolbarBackend::Toolbar &>(*cit));
 		add(*cit);
+	}
 }
 
 
@@ -84,6 +147,19 @@
 }
 
 
+void Toolbars::saveToolbarInfo()
+{
+	ToolbarSection & tb = LyX::ref().session().toolbars();
+
+	for (ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
+		cit != toolbarbackend.end(); ++cit) {
+		ToolbarsMap::iterator it = toolbars_.find(cit->name);
+		BOOST_ASSERT(it != toolbars_.end());
+		it->second->saveInfo(tb.load(cit->name));
+	}
+}
+
+
 void Toolbars::setLayout(string const & layout)
 {
 	if (layout_)
Index: src/frontends/qt4/QLToolbar.C
===================================================================
--- src/frontends/qt4/QLToolbar.C	(revision 15675)
+++ src/frontends/qt4/QLToolbar.C	(working copy)
@@ -214,6 +214,25 @@
 }
 
 
+void QLToolbar::saveInfo(ToolbarSection::ToolbarInfo & info)
+{
+	// update Toolbar info with current toolbar status
+	info.visible = QLToolbar::isVisible();
+	Qt::ToolBarArea loc = owner_.toolBarArea(this);
+
+	if (loc == Qt::TopToolBarArea)
+		info.location = ToolbarSection::ToolbarInfo::top;
+	else if (loc == Qt::BottomToolBarArea)
+		info.location = ToolbarSection::ToolbarInfo::bottom;
+	else if (loc == Qt::RightToolBarArea)
+		info.location = ToolbarSection::ToolbarInfo::right;
+	else if (loc == Qt::LeftToolBarArea)
+		info.location = ToolbarSection::ToolbarInfo::left;
+	else
+		info.location = ToolbarSection::ToolbarInfo::notset;
+}
+
+
 void QLToolbar::update()
 {
 	// This is a speed bottleneck because this is called on every keypress
Index: src/frontends/qt4/QLToolbar.h
===================================================================
--- src/frontends/qt4/QLToolbar.h	(revision 15675)
+++ src/frontends/qt4/QLToolbar.h	(working copy)
@@ -22,6 +22,9 @@
 #include <QToolBar>
 #include <vector>
 
+#include "lyx_main.h"
+#include "session.h"
+
 class QComboBox;
 
 namespace lyx {
@@ -67,6 +70,7 @@
 	void add(FuncRequest const & func, lyx::docstring const & tooltip);
 	void hide(bool);
 	void show(bool);
+	void saveInfo(ToolbarSection::ToolbarInfo & info);
 	void update();
 	LayoutBox * layout() const { return layout_.get(); }
 
Index: src/frontends/qt4/GuiView.C
===================================================================
--- src/frontends/qt4/GuiView.C	(revision 15675)
+++ src/frontends/qt4/GuiView.C	(working copy)
@@ -182,6 +182,7 @@
 		session.sessionInfo().save("WindowPosX", convert<string>(geometry.x()));
 		session.sessionInfo().save("WindowPosY", convert<string>(geometry.y()));
 	}
+	getToolbars().saveToolbarInfo();
 }
 						  
 void GuiView::setGeometry(unsigned int width,
Index: src/frontends/Toolbars.h
===================================================================
--- src/frontends/Toolbars.h	(revision 15675)
+++ src/frontends/Toolbars.h	(working copy)
@@ -26,6 +26,8 @@
 #include "ToolbarBackend.h"
 #include <boost/shared_ptr.hpp>
 #include <map>
+#include "lyx_main.h"
+#include "session.h"
 
 
 namespace lyx {
@@ -64,6 +66,10 @@
 	 *  metrics should be updated.
 	 */
 	virtual void show(bool update_metrics) = 0;
+	/** update toolbar information
+	* ToolbarInfo will then be saved by session
+	*/
+	virtual void saveInfo(ToolbarSection::ToolbarInfo & info) = 0;
 
 	/// Refresh the contents of the bar.
 	virtual void update() = 0;
@@ -86,6 +92,9 @@
 	/// Update the state of the toolbars.
 	void update(bool in_math, bool in_table, bool review);
 
+	/// save toolbar information
+	void saveToolbarInfo();
+
 	/// Select the right layout in the combox.
 	void setLayout(std::string const & layout);
 
@@ -128,6 +137,9 @@
 
 	/// The last textclass layout list in the layout choice selector
 	int last_textclass_;
+
+	// load flags with saved values
+	void initFlags(ToolbarBackend::Toolbar & tbb);
 };
 
 /// Set the layout in the kernel when an entry has been selected
Index: src/session.h
===================================================================
--- src/session.h	(revision 15675)
+++ src/session.h	(working copy)
@@ -238,6 +238,59 @@
 };
 
 
+class ToolbarSection : SessionSection
+{
+public:
+	/// information about a toolbar, not all information can be
+	/// saved/restored by all frontends, but this class provides
+	/// a superset of things that can be managed by session.
+	class ToolbarInfo
+	{
+	public:
+		///
+		ToolbarInfo() :
+			visible(true), location(notset) { }
+		///
+		ToolbarInfo(bool v, int loc) :
+			visible(v), location(static_cast<Location>(loc)) { }
+
+	public:
+		/// on/off
+		bool visible;
+
+		/// location: this can be intepreted differently.
+		enum Location {
+			top,
+			bottom,
+			left,
+			right,
+			notset
+		};
+
+		Location location;
+
+		/// potentially, icons
+	};
+
+	/// info for each toolbar
+	typedef std::map<std::string, ToolbarInfo> ToolbarMap;
+
+public:
+	///
+	void read(std::istream & is);
+
+	///
+	void write(std::ostream & os) const;
+
+	/// return reference to toolbar info, create a new one if needed
+	ToolbarInfo & load(std::string const & name);
+
+private:
+	/// toolbar information
+	ToolbarMap toolbars;
+};
+
+
 class SessionInfoSection : SessionSection
 {
 public:
@@ -307,6 +360,12 @@
 	BookmarksSection const & bookmarks() const { return bookmarks_; }
 
 	///
+	ToolbarSection & toolbars() { return toolbars_; }
+
+	///
+	ToolbarSection const & toolbars() const { return toolbars_; }
+
+	///
 	SessionInfoSection & sessionInfo() { return session_info; }
 
 	///
@@ -336,6 +395,9 @@
 	BookmarksSection bookmarks_;
 
 	///
+	ToolbarSection toolbars_;
+
+	///
 	SessionInfoSection session_info;
 };
 

Reply via email to