José Matos wrote: > On Monday 30 October 2006 12:13 pm, Peter Kümmel wrote: >> Did I get you right that then it is also dropped for 1.5.0? > > I was referring to 1.5. :-) > > If Jean-Marc and Abdel support you can commit it. As far as I remember the > patch is small and localized, right?
Yes, most is done in GuiView.C. So what do you think -Jean-Marc, Abdel and others- of applying it to trunk. In principle it's just a 'button' for switching between buffers, and could also work as starting point for a more complete QTabWidget solution. Attached the updated patch. Peter
Index: src/frontends/LyXView.h =================================================================== --- src/frontends/LyXView.h (revision 15620) +++ src/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: src/frontends/qt4/GuiView.h =================================================================== --- src/frontends/qt4/GuiView.h (revision 15620) +++ src/frontends/qt4/GuiView.h (working copy) @@ -26,7 +26,6 @@ #include <QCloseEvent> class QToolBar; - //class FuncRequest; //class string; @@ -70,6 +69,8 @@ virtual void clearMessage(); virtual bool hasFocus() const; + virtual void updateTab(); + /// show - display the top-level window void show(); @@ -79,6 +80,7 @@ /// menu item has been selected void activated(FuncRequest const &); + void initTab(QWidget* workArea); Q_SIGNALS: void closing(int); @@ -90,6 +92,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 +124,9 @@ void updateFloatingGeometry(); /// QRect floatingGeometry_; + + struct GuiViewPrivate; + GuiViewPrivate& d; }; } // namespace frontend Index: src/frontends/qt4/GuiImplementation.C =================================================================== --- src/frontends/qt4/GuiImplementation.C (revision 15620) +++ src/frontends/qt4/GuiImplementation.C (working copy) @@ -134,10 +134,11 @@ // FIXME BufferView creation should be independant of WorkArea creation buffer_views_[id].reset(new BufferView); work_areas_[id]->setBufferView(buffer_views_[id].get()); + view->setWorkArea(work_areas_[id]); + view->initTab(work_areas_[id]); + work_areas_[id]->setFocus(); - view->setCentralWidget(work_areas_[id]); - return id; } Index: src/frontends/qt4/GuiView.C =================================================================== --- src/frontends/qt4/GuiView.C (revision 15620) +++ src/frontends/qt4/GuiView.C (working copy) @@ -39,6 +39,8 @@ #include "session.h" #include "lyxfunc.h" #include "MenuBackend.h" +#include "buffer.h" +#include "bufferlist.h" #include <QAction> #include <QApplication> @@ -54,6 +56,8 @@ using std::string; using std::vector; +using lyx::support::onlyFilename; + namespace lyx { using support::subst; @@ -68,8 +72,38 @@ } // namespace anon +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); + } +}; + +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); @@ -91,6 +125,7 @@ GuiView::~GuiView() { + delete &d; } @@ -230,7 +265,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: src/frontends/LyXView.C =================================================================== --- src/frontends/LyXView.C (revision 15620) +++ src/frontends/LyXView.C (working copy) @@ -131,6 +131,7 @@ updateLayoutChoice(); updateWindowTitle(); updateStatusBar(); + updateTab(); busy(false); work_area_->redraw(); } @@ -149,6 +150,7 @@ updateToolbars(); updateLayoutChoice(); updateWindowTitle(); + updateTab(); if (loaded) { connectBuffer(*work_area_->bufferView().buffer()); showErrorList("Parse");