Bo Peng wrote:
> Dear all,
> 
> The following patch has just been committed to fix the toolbar
> management problem. It
> 
> 1. change ToolbarMap to ToolbarList
> 2. sort the loaded toolbars according to their saved locations.
> Something like, top/line1/1st, top/line1/2nd, top/line2/1st,
> right/line1/1st ...
> 3. add toolbars in order and add toolbar breaks if necessary.
> 
> Please test.

Great! The tool bars are now exactly restored!


> Bo
> 
> Index: src/session.C
> ===================================================================
> --- src/session.C    (revision 16962)
> +++ src/session.C    (working copy)
> @@ -339,36 +339,66 @@
>                 value >> location;
>                 value >> posx;
>                 value >> posy;
> -                toolbars[key] = ToolbarInfo(state, location, posx, posy);
> +                toolbars.push_back(boost::make_tuple(key,
> ToolbarInfo(state,
> location, posx, posy)));
>             } else
>                 lyxerr[Debug::INIT] << "LyX: Warning: Ignore toolbar
> info: " <<
> tmp << endl;
>         } catch (...) {
>             lyxerr[Debug::INIT] << "LyX: Warning: unknown Toolbar info:
> " <<
> tmp << endl;
>         }
>     } while (is.good());
> +    // sort the toolbars by location, line and position
> +    std::sort(toolbars.begin(), toolbars.end());
> }
> 
> 
> void ToolbarSection::write(ostream & os) const
> {
>     os << '\n' << sec_toolbars << '\n';
> -    for (ToolbarMap::const_iterator tb = toolbars.begin();
> +    for (ToolbarList::const_iterator tb = toolbars.begin();
>         tb != toolbars.end(); ++tb) {
> -        os << tb->first << " = "
> -          << static_cast<int>(tb->second.state) << " "
> -          << static_cast<int>(tb->second.location) << " "
> -          << tb->second.posx << " "
> -          << tb->second.posy << '\n';
> +        os << tb->get<0>() << " = "
> +          << static_cast<int>(tb->get<1>().state) << " "
> +          << static_cast<int>(tb->get<1>().location) << " "
> +          << tb->get<1>().posx << " "
> +          << tb->get<1>().posy << '\n';
>     }
> }
> 
> 
> ToolbarSection::ToolbarInfo & ToolbarSection::load(string const & name)
> {
> -    return toolbars[name];
> +    for (ToolbarList::iterator tb = toolbars.begin();
> +        tb != toolbars.end(); ++tb)
> +        if (tb->get<0>() == name)
> +            return tb->get<1>();
> +    // add a new item
> +    toolbars.push_back(boost::make_tuple(name,
> ToolbarSection::ToolbarInfo()));
> +    return toolbars.back().get<1>();
> }
> 
> 
> +bool operator<(ToolbarSection::ToolbarItem const & a,
> ToolbarSection::ToolbarItem const & b)
> +{
> +    ToolbarSection::ToolbarInfo lhs = a.get<1>();
> +    ToolbarSection::ToolbarInfo rhs = b.get<1>();
> +    // on if before off
> +    if (lhs.state != rhs.state)
> +        return static_cast<int>(lhs.state) < static_cast<int>(rhs.state);
> +    // order of dock does not really matter
> +    if (lhs.location != rhs.location)
> +        return static_cast<int>(lhs.location) <
> static_cast<int>(rhs.location);
> +    // if the same dock, the order depends on position
> +    if (lhs.location == ToolbarSection::ToolbarInfo::TOP ||
> +        lhs.location == ToolbarSection::ToolbarInfo::BOTTOM)
> +        return lhs.posy < rhs.posy || (lhs.posy == rhs.posy && lhs.posx
> < rhs.posx);
> +    else if (lhs.location == ToolbarSection::ToolbarInfo::LEFT ||
> +        lhs.location == ToolbarSection::ToolbarInfo::RIGHT)
> +        return lhs.posx < rhs.posx || (lhs.posx == rhs.posx && lhs.posy
> < rhs.posy);
> +    else
> +        return true;
> +}
> +
> +
> void SessionInfoSection::read(istream & is)
> {
>     string tmp;
> Index: src/frontends/LyXView.h
> ===================================================================
> --- src/frontends/LyXView.h    (revision 16962)
> +++ src/frontends/LyXView.h    (working copy)
> @@ -105,7 +105,7 @@
>     /// show busy cursor
>     virtual void busy(bool) = 0;
> 
> -    virtual Toolbars::ToolbarPtr makeToolbar(ToolbarBackend::Toolbar
> const & tbb) = 0;
> +    virtual Toolbars::ToolbarPtr makeToolbar(ToolbarBackend::Toolbar
> const & tbb, bool newline) = 0;
> 
>     //@{ generic accessor functions
> 
> Index: src/frontends/Toolbars.C
> ===================================================================
> --- src/frontends/Toolbars.C    (revision 16962)
> +++ src/frontends/Toolbars.C    (working copy)
> @@ -109,9 +109,36 @@
>     ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
>     ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
> 
> -    for (; cit != end; ++cit) {
> +    // init flags will also add these toolbars to session if they
> +    // are not already there (e.g. first run of lyx).
> +    for (; cit != end; ++cit)
>         initFlags(*cit);
> -        add(*cit);
> +
> +    // add toolbars according the order in session
> +    ToolbarSection::ToolbarList::const_iterator tb =
> LyX::ref().session().toolbars().begin();
> +    ToolbarSection::ToolbarList::const_iterator te =
> LyX::ref().session().toolbars().end();
> +    ToolbarSection::ToolbarInfo::Location last_loc =
> ToolbarSection::ToolbarInfo::NOTSET;
> +    int last_posx = 0;
> +    int last_posy = 0;
> +    for (; tb != te; ++tb) {
> +        lyxerr[Debug::INIT] << "Adding " << tb->get<0>() << " at
> position "
> << tb->get<1>().posx << " " << tb->get<1>().posy << endl;
> +        // add toolbar break if posx or posy changes
> +        bool newline = tb->get<1>().location == last_loc && (
> +            // if two toolbars at the same location, assume
> uninitialized and
> add toolbar break
> +            (tb->get<1>().posx == last_posx && tb->get<1>().posy ==
> last_posy) ||
> +            (last_loc == ToolbarSection::ToolbarInfo::TOP &&
> tb->get<1>().posy
> != last_posy) ||
> +            (last_loc == ToolbarSection::ToolbarInfo::BOTTOM &&
> tb->get<1>().posy != last_posy) ||
> +            (last_loc == ToolbarSection::ToolbarInfo::LEFT &&
> tb->get<1>().posx != last_posx) ||
> +            (last_loc == ToolbarSection::ToolbarInfo::RIGHT &&
> tb->get<1>().posx != last_posx) );
> +        // find the backend item and add
> +        for (cit = toolbarbackend.begin(); cit != end; ++cit)
> +            if (cit->name == tb->get<0>()) {
> +                add(*cit, newline);
> +                last_loc = tb->get<1>().location;
> +                last_posx = tb->get<1>().posx;
> +                last_posy = tb->get<1>().posy;
> +                break;
> +            }
>     }
> }
> 
> @@ -289,9 +316,9 @@
> }
> 
> 
> -void Toolbars::add(ToolbarBackend::Toolbar const & tbb)
> +void Toolbars::add(ToolbarBackend::Toolbar const & tbb, bool newline)
> {
> -    ToolbarPtr tb_ptr = owner_.makeToolbar(tbb);
> +    ToolbarPtr tb_ptr = owner_.makeToolbar(tbb, newline);
>     toolbars_[tbb.name] = tb_ptr;
> 
>     if (tbb.flags & ToolbarBackend::ON)
> Index: src/frontends/qt4/GuiView.h
> ===================================================================
> --- src/frontends/qt4/GuiView.h    (revision 16962)
> +++ src/frontends/qt4/GuiView.h    (working copy)
> @@ -66,7 +66,8 @@
>         const std::string & geometryArg);
>     virtual void saveGeometry();
>     virtual void busy(bool);
> -    Toolbars::ToolbarPtr makeToolbar(ToolbarBackend::Toolbar const & tbb);
> +    /// add toolbar, if newline==true, add a toolbar break before the
> toolbar
> +    Toolbars::ToolbarPtr makeToolbar(ToolbarBackend::Toolbar const &
> tbb, bool newline);
>     virtual void updateStatusBar();
>     virtual void message(lyx::docstring const & str);
>     virtual void clearMessage();
> Index: src/frontends/qt4/GuiView.C
> ===================================================================
> --- src/frontends/qt4/GuiView.C    (revision 16962)
> +++ src/frontends/qt4/GuiView.C    (working copy)
> @@ -688,70 +688,44 @@
> }
> 
> 
> -Toolbars::ToolbarPtr GuiView::makeToolbar(ToolbarBackend::Toolbar const
> & tbb)
> +Toolbars::ToolbarPtr GuiView::makeToolbar(ToolbarBackend::Toolbar
> const & tbb, bool newline)
> {
> -    // get window size
> -    int w = width();
> -    int h = height();
> -    Session & session = LyX::ref().session();
> -    string val = session.sessionInfo().load("WindowWidth", false);
> -    if (!val.empty())
> -        w = convert<unsigned int>(val);
> -    val = session.sessionInfo().load("WindowHeight", false);
> -    if (!val.empty())
> -        h = convert<unsigned int>(val);
>     QLToolbar * Tb = new QLToolbar(tbb, *this);
> 
>     if (tbb.flags & ToolbarBackend::TOP) {
> +        if (newline)
> +            addToolBarBreak(Qt::TopToolBarArea);
>         addToolBar(Qt::TopToolBarArea, Tb);
> -        if (toolbarSize_.top_width > 0
> -            && toolbarSize_.top_width + Tb->sizeHint().width() > w) {
> -            insertToolBarBreak(Tb);
> -            toolbarSize_.top_width = Tb->sizeHint().width();
> -        } else
> -            toolbarSize_.top_width += Tb->sizeHint().width();
>     }
> 
>     if (tbb.flags & ToolbarBackend::BOTTOM) {
> -        addToolBar(Qt::BottomToolBarArea, Tb);
> // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
> #if (QT_VERSION >= 0x040202)
> -        if (toolbarSize_.bottom_width > 0
> -            && toolbarSize_.bottom_width + Tb->sizeHint().width() > w) {
> -            insertToolBarBreak(Tb);
> -            toolbarSize_.bottom_width = Tb->sizeHint().width();
> -        } else
> -            toolbarSize_.bottom_width += Tb->sizeHint().width();
> +        if (newline)
> +            addToolBarBreak(Qt::BottomToolBarArea);
> #endif
> +        addToolBar(Qt::BottomToolBarArea, Tb);
>     }
> 
>     if (tbb.flags & ToolbarBackend::LEFT) {
> -        addToolBar(Qt::LeftToolBarArea, Tb);
> // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
> #if (QT_VERSION >= 0x040202)
> -        if (toolbarSize_.left_height > 0
> -            && toolbarSize_.left_height + Tb->sizeHint().height() > h) {
> -            insertToolBarBreak(Tb);
> -            toolbarSize_.left_height = Tb->sizeHint().height();
> -        } else
> -            toolbarSize_.left_height += Tb->sizeHint().height();
> +        if (newline)
> +            addToolBarBreak(Qt::LeftToolBarArea);
> #endif
> +        addToolBar(Qt::LeftToolBarArea, Tb);
>     }
> 
>     if (tbb.flags & ToolbarBackend::RIGHT) {
> -        addToolBar(Qt::RightToolBarArea, Tb);
> // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
> #if (QT_VERSION >= 0x040202)
> -        if (toolbarSize_.right_height > 0
> -            && toolbarSize_.right_height + Tb->sizeHint().height() > h) {
> -            insertToolBarBreak(Tb);
> -            toolbarSize_.right_height = Tb->sizeHint().height();
> -        } else
> -            toolbarSize_.right_height += Tb->sizeHint().height();
> +        if (newline)
> +            addToolBarBreak(Qt::RightToolBarArea);
> #endif
> +        addToolBar(Qt::RightToolBarArea, Tb);
>     }
> 
> -    // The following does not work so saved toolbar location can not be
> used.
> +    // The following does not work so I can not restore to exact
> toolbar location
>     /*
>     ToolbarSection::ToolbarInfo & info =
> LyX::ref().session().toolbars().load(tbb.name);
>     Tb->move(info.posx, info.posy);
> Index: src/frontends/Toolbars.h
> ===================================================================
> --- src/frontends/Toolbars.h    (revision 16962)
> +++ src/frontends/Toolbars.h    (working copy)
> @@ -117,8 +117,8 @@
>     typedef boost::shared_ptr<Toolbar> ToolbarPtr;
> 
> private:
> -    /// Add a new toolbar.
> -    void add(ToolbarBackend::Toolbar const & tb);
> +    /// Add a new toolbar. if newline==true, start from a new line
> +    void add(ToolbarBackend::Toolbar const & tb, bool newline);
>     /// Show or hide a toolbar.
>     void displayToolbar(ToolbarBackend::Toolbar const & tb, bool show);
>     /// Update the state of the icons
> Index: src/session.h
> ===================================================================
> --- src/session.h    (revision 16962)
> +++ src/session.h    (working copy)
> @@ -297,9 +297,12 @@
>         /// potentially, icons
>     };
> 
> +    typedef boost::tuple<std::string, ToolbarInfo> ToolbarItem;
> +
>     /// info for each toolbar
> -    typedef std::map<std::string, ToolbarInfo> ToolbarMap;
> +    typedef std::vector<ToolbarItem> ToolbarList;
> 
> +
> public:
>     ///
>     void read(std::istream & is);
> @@ -310,12 +313,25 @@
>     /// return reference to toolbar info, create a new one if needed
>     ToolbarInfo & load(std::string const & name);
> 
> +    /// toolbar begin
> +    ToolbarList::const_iterator begin() { return toolbars.begin(); }
> +
> +    /// toolbar end
> +    ToolbarList::const_iterator end() { return toolbars.end(); }
> +
> private:
>     /// toolbar information
> -    ToolbarMap toolbars;
> +    ToolbarList toolbars;
> };
> 
> +/// comparison operator to sort toolbars, the rules are:
> +///        ON before OFF
> +///     TOP < BOTTOM < LEFT < RIGHT
> +///     Line at each side
> +///     order in each line
> +bool operator< (ToolbarSection::ToolbarItem const & a,
> ToolbarSection::ToolbarItem const & b);
> 
> +
> class SessionInfoSection : SessionSection
> {
> public:
> Index: src/lyx_main.C
> ===================================================================
> --- src/lyx_main.C    (revision 16962)
> +++ src/lyx_main.C    (working copy)
> @@ -653,10 +653,10 @@
>     }
>     // if lyxrc returns (0,0), then use session info
>     else {
> -        string val = session().sessionInfo().load("WindowWidth", false);
> +        string val = session().sessionInfo().load("WindowWidth");
>         if (!val.empty())
>             width = convert<unsigned int>(val);
> -        val = session().sessionInfo().load("WindowHeight", false);
> +        val = session().sessionInfo().load("WindowHeight");
>         if (!val.empty())
>             height = convert<unsigned int>(val);
>         if (session().sessionInfo().load("WindowIsMaximized") == "yes")
> 


-- 
Peter Kümmel

Reply via email to