Session/Toolbars:

* src/LyXAction.C: LFUN_TOOLBAR_TOGGLE_STATE
	* src/session.h/C: add ToolbarSection class
	* src/lyxfunc.C: handle LFUN_TOOLBAR_TOGGLE_STATE
	* src/frontends/LyXView.h/C: toggleToolbarState(name)
	* src/frontends/Toolbars.h/C: initFlags, toogle and save toolbar, 
	    changed update logic
	* src/frontends/qt4/QLToolbar.h/C: saveInfo. Surprisingly little is 
	    asked from frontend.
	* src/frontends/qt4/GuiView.C: save toolbar when lyx exits
	* src/MenuBackend.h/C: add Toolbars submenu
	* src/lfuns.h: add LFUN_TOOLBAR_TOGGLE_STATE
	* src/ToolbarBackend.h: add AUTO flag
	* lib/ui/stdmenus.ui: add view->Toolbar menu


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15691 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2006-11-02 16:01:36 +00:00
parent 6b22addac6
commit eaa33dca6d
16 changed files with 376 additions and 7 deletions

View File

@ -265,6 +265,8 @@ Menuset
Submenu "Update|U" "view_update"
ViewFormats
Separator
Submenu "Toolbars|b" "toolbars"
Separator
Documents
End
@ -272,6 +274,9 @@ Menuset
UpdateFormats
End
Menu "toolbars"
Toolbars
End
#
# INSERT MENU
#

View File

@ -366,6 +366,7 @@ void LyXAction::init()
{ LFUN_WINDOW_NEW, "window-new", NoBuffer },
{ LFUN_WINDOW_CLOSE, "window-close", NoBuffer },
{ LFUN_UNICODE_INSERT, "unicode-insert", Noop },
{ LFUN_TOOLBAR_TOGGLE_STATE, "", Noop },
{ LFUN_NOACTION, "", Noop }
};

View File

@ -36,6 +36,7 @@
#include "lyxfunc.h"
#include "lyxlex.h"
#include "toc.h"
#include "ToolbarBackend.h"
#include "support/filetools.h"
#include "support/lstrings.h"
@ -231,6 +232,7 @@ Menu & Menu::read(LyXLex & lex)
md_floatlistinsert,
md_floatinsert,
md_pasterecent,
md_toolbars,
md_last
};
@ -253,6 +255,7 @@ Menu & Menu::read(LyXLex & lex)
{ "submenu", md_submenu },
{ "toc", md_toc },
{ "updateformats", md_updateformats },
{ "toolbars", md_toolbars },
{ "viewformats", md_viewformats }
};
@ -331,6 +334,10 @@ Menu & Menu::read(LyXLex & lex)
add(MenuItem(MenuItem::PasteRecent));
break;
case md_toolbars:
add(MenuItem(MenuItem::Toolbars));
break;
case md_branches:
add(MenuItem(MenuItem::Branches));
break;
@ -751,6 +758,35 @@ void expandPasteRecent(Menu & tomenu, Buffer const * buf)
}
void expandToolbars(Menu & tomenu, Buffer const * buf)
{
//
// extracts the toolbars from the backend
ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
int i = 1;
for (; cit != end; ++cit, ++i) {
docstring label = convert<docstring>(i) + ". " + _(cit->name);
// frontend does not update ToolbarBackend::flags when it changes toolbar
// Therefore, I can not tell from the flags if the toolbar is on or off
// it is then less confusing to say:
// this is: always on/off/auto
// frontend toolbar change is temporary.
//
if (cit->flags & ToolbarBackend::ON)
label += _(" (always on)");
else if (cit->flags & ToolbarBackend::OFF)
label += _(" (always off)");
else if (cit->flags & ToolbarBackend::AUTO)
label += _(" (auto)");
label += char_type('|') + convert<docstring>(i);
tomenu.add(MenuItem(MenuItem::Command, label,
FuncRequest(LFUN_TOOLBAR_TOGGLE_STATE, _(cit->name))));
}
}
void expandBranches(Menu & tomenu, Buffer const * buf)
{
if (!buf)
@ -819,6 +855,10 @@ void MenuBackend::expand(Menu const & frommenu, Menu & tomenu,
expandPasteRecent(tomenu, buf);
break;
case MenuItem::Toolbars:
expandToolbars(tomenu, buf);
break;
case MenuItem::Branches:
expandBranches(tomenu, buf);
break;

View File

@ -72,6 +72,8 @@ public:
/** This is the list of selections that can
be pasted. */
PasteRecent,
/** toolbars */
Toolbars,
/** Available branches in document */
Branches
};

View File

@ -53,7 +53,8 @@ public:
BOTTOM = 32, //< show at bottom
LEFT = 64, //< show at left
RIGHT = 128, //< show at right
REVIEW = 256 //< shown when change tracking is enabled
REVIEW = 256, //< shown when change tracking is enabled
AUTO = 512 //< only if AUTO is set, will MATH, TABLE and REIVEW is used
};
/// a toolbar
@ -79,6 +80,10 @@ public:
Toolbars::const_iterator end() const { return usedtoolbars.end(); }
Toolbars::iterator begin() { return usedtoolbars.begin(); }
Toolbars::iterator end() { return usedtoolbars.end(); }
/// read a toolbar from the file
void read(LyXLex &);

