File indexing completed on 2024-11-24 04:34:22
0001 /*************************************************************************** 0002 * SPDX-License-Identifier: GPL-2.0-or-later 0003 * * 0004 * SPDX-FileCopyrightText: 2004-2023 Thomas Fischer <fischer@unix-ag.uni-kl.de> 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 * This program is distributed in the hope that it will be useful, * 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0014 * GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License * 0017 * along with this program; if not, see <https://www.gnu.org/licenses/>. * 0018 ***************************************************************************/ 0019 0020 #include "hidingtabwidget.h" 0021 0022 #include <QSet> 0023 0024 typedef struct { 0025 /// the hidden widget 0026 QWidget *widget; 0027 /// the hidden widget's neighboring widgets, 0028 /// used to find a place where to insert the tab when it will be shown again. 0029 QWidget *leftNeighborWidget, *rightNeighborWidget; 0030 /// tab properties 0031 QIcon icon; 0032 QString label; 0033 bool enabled; 0034 QString toolTip; 0035 QString whatsThis; 0036 } HiddenTabInfo; 0037 0038 class HidingTabWidget::Private { 0039 private: 0040 HidingTabWidget *parent; 0041 QTabWidget *parentAsQTabWidget; 0042 0043 public: 0044 QSet<HiddenTabInfo> hiddenTabInfo; 0045 0046 Private(HidingTabWidget *_parent) 0047 : parent(_parent), parentAsQTabWidget(qobject_cast<QTabWidget *>(_parent)) 0048 { 0049 /// nothing 0050 } 0051 0052 int showTab(const HiddenTabInfo &hti, int index = InvalidTabPosition) 0053 { 0054 if (index <0) { 0055 /// No position to insert tab given, so make an educated guess 0056 index = parent->count(); ///< Append at end of tab row by default 0057 int i = InvalidTabPosition; 0058 if ((i = parent->indexOf(hti.leftNeighborWidget)) >= 0) 0059 index = i + 1; ///< Right of left neighbor 0060 else if ((i = parent->indexOf(hti.rightNeighborWidget)) >= 0) 0061 index = i; ///< Left of right neighbor 0062 } 0063 0064 /// Insert tab using QTabWidget's original function 0065 index = parentAsQTabWidget->insertTab(index, hti.widget, hti.icon, hti.label); 0066 /// Restore tab's properties 0067 parent->setTabToolTip(index, hti.toolTip); 0068 parent->setTabWhatsThis(index, hti.whatsThis); 0069 parent->setTabEnabled(index, hti.enabled); 0070 0071 return index; 0072 } 0073 }; 0074 0075 0076 /// required to for QSet<HiddenTabInfo> 0077 uint qHash(const HiddenTabInfo &hti) 0078 { 0079 return qHash(hti.widget); 0080 } 0081 0082 /// required to for QSet<HiddenTabInfo> 0083 bool operator==(const HiddenTabInfo &a, const HiddenTabInfo &b) 0084 { 0085 return a.widget == b.widget; 0086 } 0087 0088 const int HidingTabWidget::InvalidTabPosition = -1; 0089 0090 HidingTabWidget::HidingTabWidget(QWidget *parent) 0091 : QTabWidget(parent), d(new Private(this)) 0092 { 0093 /// nothing to see here 0094 } 0095 0096 HidingTabWidget::~HidingTabWidget() 0097 { 0098 delete d; 0099 } 0100 0101 QWidget *HidingTabWidget::hideTab(int index) 0102 { 0103 if (index < 0 || index >= count()) return nullptr; 0104 0105 HiddenTabInfo hti; 0106 hti.widget = widget(index); 0107 hti.leftNeighborWidget = index > 0 ? widget(index - 1) : nullptr; 0108 hti.rightNeighborWidget = index < count() - 1 ? widget(index + 1) : nullptr; 0109 hti.label = tabText(index); 0110 hti.icon = tabIcon(index); 0111 hti.enabled = isTabEnabled(index); 0112 hti.toolTip = tabToolTip(index); 0113 hti.whatsThis = tabWhatsThis(index); 0114 d->hiddenTabInfo.insert(hti); 0115 0116 QTabWidget::removeTab(index); 0117 0118 return hti.widget; 0119 } 0120 0121 int HidingTabWidget::showTab(QWidget *page) 0122 { 0123 for (const HiddenTabInfo &hti : const_cast<const QSet<HiddenTabInfo> &>(d->hiddenTabInfo)) { 0124 if (hti.widget == page) 0125 return d->showTab(hti); 0126 } 0127 0128 return InvalidTabPosition; 0129 } 0130 0131 void HidingTabWidget::removeTab(int index) 0132 { 0133 if (index >= 0 && index < count()) { 0134 QWidget *page = widget(index); 0135 for (const HiddenTabInfo &hti : const_cast<const QSet<HiddenTabInfo> &>(d->hiddenTabInfo)) { 0136 if (hti.widget == page) { 0137 d->hiddenTabInfo.remove(hti); 0138 break; 0139 } 0140 } 0141 QTabWidget::removeTab(index); 0142 } 0143 } 0144 0145 int HidingTabWidget::addTab(QWidget *page, const QString &label) 0146 { 0147 for (const HiddenTabInfo &hti : const_cast<const QSet<HiddenTabInfo> &>(d->hiddenTabInfo)) { 0148 if (hti.widget == page) { 0149 int pos = d->showTab(hti); 0150 setTabText(pos, label); 0151 return pos; 0152 } 0153 } 0154 0155 return QTabWidget::addTab(page, label); 0156 } 0157 0158 int HidingTabWidget::addTab(QWidget *page, const QIcon &icon, const QString &label) 0159 { 0160 for (const HiddenTabInfo &hti : const_cast<const QSet<HiddenTabInfo> &>(d->hiddenTabInfo)) { 0161 if (hti.widget == page) { 0162 int pos = d->showTab(hti); 0163 setTabIcon(pos, icon); 0164 setTabText(pos, label); 0165 return pos; 0166 } 0167 } 0168 0169 return QTabWidget::addTab(page, icon, label); 0170 } 0171 0172 int HidingTabWidget::insertTab(int index, QWidget *page, const QString &label) 0173 { 0174 for (const HiddenTabInfo &hti : const_cast<const QSet<HiddenTabInfo> &>(d->hiddenTabInfo)) { 0175 if (hti.widget == page) { 0176 int pos = d->showTab(hti, index); 0177 setTabText(pos, label); 0178 return pos; 0179 } 0180 } 0181 0182 return QTabWidget::insertTab(index, page, label); 0183 } 0184 0185 int HidingTabWidget::insertTab(int index, QWidget *page, const QIcon &icon, const QString &label) 0186 { 0187 for (const HiddenTabInfo &hti : const_cast<const QSet<HiddenTabInfo> &>(d->hiddenTabInfo)) { 0188 if (hti.widget == page) { 0189 index = d->showTab(hti, index); 0190 setTabIcon(index, icon); 0191 setTabText(index, label); 0192 return index; 0193 } 0194 } 0195 0196 return QTabWidget::insertTab(index, page, icon, label); 0197 } 0198 0199 bool HidingTabWidget::tabIsShown(QWidget *page) const 0200 { 0201 for (int i = 0; i < count(); ++i) 0202 if (widget(i) == page) 0203 return true; 0204 return false; 0205 }