While your discussion I've finished the tab implementation. :) Please test or comment it. It should be possible to port it back to 1.4 (there is also a QTabBar)
Peter
Index: frontends/LyXView.h =================================================================== --- frontends/LyXView.h (revision 15526) +++ frontends/LyXView.h (working copy) @@ -153,6 +153,9 @@ /// updates the title of the window void updateWindowTitle(); + /// updates the tab view + virtual void updateTab() = 0; + /// reset autosave timer void resetAutosaveTimer(); Index: frontends/qt4/GuiView.h =================================================================== --- frontends/qt4/GuiView.h (revision 15526) +++ frontends/qt4/GuiView.h (working copy) @@ -26,7 +26,7 @@ #include <QCloseEvent> class QToolBar; - +class WidgetWithTabBar; //class FuncRequest; //class string; @@ -66,6 +66,8 @@ virtual void clearMessage(); virtual bool hasFocus() const; + virtual void updateTab(); + /// show - display the top-level window void show(); @@ -75,6 +77,7 @@ /// menu item has been selected void activated(FuncRequest const &); + void initTab(QWidget* workArea); Q_SIGNALS: void closing(int); @@ -86,6 +89,8 @@ /// populate a toplevel menu and all its children on demand void updateMenu(QAction *); + void currentTabChanged (int index); + protected: /// make sure we quit cleanly virtual void closeEvent(QCloseEvent * e); @@ -116,6 +121,9 @@ void updateFloatingGeometry(); /// QRect floatingGeometry_; + + struct GuiViewPrivate; + GuiViewPrivate& d; }; } // namespace frontend Index: frontends/qt4/GuiImplementation.C =================================================================== --- frontends/qt4/GuiImplementation.C (revision 15526) +++ frontends/qt4/GuiImplementation.C (working copy) @@ -103,7 +103,7 @@ work_areas_[id]->setBufferView(buffer_views_[id].get()); view->setWorkArea(work_areas_[id]); - view->setCentralWidget(work_areas_[id]); + view->initTab(work_areas_[id]); return id; } Index: frontends/qt4/GuiView.C =================================================================== --- frontends/qt4/GuiView.C (revision 15526) +++ frontends/qt4/GuiView.C (working copy) @@ -21,6 +21,8 @@ #include "MenuBackend.h" #include "funcrequest.h" #include "funcrequest.h" +#include "buffer.h" +#include "bufferlist.h" #include "debug.h" @@ -45,14 +47,30 @@ #include <QPixmap> #include <QStatusBar> #include <QToolBar> +#include <QTabBar> - #include <boost/bind.hpp> using std::string; using std::endl; +using lyx::support::onlyFilename; +class WidgetWithTabBar : public QWidget +{ +public: + QTabBar* tabbar; + WidgetWithTabBar(QWidget* w) + { + tabbar = new QTabBar; + QVBoxLayout* l = new QVBoxLayout; + l->addWidget(tabbar); + l->addWidget(w); + l->setMargin(0); + setLayout(l); + } +}; + namespace lyx { using support::subst; @@ -66,9 +84,25 @@ } // namespace anon +struct GuiView::GuiViewPrivate +{ + typedef std::map<int, FuncRequest> FuncMap; + typedef std::pair<int, FuncRequest> FuncMapPair; + typedef std::map<int, FuncRequest>::const_iterator FuncMapCIter; + typedef std::map<string, QString> NameMap; + typedef std::pair<string, QString> NameMapPair; + typedef std::map<string, QString>::const_iterator NameMapCIter; + typedef std::map<string, QString>::iterator NameMapIter; + FuncMap funcmap; + NameMap namemap; + WidgetWithTabBar* wt; + GuiViewPrivate() + {} +}; + GuiView::GuiView(int id) - : QMainWindow(), LyXView(id), commandbuffer_(0) + : QMainWindow(), LyXView(id), commandbuffer_(0), d(*new GuiViewPrivate) { setAttribute(Qt::WA_DeleteOnClose, true); setAttribute(Qt::WA_QuitOnClose, true); @@ -90,6 +124,7 @@ GuiView::~GuiView() { + delete &d; } @@ -222,7 +257,104 @@ statusbar_timer_.stop(); } +void GuiView::initTab(QWidget* workarea) +{ + d.wt = new WidgetWithTabBar(workarea); + setCentralWidget(d.wt); + QObject::connect(d.wt->tabbar, SIGNAL(currentChanged(int)), + this, SLOT(currentTabChanged(int))); +} +void GuiView::updateTab() +{ + // update when all is done + d.wt->tabbar->blockSignals(true); + if (view()->buffer()) + { + string cur_title = view()->buffer()->fileName(); + if (d.namemap.find(cur_title) == d.namemap.end()) + { + // insert + QString tab_title = lyx::toqstr(onlyFilename(cur_title)); + QTabBar& tb = *d.wt->tabbar; + int index = tb.addTab(tab_title); + tb.setCurrentIndex(index); + FuncRequest func(LFUN_BUFFER_SWITCH, cur_title); + d.funcmap.insert(GuiViewPrivate::FuncMapPair(index, func)); + d.namemap.insert(GuiViewPrivate::NameMapPair(cur_title, tab_title)); + } + } + + // check if all names showed by the tabs are also + // in the current bufferlist + typedef std::vector<string> Strings; + Strings const names = theBufferList().getFileNames(); + Strings::const_iterator docend = names.end(); + GuiViewPrivate::NameMapIter tabit = d.namemap.begin(); + Strings remove; + for (;tabit != d.namemap.end(); ++tabit) + { + bool found = false; + Strings::const_iterator docit = names.begin(); + for (; docit != docend; ++docit) + if (tabit->first == *docit) + found = true; + if (!found) + remove.push_back(tabit->first); + } + + // remove tabs + for(size_t i = 0; i<remove.size(); i++) + { + if (d.namemap.find(remove[i]) != d.namemap.end()) + { + tabit = d.namemap.find(remove[i]); + std::cout << "GuiView::updateTab tab removed : " << tabit->first <<"\n"; + QTabBar& tb = *d.wt->tabbar; + for (int index = 0; index<tb.count(); index++) + if (tb.tabText(index) == tabit->second) + { + tb.removeTab(index); + break; + } + d.namemap.erase(tabit); + } + } + + // rebuild func map + if (remove.size() > 0) + { + d.funcmap.clear(); + tabit = d.namemap.begin(); + for (;tabit != d.namemap.end(); ++tabit) + { + QTabBar& tb = *d.wt->tabbar; + for (int index = 0; index<tb.count(); index++) + { + if (tb.tabText(index) == tabit->second) + { + FuncRequest func(LFUN_BUFFER_SWITCH, tabit->first); + d.funcmap.insert(GuiViewPrivate::FuncMapPair(index, func)); + break; + } + } + } + } + d.wt->tabbar->blockSignals(false); + d.wt->tabbar->update(); +} + +void GuiView::currentTabChanged (int index) +{ + std::cout << "GuiView::currentTabChanged: " << index <<"\n"; + GuiViewPrivate::FuncMapCIter it = d.funcmap.find(index); + if (it != d.funcmap.end()) + { + activated(it->second); + } +} + + void GuiView::updateStatusBar() { // let the user see the explicit message Index: frontends/LyXView.C =================================================================== --- frontends/LyXView.C (revision 15526) +++ frontends/LyXView.C (working copy) @@ -129,6 +129,7 @@ updateLayoutChoice(); updateWindowTitle(); updateStatusBar(); + updateTab(); work_area_->redraw(); } @@ -144,6 +145,7 @@ updateToolbars(); updateLayoutChoice(); updateWindowTitle(); + updateTab(); if (loaded) { connectBuffer(*work_area_->bufferView().buffer()); showErrorList("Parse");