View File

@ -305,6 +305,20 @@ void LyXView::updateToolbars()
}
void LyXView::toggleToolbarState(string const & name)
{
// it is possible to get current toolbar status like this,...
// but I decide to obey the order of ToolbarBackend::flags
// and disregard real toolbar status.
// toolbars_->saveToolbarInfo();
//
// toggle state on/off/auto
toolbars_->toggleToolbarState(name);
// update toolbar
updateToolbars();
}
void LyXView::updateMenubar()
{
menubar_->update();

View File

@ -136,6 +136,8 @@ public:
/// update the toolbar
void updateToolbars();
/// toggle toolbar state
void toggleToolbarState(std::string const & name);
/// update the menubar
void updateMenubar();
/// update the status bar

View File

@ -22,6 +22,7 @@
#include "lyxfunc.h"
#include "lyxtextclass.h"
#include "LyXView.h"
#include "lyx_main.h"
namespace lyx {
@ -36,15 +37,78 @@ Toolbars::Toolbars(LyXView & owner)
last_textclass_(-1)
{}
#define TurnOnFlag(x) flags |= ToolbarBackend::x
#define TurnOffFlag(x) flags &= ~ToolbarBackend::x
void Toolbars::initFlags(ToolbarBackend::Toolbar & tbb)
{
ToolbarSection::ToolbarInfo & info = LyX::ref().session().toolbars().load(tbb.name);
unsigned int flags = static_cast<unsigned int>(tbb.flags);
// remove position
TurnOffFlag(TOP);
TurnOffFlag(BOTTOM);
TurnOffFlag(RIGHT);
TurnOffFlag(LEFT);
bool valid_location = true;
// init tbb.flags with saved location
if (info.location == ToolbarSection::ToolbarInfo::TOP)
TurnOnFlag(TOP);
else if (info.location == ToolbarSection::ToolbarInfo::BOTTOM)
TurnOnFlag(BOTTOM);
else if (info.location == ToolbarSection::ToolbarInfo::RIGHT)
TurnOnFlag(RIGHT);
else if (info.location == ToolbarSection::ToolbarInfo::LEFT)
TurnOnFlag(LEFT);
else {
TurnOnFlag(TOP);
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,
TurnOffFlag(ON);
TurnOffFlag(OFF);
TurnOffFlag(AUTO);
if (info.state == ToolbarSection::ToolbarInfo::ON)
TurnOnFlag(ON);
else if (info.state == ToolbarSection::ToolbarInfo::OFF)
TurnOnFlag(OFF);
else
TurnOnFlag(AUTO);
}
/*
std::cout << "State " << info.state << " 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)
<< " AU:" << (flags & ToolbarBackend::AUTO)
<< 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();
ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
for (; cit != end; ++cit)
for (; cit != end; ++cit) {
initFlags(*cit);
add(*cit);
}
}
@ -65,6 +129,39 @@ void Toolbars::display(string const & name, bool show)
}
void Toolbars::toggleToolbarState(string const & name)
{
ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
for (; cit != end; ++cit) {
if (cit->name == name) {
int flags = cit->flags;
if (flags & ToolbarBackend::ON) {
TurnOffFlag(ON);
TurnOnFlag(OFF);
} else if (flags & ToolbarBackend::AUTO) {
TurnOffFlag(AUTO);
TurnOnFlag(ON);
} else if ((flags & ToolbarBackend::MATH) || (flags & ToolbarBackend::TABLE)
|| (flags & ToolbarBackend::REVIEW)) {
// for math etc, toggle from off -> auto
TurnOffFlag(OFF);
TurnOnFlag(AUTO);
} else {
// for others, toggle from off -> on
TurnOffFlag(OFF);
TurnOnFlag(ON);
}
cit->flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
break;
}
}
}
#undef TurnOnFlag
#undef TurnOffFlag
void Toolbars::update(bool in_math, bool in_table, bool review)
{
update();
@ -74,16 +171,53 @@ void Toolbars::update(bool in_math, bool in_table, bool review)
ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
for (; cit != end; ++cit) {
if (cit->flags & ToolbarBackend::MATH)
if (cit->flags & ToolbarBackend::ON)
displayToolbar(*cit, true);
else if (cit->flags & ToolbarBackend::OFF)
displayToolbar(*cit, false);
else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::MATH))
displayToolbar(*cit, in_math);
else if (cit->flags & ToolbarBackend::TABLE)
else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::TABLE))
displayToolbar(*cit, in_table);
else if (cit->flags & ToolbarBackend::REVIEW)
else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::REVIEW))
displayToolbar(*cit, review);
}
}
void Toolbars::saveToolbarInfo()
{
ToolbarSection & tb = LyX::ref().session().toolbars();
for (ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
cit != toolbarbackend.end(); ++cit) {
ToolbarsMap::iterator it = toolbars_.find(cit->name);
BOOST_ASSERT(it != toolbars_.end());
// get toolbar info from session.
ToolbarSection::ToolbarInfo & info = tb.load(cit->name);
if (cit->flags & ToolbarBackend::ON)
info.state = ToolbarSection::ToolbarInfo::ON;
else if (cit->flags & ToolbarBackend::OFF)
info.state = ToolbarSection::ToolbarInfo::OFF;
else if (cit->flags & ToolbarBackend::AUTO)
info.state = ToolbarSection::ToolbarInfo::AUTO;
// save other information
// if auto, frontend should *not* set on/off
it->second->saveInfo(info);
// maybe it is useful to update flags with real status. I do not know
/*
if (!(cit->flags & ToolbarBackend::AUTO)) {
unsigned int flags = static_cast<unsigned int>(cit->flags);
flags &= ~(info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarBackend::OFF : ToolbarBackend::ON);
flags |= (info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarBackend::ON : ToolbarBackend::OFF);
if (info.state == ToolbarSection::ToolbarInfo::ON)
cit->flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
}
*/
}
}
void Toolbars::setLayout(string const & layout)
{
if (layout_)

View File

@ -26,6 +26,7 @@
#include "ToolbarBackend.h"
#include <boost/shared_ptr.hpp>
#include <map>
#include "session.h"
namespace lyx {
@ -64,6 +65,10 @@ public:
* 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;
@ -83,9 +88,15 @@ public:
/// Show/hide the named toolbar.
void display(std::string const & name, bool show);
/// toggle the state of toolbars (on/off/auto)
void toggleToolbarState(std::string const & name);
/// 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 +139,9 @@ private:
/// 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

View File

@ -185,6 +185,7 @@ void GuiView::saveGeometry()
session.sessionInfo().save("WindowPosX", convert<string>(geometry.x()));
session.sessionInfo().save("WindowPosY", convert<string>(geometry.y()));
}
getToolbars().saveToolbarInfo();
}
void GuiView::setGeometry(unsigned int width,

View File

@ -214,6 +214,32 @@ void QLToolbar::show(bool)
}
void QLToolbar::saveInfo(ToolbarSection::ToolbarInfo & info)
{
// if info.state == auto *do not* set on/off
if (info.state != ToolbarSection::ToolbarInfo::AUTO) {
if (QLToolbar::isVisible())
info.state = ToolbarSection::ToolbarInfo::ON;
else
info.state = ToolbarSection::ToolbarInfo::OFF;
}
//
// no need to save it here.
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

View File

@ -21,6 +21,7 @@
#include <QToolBar>
#include <vector>
#include "session.h"
class QComboBox;
@ -67,6 +68,7 @@ public:
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(); }

View File

@ -374,6 +374,7 @@ enum kb_action {
LFUN_UNICODE_INSERT, // Lgb 20061022
// 285
LFUN_BOOKMARK_CLEAR, // bpeng 20061031
LFUN_TOOLBAR_TOGGLE_STATE, // bpeng 20061101
LFUN_LASTACTION // end of the table
};

View File

@ -635,6 +635,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
case LFUN_BUFFER_PREVIOUS:
case LFUN_WINDOW_NEW:
case LFUN_WINDOW_CLOSE:
case LFUN_TOOLBAR_TOGGLE_STATE:
// these are handled in our dispatch()
break;
@ -1690,6 +1691,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
LyX::ref().session().bookmarks().clear();
break;
case LFUN_TOOLBAR_TOGGLE_STATE:
lyx_view_->toggleToolbarState(argument);
break;
default: {
BOOST_ASSERT(lyx_view_);
view()->cursor().dispatch(cmd);

View File

@ -48,6 +48,7 @@ string const sec_lastfilepos = "[cursor positions]";
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 @@ BookmarksSection::Bookmark const & BookmarksSection::bookmark(unsigned int i) co
}
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);
int state;
int location;
istringstream value(tmp.substr(pos + 3));
value >> state;
value.ignore(1); // ignore " "
value >> location;
toolbars[key] = ToolbarInfo(state, 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 << " = "
<< static_cast<int>(tb->second.state) << " "
<< static_cast<int>(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 @@ void Session::readFile()
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 @@ void Session::writeFile() const
lastOpened().write(os);
lastFilePos().write(os);
bookmarks().write(os);
toolbars().write(os);
sessionInfo().write(os);
} else
lyxerr << "LyX: Warning: unable to save Session: "

View File

@ -238,6 +238,65 @@ private:
};
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() :
state(ON), location(NOTSET) { }
///
ToolbarInfo(int s, int loc) :
state(static_cast<State>(s)), location(static_cast<Location>(loc)) { }
public:
enum State {
ON,
OFF,
AUTO
};
/// on/off/auto
State state;
/// 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:
@ -306,6 +365,12 @@ public:
///
BookmarksSection const & bookmarks() const { return bookmarks_; }
///
ToolbarSection & toolbars() { return toolbars_; }
///
ToolbarSection const & toolbars() const { return toolbars_; }
///
SessionInfoSection & sessionInfo() { return session_info; }
@ -335,6 +400,9 @@ private:
///
BookmarksSection bookmarks_;
///
ToolbarSection toolbars_;
///
SessionInfoSection session_info;
};