text: /****************************************************************************
  **
  ** Copyright (C) 2016 The Qt Company Ltd.
  ** Contact: https://www.qt.io/licensing/
  **
  ** This file is part of the test suite of the Qt Toolkit.
  **
  ** $QT_BEGIN_LICENSE:BSD$
  ** Commercial License Usage
  ** Licensees holding valid commercial Qt licenses may use this file in
  ** accordance with the commercial license agreement provided with the
  ** Software or, alternatively, in accordance with the terms contained in
  ** a written agreement between you and The Qt Company. For licensing terms
  ** and conditions see https://www.qt.io/terms-conditions. For further
  ** information use the contact form at https://www.qt.io/contact-us.
  **
  ** BSD License Usage
  ** Alternatively, you may use this file under the terms of the BSD license
  ** as follows:
  **
  ** "Redistribution and use in source and binary forms, with or without
  ** modification, are permitted provided that the following conditions are
  ** met:
  **   * Redistributions of source code must retain the above copyright
  **     notice, this list of conditions and the following disclaimer.
  **   * Redistributions in binary form must reproduce the above copyright
  **     notice, this list of conditions and the following disclaimer in
  **     the documentation and/or other materials provided with the
  **     distribution.
  **   * Neither the name of The Qt Company Ltd nor the names of its
  **     contributors may be used to endorse or promote products derived
  **     from this software without specific prior written permission.
  **
  **
  ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  **
  ** $QT_END_LICENSE$
  **
  ****************************************************************************/
  
  #include <QApplication>
  #include <QWidget>
  #include <QStackedWidget>
  #include <QTabBar>
  #include <QLabel>
  #include <QLayout>
  #include <QDesktopWidget>
  #include <QTabWidget>
  #include <QProxyStyle>
  #include <qdebug.h>
  #include "tabbarform.h"
  
  class TabBarProxyStyle : public QProxyStyle
  {
  public:
      TabBarProxyStyle() : QProxyStyle(), alignment(Qt::AlignLeft)
      { }
  
      int styleHint(StyleHint hint, const QStyleOption *option = 0,
                    const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const
      {
          if (hint == QStyle::SH_TabBar_Alignment)
              return alignment;
  
          return QProxyStyle::styleHint(hint, option, widget, returnData);
      }
  
      Qt::Alignment alignment;
  };
  
  const int TabCount = 5;
  
  int main(int argc, char *argv[])
  {
      QApplication app(argc, argv);
      auto *proxyStyle = new TabBarProxyStyle;
      app.setStyle(proxyStyle);
  
      QWidget widget;
      QStackedWidget stackedWidget;
      QTabBar tabBar;
      tabBar.setDocumentMode(true);
      tabBar.setTabsClosable(true);
      tabBar.setMovable(true);
      tabBar.setExpanding(false);
  
      // top
      tabBar.setShape(QTabBar::RoundedNorth);
      // bottom
  //    tabBar.setShape(QTabBar::RoundedSouth);
      // left
  //    tabBar.setShape(QTabBar::RoundedWest);
      // right
  //    tabBar.setShape(QTabBar::RoundedEast);
  
      const auto shortLabel = QStringLiteral("Tab %1");
      const auto longLabel = QStringLiteral("An Extremely Long Tab Label %1");
  
      QMap<int, QWidget*> tabs;
      for (int i = 0; i < TabCount; i++) {
          QString tabNumberString = QString::number(i);
          QLabel *label = new QLabel(QStringLiteral("Tab %1 content").arg(tabNumberString));
          tabs[i] = label;
          label->setAlignment(Qt::AlignCenter);
          stackedWidget.addWidget(label);
          tabBar.addTab(shortLabel.arg(tabNumberString));
      }
  
      QObject::connect(&tabBar, &QTabBar::tabMoved, [&tabs](int from, int to) {
          QWidget *thisWidget = tabs[from];
          QWidget *thatWidget = tabs[to];
          tabs[from] = thatWidget;
          tabs[to] = thisWidget;
      });
  
      QObject::connect(&tabBar, &QTabBar::currentChanged, [&stackedWidget, &tabs](int index) {
          if (index >= 0)
              stackedWidget.setCurrentWidget(tabs[index]);
      });
  
      QObject::connect(&tabBar, &QTabBar::tabCloseRequested, [&stackedWidget, &tabBar, &tabs](int index) {
          QWidget *widget = tabs[index];
          tabBar.removeTab(index);
          for (int i = index + 1; i < TabCount; i++)
              tabs[i-1] = tabs[i];
          int currentIndex = tabBar.currentIndex();
          if (currentIndex >= 0)
              stackedWidget.setCurrentWidget(tabs[currentIndex]);
          delete widget;
      });
  
      QLayout *layout;
      switch (tabBar.shape()) {
      case QTabBar::RoundedEast:
      case QTabBar::TriangularEast:
          tabBar.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
          layout = new QHBoxLayout(&widget);
          layout->addWidget(&stackedWidget);
          layout->addWidget(&tabBar);
          break;
      case QTabBar::RoundedWest:
      case QTabBar::TriangularWest:
          tabBar.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
          layout = new QHBoxLayout(&widget);
          layout->addWidget(&tabBar);
          layout->addWidget(&stackedWidget);
          break;
      case QTabBar::RoundedNorth:
      case QTabBar::TriangularNorth:
          tabBar.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
          layout = new QVBoxLayout(&widget);
          layout->addWidget(&tabBar);
          layout->addWidget(&stackedWidget);
          break;
      case QTabBar::RoundedSouth:
      case QTabBar::TriangularSouth:
          tabBar.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
          layout = new QVBoxLayout(&widget);
          layout->addWidget(&stackedWidget);
          layout->addWidget(&tabBar);
          break;
      }
  
      TabBarForm form;
      layout->addWidget(&form);
      layout->setAlignment(&form, Qt::AlignHCenter);
  
      form.ui->documentModeButton->setChecked(tabBar.documentMode());
      QObject::connect(form.ui->documentModeButton, &QCheckBox::toggled, [&] {
          tabBar.setDocumentMode(form.ui->documentModeButton->isChecked());
          // QMacStyle (and maybe other styles) requires a re-polish to get the right font
          QApplication::sendEvent(&tabBar, new QEvent(QEvent::ThemeChange));
      });
  
      form.ui->movableTabsButton->setChecked(tabBar.isMovable());
      QObject::connect(form.ui->movableTabsButton, &QCheckBox::toggled, [&] {
          tabBar.setMovable(form.ui->movableTabsButton->isChecked());
          tabBar.update();
      });
  
      form.ui->closableTabsButton->setChecked(tabBar.tabsClosable());
      QObject::connect(form.ui->closableTabsButton, &QCheckBox::toggled, [&] {
          tabBar.setTabsClosable(form.ui->closableTabsButton->isChecked());
          tabBar.update();
      });
  
      form.ui->expandingTabsButton->setChecked(tabBar.expanding());
      QObject::connect(form.ui->expandingTabsButton, &QCheckBox::toggled, [&] {
          tabBar.setExpanding(form.ui->expandingTabsButton->isChecked());
          tabBar.update();
      });
  
      form.ui->displayIconButton->setChecked(!tabBar.tabIcon(0).isNull());
      QObject::connect(form.ui->displayIconButton, &QCheckBox::toggled, [&] {
          const auto icon = form.ui->displayIconButton->isChecked() ?
                            tabBar.style()->standardIcon(QStyle::SP_ComputerIcon) : QIcon();
          for (int i = 0; i < tabBar.count(); i++)
              tabBar.setTabIcon(i, icon);
      });
  
      form.ui->longLabelButton->setChecked(false);
      QObject::connect(form.ui->longLabelButton, &QCheckBox::toggled, [&] {
          const auto &label = form.ui->longLabelButton->isChecked() ? longLabel : shortLabel;
          for (int i = 0; i < tabBar.count(); i++)
              tabBar.setTabText(i, label.arg(i));
      });
  
      QObject::connect(form.ui->shapeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [&](int index) {
          Q_UNUSED(index);
          // TODO
      });
  
      if (proxyStyle->alignment == Qt::AlignLeft)
          form.ui->leftAlignedButton->setChecked(true);
      else if (proxyStyle->alignment == Qt::AlignRight)
          form.ui->rightAlignedButton->setChecked(true);
      else
          form.ui->centeredButton->setChecked(true);
      QObject::connect(form.ui->textAlignmentGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), [&](QAbstractButton *b) {
          proxyStyle->alignment = b == form.ui->leftAlignedButton ? Qt::AlignLeft :
                                  b == form.ui->rightAlignedButton ? Qt::AlignRight : Qt::AlignCenter;
          QApplication::sendEvent(&tabBar, new QEvent(QEvent::StyleChange));
      });
  
      layout->setMargin(12);
      widget.show();
  
      return app.exec();
  }
  