1 /* 2 * Copyright (C) 2014, 2015 Nicolas Bonnefon and other contributors 3 * 4 * This file is part of glogg. 5 * 6 * glogg is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * glogg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with glogg. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "tabbedcrawlerwidget.h" 21 22 #include <QKeyEvent> 23 #include <QLabel> 24 25 #include "crawlerwidget.h" 26 27 #include "log.h" 28 29 TabbedCrawlerWidget::TabbedCrawlerWidget() : QTabWidget(), 30 olddata_icon_( ":/images/olddata_icon.png" ), 31 newdata_icon_( ":/images/newdata_icon.png" ), 32 newfiltered_icon_( ":/images/newfiltered_icon.png" ), 33 myTabBar_() 34 { 35 #ifdef WIN32 36 myTabBar_.setStyleSheet( "QTabBar::tab {\ 37 height: 20px; " 38 "} " 39 "QTabBar::close-button {\ 40 height: 6px; width: 6px;\ 41 subcontrol-origin: padding;\ 42 subcontrol-position: left;\ 43 }" ); 44 #else 45 // On GTK style, it looks better with a smaller font 46 myTabBar_.setStyleSheet( 47 "QTabBar::tab {" 48 " height: 20px; " 49 " font-size: 9pt; " 50 "} " 51 "QTabBar::close-button {\ 52 height: 6px; width: 6px;\ 53 subcontrol-origin: padding;\ 54 subcontrol-position: left;\ 55 }" ); 56 #endif 57 setTabBar( &myTabBar_ ); 58 myTabBar_.hide(); 59 60 } 61 62 // I know hiding non-virtual functions from the base class is bad form 63 // and I do it here out of pure laziness: I don't want to encapsulate 64 // QTabBar with all signals and all just to implement this very simple logic. 65 // Maybe one day that should be done better... 66 67 int TabbedCrawlerWidget::addTab( QWidget* page, const QString& label ) 68 { 69 int index = QTabWidget::addTab( page, label ); 70 71 if ( auto crawler = dynamic_cast<CrawlerWidget*>( page ) ) { 72 // Mmmmhhhh... new Qt5 signal syntax create tight coupling between 73 // us and the sender, baaaaad.... 74 75 // Listen for a changing data status: 76 connect( crawler, &CrawlerWidget::dataStatusChanged, 77 [ this, index ]( DataStatus status ) { setTabDataStatus( index, status ); } ); 78 } 79 80 // Display the icon 81 QLabel* icon_label = new QLabel(); 82 icon_label->setPixmap( olddata_icon_.pixmap( 11, 12 ) ); 83 icon_label->setAlignment( Qt::AlignCenter ); 84 myTabBar_.setTabButton( index, QTabBar::RightSide, icon_label ); 85 86 LOG(logDEBUG) << "addTab, count = " << count(); 87 LOG(logDEBUG) << "width = " << olddata_icon_.pixmap( 11, 12 ).devicePixelRatio(); 88 89 if ( count() > 1 ) 90 myTabBar_.show(); 91 92 return index; 93 } 94 95 void TabbedCrawlerWidget::removeTab( int index ) 96 { 97 QTabWidget::removeTab( index ); 98 99 if ( count() <= 1 ) 100 myTabBar_.hide(); 101 } 102 103 void TabbedCrawlerWidget::mouseReleaseEvent( QMouseEvent *event) 104 { 105 LOG(logDEBUG) << "TabbedCrawlerWidget::mouseReleaseEvent"; 106 107 if (event->button() == Qt::MidButton) 108 { 109 int tab = this->myTabBar_.tabAt( event->pos() ); 110 if (-1 != tab) 111 { 112 emit tabCloseRequested( tab ); 113 } 114 } 115 } 116 117 void TabbedCrawlerWidget::keyPressEvent( QKeyEvent* event ) 118 { 119 const auto mod = event->modifiers(); 120 const auto key = event->key(); 121 122 LOG(logDEBUG) << "TabbedCrawlerWidget::keyPressEvent"; 123 124 // Ctrl + tab 125 if ( ( mod == Qt::ControlModifier && key == Qt::Key_Tab ) || 126 ( mod == ( Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier ) && key == Qt::Key_Right ) ) { 127 setCurrentIndex( ( currentIndex() + 1 ) % count() ); 128 } 129 // Ctrl + shift + tab 130 else if ( ( mod == ( Qt::ControlModifier | Qt::ShiftModifier ) && key == Qt::Key_Tab ) || 131 ( mod == ( Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier ) && key == Qt::Key_Left ) ) { 132 setCurrentIndex( ( currentIndex() - 1 >= 0 ) ? currentIndex() - 1 : count() - 1 ); 133 } 134 // Ctrl + numbers 135 else if ( mod == Qt::ControlModifier && ( key >= Qt::Key_1 && key <= Qt::Key_8 ) ) { 136 int new_index = key - Qt::Key_0; 137 if ( new_index <= count() ) 138 setCurrentIndex( new_index - 1 ); 139 } 140 // Ctrl + 9 141 else if ( mod == Qt::ControlModifier && key == Qt::Key_9 ) { 142 setCurrentIndex( count() - 1 ); 143 } 144 else if ( mod == Qt::ControlModifier && (key == Qt::Key_Q || key == Qt::Key_W) ) { 145 emit tabCloseRequested( currentIndex() ); 146 } 147 else { 148 QTabWidget::keyPressEvent( event ); 149 } 150 } 151 152 void TabbedCrawlerWidget::setTabDataStatus( int index, DataStatus status ) 153 { 154 LOG(logDEBUG) << "TabbedCrawlerWidget::setTabDataStatus " << index; 155 156 QLabel* icon_label = dynamic_cast<QLabel*>( 157 myTabBar_.tabButton( index, QTabBar::RightSide ) ); 158 159 if ( icon_label ) { 160 const QIcon* icon; 161 switch ( status ) { 162 case DataStatus::OLD_DATA: 163 icon = &olddata_icon_; 164 break; 165 case DataStatus::NEW_DATA: 166 icon = &newdata_icon_; 167 break; 168 case DataStatus::NEW_FILTERED_DATA: 169 icon = &newfiltered_icon_; 170 break; 171 } 172 icon_label->setPixmap ( icon->pixmap(12,12) ); 173 } 174 } 175