Abdelrazak Younes wrote:
> Peter Kümmel wrote:
>> While your discussion I've finished the tab implementation. :)
> 
> I always said that, less talk, more action!
> :-)
> 
> 
>> Please test or comment it.
>> It should be possible to port it back to 1.4 (there is also a QTabBar)
> 
> I think it is a very good solution for 1.4 where there is only one
> possible LyXView. And you could reuse the menu backend for it as the
> BufferList looking and the associated LFUN is already implemented there.
> This would mean a bit less code. Otherwise the code looks very clean to
> my eyes.

If it's OK for JMarc.

> For 1.5, while I agree that your patch is a very good first step I'd
> prefer that we think a bit more about what we really want.

Yes at least as starting point.

> 
> Abdel.
> 
> 

New in this patch:
 - tabs also handle the selection via the View menu
 - tabs are only showed when there is more than one document


Peter
Index: frontends/LyXView.h
===================================================================
--- frontends/LyXView.h (revision 15548)
+++ 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 15548)
+++ frontends/qt4/GuiView.h     (working copy)
@@ -26,7 +26,7 @@
 #include <QCloseEvent>
 
 class QToolBar;
-
+class WidgetWithTabBar;
 //class FuncRequest;
 
 //class string;
@@ -70,6 +70,8 @@
        virtual void clearMessage();
        virtual bool hasFocus() const;
 
+       virtual void updateTab();
+
        /// show - display the top-level window
        void show();
 
@@ -79,6 +81,7 @@
        /// menu item has been selected
        void activated(FuncRequest const &);
 
+       void initTab(QWidget* workArea);
 
 Q_SIGNALS:
        void closing(int);
@@ -90,6 +93,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);
@@ -120,6 +125,9 @@
        void updateFloatingGeometry();
        ///
        QRect floatingGeometry_;
+
+       struct GuiViewPrivate;
+       GuiViewPrivate& d;
 };
 
 } // namespace frontend
Index: frontends/qt4/GuiImplementation.C
===================================================================
--- frontends/qt4/GuiImplementation.C   (revision 15548)
+++ frontends/qt4/GuiImplementation.C   (working copy)
@@ -136,7 +136,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 15548)
+++ frontends/qt4/GuiView.C     (working copy)
@@ -38,6 +38,8 @@
 #include "session.h"
 #include "lyxfunc.h"
 #include "MenuBackend.h"
+#include "buffer.h"
+#include "bufferlist.h"
 
 #include <QAction>
 #include <QApplication>
@@ -45,13 +47,30 @@
 #include <QPixmap>
 #include <QStatusBar>
 #include <QToolBar>
+#include <QTabBar>
 
 #include <boost/bind.hpp>
 
 using std::endl;
 using std::string;
 using std::vector;
+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;
@@ -65,9 +84,23 @@
 
 } // namespace anon
 
+struct GuiView::GuiViewPrivate
+{
+       typedef std::map<int, FuncRequest> FuncMap;
+       typedef std::pair<int, FuncRequest> FuncMapPair;
+       typedef std::map<string, QString> NameMap;
+       typedef std::pair<string, QString> NameMapPair;
 
+       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);
@@ -89,6 +122,7 @@
 
 GuiView::~GuiView()
 {
+       delete &d;
 }
 
 
@@ -221,7 +255,124 @@
        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()
+{
+       QTabBar& tb = *d.wt->tabbar;
+
+       // update when all  is done
+       tb.blockSignals(true);
+
+       typedef std::vector<string> Strings;
+       Strings const names = theBufferList().getFileNames();
+       size_t n_size = names.size();
+
+       Strings addtab;
+       // show tabs only when there is more 
+       // than one file opened
+       if (n_size > 1)
+       {
+               for (size_t i = 0; i != n_size; i++) 
+                       if (d.namemap.find(names[i]) == d.namemap.end())
+                               addtab.push_back(names.at(i));
+       }
+
+       for(size_t i = 0; i<addtab.size(); i++)
+       {
+               QString tab_name = lyx::toqstr(onlyFilename(addtab.at(i))); 
+               d.namemap.insert(GuiViewPrivate::NameMapPair(addtab.at(i), 
tab_name));
+               tb.addTab(tab_name);
+       }
+
+       // check if all names showed by the tabs
+       // are also in the current bufferlist
+       Strings removetab;
+       bool notall = true;
+       if (n_size < 2)
+               notall = false;
+       std::map<string, QString>::iterator tabit = d.namemap.begin();
+       for (;tabit != d.namemap.end(); ++tabit)
+       {
+               bool found = false;
+               for (size_t i = 0; i != n_size; i++) 
+                       if (tabit->first == names.at(i) && notall)
+                               found = true;
+               if (!found)
+                       removetab.push_back(tabit->first);
+       }
+       
+
+       // remove tabs
+       for(size_t i = 0; i<removetab.size(); i++)
+       {
+               if (d.namemap.find(removetab.at(i)) != d.namemap.end())
+               {
+                       tabit = d.namemap.find(removetab.at(i));
+                       for (int i = 0; i < tb.count(); i++)
+                               if (tb.tabText(i) == tabit->second)
+                               {
+                                       tb.removeTab(i);
+                                       break;
+                               }
+                       d.namemap.erase(tabit);
+               }
+       }
+
+       // rebuild func map
+       if (removetab.size() > 0 || addtab.size() > 0)
+       {
+               d.funcmap.clear();
+               tabit = d.namemap.begin();
+               for (;tabit != d.namemap.end(); ++tabit)
+               {
+                       QTabBar& tb = *d.wt->tabbar;
+                       for (int i = 0; i < tb.count(); i++)
+                       {
+                               if (tb.tabText(i) == tabit->second)
+                               {
+                                       FuncRequest func(LFUN_BUFFER_SWITCH, 
tabit->first);
+                                       
d.funcmap.insert(GuiViewPrivate::FuncMapPair(i, func));
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       // set current tab
+       if (view()->buffer()) 
+       {
+               string cur_title = view()->buffer()->fileName();
+               if (d.namemap.find(cur_title) != d.namemap.end())
+               {
+                       QString tabname = d.namemap.find(cur_title)->second;
+                       for (int i = 0; i < tb.count(); i++)
+                               if (tb.tabText(i) == tabname)
+                               {
+                                       tb.setCurrentIndex(i);
+                                       break;
+                               }
+               }
+       }
+
+       tb.blockSignals(false);
+       d.wt->update();
+}
+
+void GuiView::currentTabChanged (int index)
+{
+       std::map<int, FuncRequest>::const_iterator 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 15548)
+++ 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