1333b2889SNicolas Bonnefon /* 245ef183cSNicolas Bonnefon * Copyright (C) 2014, 2015 Nicolas Bonnefon and other contributors 3333b2889SNicolas Bonnefon * 4333b2889SNicolas Bonnefon * This file is part of glogg. 5333b2889SNicolas Bonnefon * 6333b2889SNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify 7333b2889SNicolas Bonnefon * it under the terms of the GNU General Public License as published by 8333b2889SNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or 9333b2889SNicolas Bonnefon * (at your option) any later version. 10333b2889SNicolas Bonnefon * 11333b2889SNicolas Bonnefon * glogg is distributed in the hope that it will be useful, 12333b2889SNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of 13333b2889SNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14333b2889SNicolas Bonnefon * GNU General Public License for more details. 15333b2889SNicolas Bonnefon * 16333b2889SNicolas Bonnefon * You should have received a copy of the GNU General Public License 17333b2889SNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>. 18333b2889SNicolas Bonnefon */ 19333b2889SNicolas Bonnefon 20333b2889SNicolas Bonnefon #include "tabbedcrawlerwidget.h" 21333b2889SNicolas Bonnefon 22f88e59a4SNicolas Bonnefon #include <QKeyEvent> 234006f1beSNicolas Bonnefon #include <QLabel> 24f88e59a4SNicolas Bonnefon 2545ef183cSNicolas Bonnefon #include "crawlerwidget.h" 2645ef183cSNicolas Bonnefon 27333b2889SNicolas Bonnefon #include "log.h" 28333b2889SNicolas Bonnefon 297999f43eSNicolas Bonnefon TabbedCrawlerWidget::TabbedCrawlerWidget() : QTabWidget(), 30c633ced3SNicolas Bonnefon olddata_icon_( ":/images/olddata_icon.png" ), 31c633ced3SNicolas Bonnefon newdata_icon_( ":/images/newdata_icon.png" ), 32c633ced3SNicolas Bonnefon newfiltered_icon_( ":/images/newfiltered_icon.png" ), 337999f43eSNicolas Bonnefon myTabBar_() 34333b2889SNicolas Bonnefon { 359c01a031SNicolas Bonnefon #ifdef WIN32 36333b2889SNicolas Bonnefon myTabBar_.setStyleSheet( "QTabBar::tab {\ 37333b2889SNicolas Bonnefon height: 20px; " 384006f1beSNicolas Bonnefon "} " 394006f1beSNicolas Bonnefon "QTabBar::close-button {\ 404006f1beSNicolas Bonnefon height: 6px; width: 6px;\ 414006f1beSNicolas Bonnefon subcontrol-origin: padding;\ 424006f1beSNicolas Bonnefon subcontrol-position: left;\ 434006f1beSNicolas Bonnefon }" ); 44333b2889SNicolas Bonnefon #else 45333b2889SNicolas Bonnefon // On GTK style, it looks better with a smaller font 46333b2889SNicolas Bonnefon myTabBar_.setStyleSheet( 47333b2889SNicolas Bonnefon "QTabBar::tab {" 48333b2889SNicolas Bonnefon " height: 20px; " 49333b2889SNicolas Bonnefon " font-size: 9pt; " 50333b2889SNicolas Bonnefon "} " 51333b2889SNicolas Bonnefon "QTabBar::close-button {\ 524006f1beSNicolas Bonnefon height: 6px; width: 6px;\ 534006f1beSNicolas Bonnefon subcontrol-origin: padding;\ 544006f1beSNicolas Bonnefon subcontrol-position: left;\ 554006f1beSNicolas Bonnefon }" ); 56333b2889SNicolas Bonnefon #endif 57333b2889SNicolas Bonnefon setTabBar( &myTabBar_ ); 58333b2889SNicolas Bonnefon myTabBar_.hide(); 597999f43eSNicolas Bonnefon 60333b2889SNicolas Bonnefon } 61333b2889SNicolas Bonnefon 62333b2889SNicolas Bonnefon // I know hiding non-virtual functions from the base class is bad form 63333b2889SNicolas Bonnefon // and I do it here out of pure laziness: I don't want to encapsulate 64333b2889SNicolas Bonnefon // QTabBar with all signals and all just to implement this very simple logic. 65333b2889SNicolas Bonnefon // Maybe one day that should be done better... 66333b2889SNicolas Bonnefon 67333b2889SNicolas Bonnefon int TabbedCrawlerWidget::addTab( QWidget* page, const QString& label ) 68333b2889SNicolas Bonnefon { 69333b2889SNicolas Bonnefon int index = QTabWidget::addTab( page, label ); 70333b2889SNicolas Bonnefon 7145ef183cSNicolas Bonnefon if ( auto crawler = dynamic_cast<CrawlerWidget*>( page ) ) { 7245ef183cSNicolas Bonnefon // Mmmmhhhh... new Qt5 signal syntax create tight coupling between 7345ef183cSNicolas Bonnefon // us and the sender, baaaaad.... 7445ef183cSNicolas Bonnefon 7545ef183cSNicolas Bonnefon // Listen for a changing data status: 7645ef183cSNicolas Bonnefon connect( crawler, &CrawlerWidget::dataStatusChanged, 7745ef183cSNicolas Bonnefon [ this, index ]( DataStatus status ) { setTabDataStatus( index, status ); } ); 7845ef183cSNicolas Bonnefon } 7945ef183cSNicolas Bonnefon 804006f1beSNicolas Bonnefon // Display the icon 814006f1beSNicolas Bonnefon QLabel* icon_label = new QLabel(); 827999f43eSNicolas Bonnefon icon_label->setPixmap( olddata_icon_.pixmap( 11, 12 ) ); 834006f1beSNicolas Bonnefon icon_label->setAlignment( Qt::AlignCenter ); 844006f1beSNicolas Bonnefon myTabBar_.setTabButton( index, QTabBar::RightSide, icon_label ); 854006f1beSNicolas Bonnefon 86333b2889SNicolas Bonnefon LOG(logDEBUG) << "addTab, count = " << count(); 877999f43eSNicolas Bonnefon LOG(logDEBUG) << "width = " << olddata_icon_.pixmap( 11, 12 ).devicePixelRatio(); 88333b2889SNicolas Bonnefon 89333b2889SNicolas Bonnefon if ( count() > 1 ) 90333b2889SNicolas Bonnefon myTabBar_.show(); 91333b2889SNicolas Bonnefon 92333b2889SNicolas Bonnefon return index; 93333b2889SNicolas Bonnefon } 94333b2889SNicolas Bonnefon 95333b2889SNicolas Bonnefon void TabbedCrawlerWidget::removeTab( int index ) 96333b2889SNicolas Bonnefon { 97333b2889SNicolas Bonnefon QTabWidget::removeTab( index ); 98333b2889SNicolas Bonnefon 99333b2889SNicolas Bonnefon if ( count() <= 1 ) 100333b2889SNicolas Bonnefon myTabBar_.hide(); 101333b2889SNicolas Bonnefon } 102f88e59a4SNicolas Bonnefon 103045bfe08SGustav Andersson void TabbedCrawlerWidget::mouseReleaseEvent( QMouseEvent *event) 104045bfe08SGustav Andersson { 105045bfe08SGustav Andersson LOG(logDEBUG) << "TabbedCrawlerWidget::mouseReleaseEvent"; 106045bfe08SGustav Andersson 107045bfe08SGustav Andersson if (event->button() == Qt::MidButton) 108045bfe08SGustav Andersson { 109045bfe08SGustav Andersson int tab = this->myTabBar_.tabAt( event->pos() ); 110045bfe08SGustav Andersson if (-1 != tab) 111045bfe08SGustav Andersson { 112045bfe08SGustav Andersson emit tabCloseRequested( tab ); 113045bfe08SGustav Andersson } 114045bfe08SGustav Andersson } 115045bfe08SGustav Andersson } 116045bfe08SGustav Andersson 117f88e59a4SNicolas Bonnefon void TabbedCrawlerWidget::keyPressEvent( QKeyEvent* event ) 118f88e59a4SNicolas Bonnefon { 119*a9518197SNicolas Bonnefon const auto mod = event->modifiers(); 120*a9518197SNicolas Bonnefon const auto key = event->key(); 121*a9518197SNicolas Bonnefon 122f88e59a4SNicolas Bonnefon LOG(logDEBUG) << "TabbedCrawlerWidget::keyPressEvent"; 123f88e59a4SNicolas Bonnefon 124f88e59a4SNicolas Bonnefon // Ctrl + tab 125*a9518197SNicolas Bonnefon if ( ( mod == Qt::ControlModifier && key == Qt::Key_Tab ) || 126*a9518197SNicolas Bonnefon ( mod == ( Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier ) && key == Qt::Key_Right ) ) { 127f88e59a4SNicolas Bonnefon setCurrentIndex( ( currentIndex() + 1 ) % count() ); 128f88e59a4SNicolas Bonnefon } 129f88e59a4SNicolas Bonnefon // Ctrl + shift + tab 130*a9518197SNicolas Bonnefon else if ( ( mod == ( Qt::ControlModifier | Qt::ShiftModifier ) && key == Qt::Key_Tab ) || 131*a9518197SNicolas Bonnefon ( mod == ( Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier ) && key == Qt::Key_Left ) ) { 132*a9518197SNicolas Bonnefon setCurrentIndex( ( currentIndex() - 1 >= 0 ) ? currentIndex() - 1 : count() - 1 ); 133f88e59a4SNicolas Bonnefon } 134d73b7073SNicolas Bonnefon // Ctrl + numbers 135*a9518197SNicolas Bonnefon else if ( mod == Qt::ControlModifier && ( key >= Qt::Key_1 && key <= Qt::Key_8 ) ) { 136*a9518197SNicolas Bonnefon int new_index = key - Qt::Key_0; 137f88e59a4SNicolas Bonnefon if ( new_index <= count() ) 138f88e59a4SNicolas Bonnefon setCurrentIndex( new_index - 1 ); 139f88e59a4SNicolas Bonnefon } 140d73b7073SNicolas Bonnefon // Ctrl + 9 141*a9518197SNicolas Bonnefon else if ( mod == Qt::ControlModifier && key == Qt::Key_9 ) { 142f88e59a4SNicolas Bonnefon setCurrentIndex( count() - 1 ); 143f88e59a4SNicolas Bonnefon } 144*a9518197SNicolas Bonnefon else if ( mod == Qt::ControlModifier && (key == Qt::Key_Q || key == Qt::Key_W) ) { 145d73b7073SNicolas Bonnefon emit tabCloseRequested( currentIndex() ); 146d73b7073SNicolas Bonnefon } 147f88e59a4SNicolas Bonnefon else { 148f88e59a4SNicolas Bonnefon QTabWidget::keyPressEvent( event ); 149f88e59a4SNicolas Bonnefon } 150f88e59a4SNicolas Bonnefon } 1514006f1beSNicolas Bonnefon 1524006f1beSNicolas Bonnefon void TabbedCrawlerWidget::setTabDataStatus( int index, DataStatus status ) 1534006f1beSNicolas Bonnefon { 1547999f43eSNicolas Bonnefon LOG(logDEBUG) << "TabbedCrawlerWidget::setTabDataStatus " << index; 15545ef183cSNicolas Bonnefon 1564006f1beSNicolas Bonnefon QLabel* icon_label = dynamic_cast<QLabel*>( 1574006f1beSNicolas Bonnefon myTabBar_.tabButton( index, QTabBar::RightSide ) ); 1584006f1beSNicolas Bonnefon 1594006f1beSNicolas Bonnefon if ( icon_label ) { 1607999f43eSNicolas Bonnefon const QIcon* icon; 1614006f1beSNicolas Bonnefon switch ( status ) { 1624006f1beSNicolas Bonnefon case DataStatus::OLD_DATA: 1637999f43eSNicolas Bonnefon icon = &olddata_icon_; 1644006f1beSNicolas Bonnefon break; 1654006f1beSNicolas Bonnefon case DataStatus::NEW_DATA: 1667999f43eSNicolas Bonnefon icon = &newdata_icon_; 1674006f1beSNicolas Bonnefon break; 1684006f1beSNicolas Bonnefon case DataStatus::NEW_FILTERED_DATA: 1697999f43eSNicolas Bonnefon icon = &newfiltered_icon_; 1704006f1beSNicolas Bonnefon break; 1714006f1beSNicolas Bonnefon } 1727999f43eSNicolas Bonnefon icon_label->setPixmap ( icon->pixmap(12,12) ); 1734006f1beSNicolas Bonnefon } 1744006f1beSNicolas Bonnefon } 175