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");

Reply via email to