Add tab support

frontends/LyXView.h
	- add tab update function 
	
frontends/qt4/GuiView.h
	- add tab update function
	- add function for setting up the tabs
	- add slot for the tab clicks
	- add pimpl
	
frontends/qt4/GuiImplementation.C
	- don't set the buffer as central widget 
	  but initilize the tabs
	  
frontends/qt4/GuiView.C
	- use QTabBar for switching
	- scan the bufferlist on updates
	
frontends/LyXView.C
	- also update the tabs
	


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15637 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Peter Kümmel 2006-10-31 14:12:46 +00:00
parent b15b581f57
commit 8669b0087e
5 changed files with 169 additions and 4 deletions

View File

@ -131,6 +131,7 @@ void LyXView::setBuffer(Buffer * b)
updateLayoutChoice(); updateLayoutChoice();
updateWindowTitle(); updateWindowTitle();
updateStatusBar(); updateStatusBar();
updateTab();
busy(false); busy(false);
work_area_->redraw(); work_area_->redraw();
} }
@ -149,6 +150,7 @@ bool LyXView::loadLyXFile(string const & filename, bool tolastfiles)
updateToolbars(); updateToolbars();
updateLayoutChoice(); updateLayoutChoice();
updateWindowTitle(); updateWindowTitle();
updateTab();
if (loaded) { if (loaded) {
connectBuffer(*work_area_->bufferView().buffer()); connectBuffer(*work_area_->bufferView().buffer());
showErrorList("Parse"); showErrorList("Parse");

View File

@ -153,6 +153,9 @@ public:
/// updates the title of the window /// updates the title of the window
void updateWindowTitle(); void updateWindowTitle();
/// updates the tab view
virtual void updateTab() = 0;
/// reset autosave timer /// reset autosave timer
void resetAutosaveTimer(); void resetAutosaveTimer();

View File

@ -134,9 +134,10 @@ int GuiImplementation::newWorkArea(unsigned int w, unsigned int h, int view_id)
// FIXME BufferView creation should be independant of WorkArea creation // FIXME BufferView creation should be independant of WorkArea creation
buffer_views_[id].reset(new BufferView); buffer_views_[id].reset(new BufferView);
work_areas_[id]->setBufferView(buffer_views_[id].get()); work_areas_[id]->setBufferView(buffer_views_[id].get());
view->setWorkArea(work_areas_[id]);
view->setCentralWidget(work_areas_[id]); view->setWorkArea(work_areas_[id]);
view->initTab(work_areas_[id]);
work_areas_[id]->setFocus();
return id; return id;
} }

View File

@ -39,6 +39,8 @@
#include "session.h" #include "session.h"
#include "lyxfunc.h" #include "lyxfunc.h"
#include "MenuBackend.h" #include "MenuBackend.h"
#include "buffer.h"
#include "bufferlist.h"
#include <QAction> #include <QAction>
#include <QApplication> #include <QApplication>
@ -54,6 +56,8 @@ using std::endl;
using std::string; using std::string;
using std::vector; using std::vector;
using lyx::support::onlyFilename;
namespace lyx { namespace lyx {
using support::subst; using support::subst;
@ -68,8 +72,38 @@ int const statusbar_timer_value = 3000;
} // namespace anon } // 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) 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_DeleteOnClose, true);
setAttribute(Qt::WA_QuitOnClose, true); setAttribute(Qt::WA_QuitOnClose, true);
@ -91,6 +125,7 @@ GuiView::GuiView(int id)
GuiView::~GuiView() GuiView::~GuiView()
{ {
delete &d;
} }
@ -230,6 +265,123 @@ void GuiView::update_view_state_qt()
statusbar_timer_.stop(); 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() void GuiView::updateStatusBar()
{ {

View File

@ -26,7 +26,6 @@
#include <QCloseEvent> #include <QCloseEvent>
class QToolBar; class QToolBar;
//class FuncRequest; //class FuncRequest;
//class string; //class string;
@ -70,6 +69,8 @@ public:
virtual void clearMessage(); virtual void clearMessage();
virtual bool hasFocus() const; virtual bool hasFocus() const;
virtual void updateTab();
/// show - display the top-level window /// show - display the top-level window
void show(); void show();
@ -79,6 +80,7 @@ public:
/// menu item has been selected /// menu item has been selected
void activated(FuncRequest const &); void activated(FuncRequest const &);
void initTab(QWidget* workArea);
Q_SIGNALS: Q_SIGNALS:
void closing(int); void closing(int);
@ -90,6 +92,8 @@ public Q_SLOTS:
/// populate a toplevel menu and all its children on demand /// populate a toplevel menu and all its children on demand
void updateMenu(QAction *); void updateMenu(QAction *);
void currentTabChanged (int index);
protected: protected:
/// make sure we quit cleanly /// make sure we quit cleanly
virtual void closeEvent(QCloseEvent * e); virtual void closeEvent(QCloseEvent * e);
@ -120,6 +124,9 @@ private:
void updateFloatingGeometry(); void updateFloatingGeometry();
/// ///
QRect floatingGeometry_; QRect floatingGeometry_;
struct GuiViewPrivate;
GuiViewPrivate& d;
}; };
} // namespace frontend } // namespace frontend