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
TabbedCrawlerWidget()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
addTab(QWidget * page,const QString & label)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
removeTab(int index)95 void TabbedCrawlerWidget::removeTab( int index )
96 {
97 QTabWidget::removeTab( index );
98
99 if ( count() <= 1 )
100 myTabBar_.hide();
101 }
102
mouseReleaseEvent(QMouseEvent * event)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
keyPressEvent(QKeyEvent * event)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
setTabDataStatus(int index,DataStatus status)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 default:
172 return;
173 }
174
175 icon_label->setPixmap ( icon->pixmap(12,12) );
176
177 }
178 }
179