2
* psitabwidget.cpp - Customised QTabWidget for Psi
3
* Copyright (C) 2006 Kevin Smith
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include "psitabwidget.h"
22
#include "psitabbar.h"
24
#include <QVBoxLayout>
25
#include <QHBoxLayout>
26
#include <QToolButton>
27
#include <QStackedLayout>
29
#include <QApplication>
36
PsiTabWidget::PsiTabWidget(QWidget *parent) : QWidget(parent)
37
//: QTabWidget(parent)
39
tabsPosition_ = QTabWidget::East; // impossible => uninitialised state
40
tabBar_ = new PsiTabBar(this);
41
tabBar_->setUsesScrollButtons(true);
42
layout_ = new QVBoxLayout(this);
43
layout_->setMargin(0);
44
layout_->setSpacing(0);
45
barLayout_ = new QHBoxLayout(layout_);
46
barLayout_->setMargin(0);
47
barLayout_->setSpacing(0);
48
barLayout_->addWidget(tabBar_, 2);
49
barLayout_->setAlignment(Qt::AlignLeft);
51
int buttonwidth = qMax(tabBar_->style()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, tabBar_),
52
QApplication::globalStrut().width());
54
downButton_ = new QToolButton(this);
55
downButton_->setMinimumSize(3,3);
56
downButton_->setFixedWidth(buttonwidth);
57
downButton_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
58
menu_ = new QMenu(this);
59
downButton_->setMenu(menu_);
60
connect(menu_, SIGNAL(aboutToShow()), SLOT(menu_aboutToShow()));
61
connect(menu_, SIGNAL(triggered(QAction*)), SLOT(menu_triggered(QAction*)));
62
barLayout_->add(downButton_);
64
closeButton_ = new QToolButton(this);
65
closeButton_->setMinimumSize(3,3);
66
closeButton_->setFixedWidth(buttonwidth);
67
closeButton_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
68
barLayout_->add(closeButton_);
69
closeButton_->setText("x");
70
downButton_->setArrowType(Qt::DownArrow);
71
downButton_->setPopupMode(QToolButton::InstantPopup);
72
stacked_ = new QStackedLayout(layout_);
74
setTabPosition(QTabWidget::Top);
76
connect( tabBar_, SIGNAL(mouseDoubleClickTab(int)), SLOT(mouseDoubleClickTab(int)));
77
connect( tabBar_, SIGNAL( currentChanged(int)), SLOT(tab_currentChanged(int)));
78
connect( tabBar_, SIGNAL( contextMenu(QContextMenuEvent*,int)), SLOT( tab_contextMenu(QContextMenuEvent*,int)));
79
connect( closeButton_, SIGNAL(clicked()), SIGNAL(closeButtonClicked()));
82
void PsiTabWidget::setCloseIcon(const QIcon& icon) {
83
closeButton_->setIcon(icon);
84
closeButton_->setText("");
90
PsiTabWidget::~PsiTabWidget()
96
* Set the color of text on a tab.
97
* \param tab Widget for the tab to change.
98
* \param color Color to set text.
100
void PsiTabWidget::setTabTextColor( QWidget* tab, const QColor& color)
102
for (int i=0; i < count(); i++) {
103
if ( widget(i) == tab ) {
104
tabBar_->setTabTextColor(i,color);
110
* Returns the specified widget.
111
* \param index Widget to return.
112
* \return Specified widget.
114
QWidget* PsiTabWidget::widget(int index)
116
return widgets_[index];
119
void PsiTabWidget::mouseDoubleClickTab( int tab )
121
emit mouseDoubleClickTab(widget(tab));
125
* Number of tabs/widgets
127
int PsiTabWidget::count()
129
return tabBar_->count();
133
* Returns the widget of the current page
135
QWidget* PsiTabWidget::currentPage()
137
return widgets_[currentPageIndex()];
140
void PsiTabWidget::tab_currentChanged( int tab )
142
// qt 4.4 sends -1 i case of an empty QTabbar, ignore that case.
143
if (tab == -1) return;
145
emit currentChanged(currentPage());
150
* Returns the index of the current page
152
int PsiTabWidget::currentPageIndex()
154
return tabBar_->currentIndex();
158
* Add the Widget to the tab stack.
160
void PsiTabWidget::addTab(QWidget* widget, QString name)
163
if (widgets_.contains(widget)) {
166
widgets_.append(widget);
167
stacked_->addWidget(widget);
168
tabBar_->addTab(name);
169
showPage(currentPage());
173
* Selects the page for the specified widget.
175
void PsiTabWidget::showPage(QWidget* widget) {
176
for (int i=0; i < count(); i++) {
177
if (widgets_[i] == widget) {
178
showPageDirectly(widget);
179
tabBar_->setCurrentIndex(i);
186
* Selects the page for the specified widget (internal helper).
188
void PsiTabWidget::showPageDirectly(QWidget* widget) {
189
// FIXME move this back into showPage? should this be in the public interface?
190
for (int i=0; i < count(); i++) {
191
if (widgets_[i] == widget) {
192
stacked_->setCurrentWidget(widget);
193
// currentChanged is handled by tabBar_
200
* Removes the page for the specified widget.
202
void PsiTabWidget::removePage(QWidget* widget) {
203
for (int i=0; i < count(); i++) {
204
if (widgets_[i] == widget) {
205
stacked_->removeWidget(widget);
207
tabBar_->removeTab(i);
208
// tabBar_ emits current changed if needed
214
* Finds the index of the widget (or -1 if missing).
216
int PsiTabWidget::getIndex(QWidget* widget) {
217
for (int i = 0; i < count(); i++) {
218
if (widgets_[i] == widget) {
226
* Set the text of the tab.
228
void PsiTabWidget::setTabLabel(QWidget* widget, const QString& label) {
229
int index = getIndex(widget);
233
tabBar_->setTabText(index, label);
236
void PsiTabWidget::setCurrentPage(int index) {
237
Q_ASSERT(index >=0 && index < count());
238
showPage(widgets_[index]);
241
void PsiTabWidget::removeCurrentPage() {
242
removePage(currentPage());
245
void PsiTabWidget::setTabPosition(QTabWidget::TabPosition pos)
247
if (tabsPosition_ == pos) return;
250
tabBar_->setShape(tabsPosition_ == QTabWidget::Top ? QTabBar::RoundedNorth : QTabBar::RoundedSouth);
252
layout_->removeItem(barLayout_);
253
layout_->removeItem(stacked_);
255
// addLayout sets parent and complains if it's already set
256
barLayout_->setParent(0);
257
stacked_->setParent(0);
258
if (tabsPosition_ == QTabWidget::Top) {
259
layout_->addLayout(barLayout_);
260
layout_->addLayout(stacked_);
262
layout_->addLayout(stacked_);
263
layout_->addLayout(barLayout_);
267
void PsiTabWidget::menu_aboutToShow()
271
for (int i=0; i < tabBar_->count(); i++) {
272
QRect r = tabBar_->tabRect(i);
273
bool newvis = tabBar_->rect().contains(r);
275
menu_->addSeparator ();
278
menu_->addAction(tabBar_->tabText(i))->setData(i+1);
280
emit aboutToShowMenu(menu_);
283
void PsiTabWidget::menu_triggered(QAction *act)
285
int idx = act->data().toInt();
286
if (idx <= 0 || idx > tabBar_->count()) {
290
setCurrentPage(idx-1);
295
void PsiTabWidget::tab_contextMenu( QContextMenuEvent * event, int tab)
297
emit tabContextMenu(tab, tabBar_->mapToGlobal(event->pos()), event);
302
QWidget* PsiTabWidget::page(int index) {
303
Q_ASSERT(index >=0 && index < count());
304
return widgets_[index];