?? multitabbar.cpp
字號:
/*************************************************************************** kmultitabbar.cpp - description ------------------- begin : 2001 copyright : (C) 2001,2002,2003 by Joseph Wenninger <jowenn@kde.org> (C) 2005 by Mark Kretschmann <markey@web.de>***************************************************************************//*************************************************************************** This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.***************************************************************************/#include "debug.h"#include "multitabbar.h"#include "multitabbar.moc"#include "multitabbar_p.h"#include "multitabbar_p.moc"#include <math.h>#include <qbutton.h>#include <qfontmetrics.h>#include <qlayout.h>#include <qpainter.h>#include <qpopupmenu.h>#include <qstyle.h>#include <qtimer.h>#include <kapplication.h>#include <kconfig.h>#include <kdebug.h>#include <kiconeffect.h>#include <kiconloader.h>#include <klocale.h>#include <kpopupmenu.h>#include <kstringhandler.h>#define NEARBYINT(i) ((int(float(i) + 0.5)))namespace Amarok { extern KConfig *config( const QString& ); }class MultiTabBarTabPrivate{ public: QPixmap pix;};class MultiTabBarButtonPrivate{ public: MultiTabBarButtonPrivate() : finalDropTarget( 0 ) {} DropProxyTarget *finalDropTarget;};MultiTabBarInternal::MultiTabBarInternal( QWidget *parent, MultiTabBar::MultiTabBarMode bm ) : QScrollView( parent ){ m_expandedTabSize = -1; m_showActiveTabTexts = false; m_tabs.setAutoDelete( true ); m_barMode = bm; setHScrollBarMode( AlwaysOff ); setVScrollBarMode( AlwaysOff ); if ( bm == MultiTabBar::Vertical ) { box = new QWidget( viewport() ); mainLayout = new QVBoxLayout( box ); mainLayout->setAutoAdd( true ); box->setFixedWidth( 24 ); setFixedWidth( 24 ); } else { box = new QWidget( viewport() ); mainLayout = new QHBoxLayout( box ); mainLayout->setAutoAdd( true ); box->setFixedHeight( 24 ); setFixedHeight( 24 ); } addChild( box ); setFrameStyle( NoFrame ); viewport() ->setBackgroundMode( Qt::PaletteBackground ); /* box->setPaletteBackgroundColor(Qt::red); setPaletteBackgroundColor(Qt::green);*/}void MultiTabBarInternal::setStyle( enum MultiTabBar::MultiTabBarStyle style ){ m_style = style; for ( uint i = 0;i < m_tabs.count();i++ ) m_tabs.at( i ) ->setStyle( m_style ); if ( ( m_style == MultiTabBar::KDEV3 ) || ( m_style == MultiTabBar::KDEV3ICON ) || ( m_style == MultiTabBar::AMAROK ) ) { delete mainLayout; mainLayout = 0; resizeEvent( 0 ); } else if ( mainLayout == 0 ) { if ( m_barMode == MultiTabBar::Vertical ) { box = new QWidget( viewport() ); mainLayout = new QVBoxLayout( box ); box->setFixedWidth( 24 ); setFixedWidth( 24 ); } else { box = new QWidget( viewport() ); mainLayout = new QHBoxLayout( box ); box->setFixedHeight( 24 ); setFixedHeight( 24 ); } addChild( box ); for ( uint i = 0;i < m_tabs.count();i++ ) mainLayout->add( m_tabs.at( i ) ); mainLayout->setAutoAdd( true ); } viewport() ->repaint();}void MultiTabBarInternal::drawContents ( QPainter * paint, int clipx, int clipy, int clipw, int cliph ){ QScrollView::drawContents ( paint , clipx, clipy, clipw, cliph ); if ( m_position == MultiTabBar::Right ) { paint->setPen( colorGroup().shadow() ); paint->drawLine( 0, 0, 0, viewport() ->height() ); paint->setPen( colorGroup().background().dark( 120 ) ); paint->drawLine( 1, 0, 1, viewport() ->height() ); } else if ( m_position == MultiTabBar::Left ) { paint->setPen( colorGroup().light() ); paint->drawLine( 23, 0, 23, viewport() ->height() ); paint->drawLine( 22, 0, 22, viewport() ->height() ); paint->setPen( colorGroup().shadow() ); paint->drawLine( 0, 0, 0, viewport() ->height() ); } else if ( m_position == MultiTabBar::Bottom ) { paint->setPen( colorGroup().shadow() ); paint->drawLine( 0, 0, viewport() ->width(), 0 ); paint->setPen( colorGroup().background().dark( 120 ) ); paint->drawLine( 0, 1, viewport() ->width(), 1 ); } else { paint->setPen( colorGroup().light() ); paint->drawLine( 0, 23, viewport() ->width(), 23 ); paint->drawLine( 0, 22, viewport() ->width(), 22 ); /* paint->setPen(colorGroup().shadow()); paint->drawLine(0,0,0,viewport()->height());*/ }}void MultiTabBarInternal::contentsMousePressEvent( QMouseEvent *ev ){ ev->ignore();}void MultiTabBarInternal::showTabSelectionMenu(QPoint pos){ KPopupMenu popup; popup.insertTitle( i18n("Browsers") , /*id*/ -1, /*index*/ 1 ); popup.setCheckable( true ); for( uint i = 0; i < m_tabs.count(); i++ ) { MultiTabBarTab* tab = m_tabs.at( i ); popup.insertItem( tab->text(), i ); popup.setItemChecked(i, tab->visible() ? true : false); } int col = popup.exec(pos); if ( col >= 0 ) setTabVisible( col, !popup.isItemChecked(col) );}void MultiTabBarInternal::mousePressEvent( QMouseEvent *ev ){ if ( ev->button() != QMouseEvent::RightButton ){ ev->ignore(); return; } // right button pressed showTabSelectionMenu(ev->globalPos());}#define CALCDIFF(m_tabs,diff,i) if (m_lines>(int)lines) {\ /*kdDebug()<<"i="<<i<<" visibleTabCount="<<visibleTabCount()<<" space="<<space<<endl;*/ \ uint ulen=0;\ diff=0; \ for (uint i2=i;i2<visibleTabCount();i2++) {\ uint l1=sizePerTab();\ if ((ulen+l1)>space){\ if (ulen==0) diff=0;\ else diff=((float)(space-ulen))/(i2-i);\ break;\ }\ ulen+=l1;\ }\ } else {diff=0; }void MultiTabBarInternal::resizeEvent( QResizeEvent *ev ){ /* kdDebug()<<"MultiTabBarInternal::resizeEvent"<<endl; kdDebug()<<"MultiTabBarInternal::resizeEvent - box geometry"<<box->geometry()<<endl; kdDebug()<<"MultiTabBarInternal::resizeEvent - geometry"<<geometry()<<endl;*/ if ( ev ) QScrollView::resizeEvent( ev ); if ( ( m_style == MultiTabBar::KDEV3 ) || ( m_style == MultiTabBar::KDEV3ICON ) || ( m_style == MultiTabBar::AMAROK ) ) { box->setGeometry( 0, 0, width(), height() ); int lines = 1; uint space; float tmp = 0; if ( ( m_position == MultiTabBar::Bottom ) || ( m_position == MultiTabBar::Top ) ) space = width(); else space = height(); // made space for tab management button int cnt = 0; //CALCULATE LINES const uint tabCount = m_tabs.count(); for ( uint i = 0;i < tabCount;i++ ) { if ( ! m_tabs.at( i ) ->visible() ) continue; cnt++; tmp += sizePerTab(); if ( tmp > space ) { if ( cnt > 1 ) i--; else if ( i == ( tabCount - 1 ) ) break; cnt = 0; tmp = 0; lines++; } } //SET SIZE & PLACE float diff = 0; cnt = 0; if ( ( m_position == MultiTabBar::Bottom ) || ( m_position == MultiTabBar::Top ) ) { setFixedHeight( lines * 24 ); box->setFixedHeight( lines * 24 ); m_lines = height() / 24 - 1; lines = 0; CALCDIFF( m_tabs, diff, 0 ) tmp = -diff; //kdDebug()<<"m_lines recalculated="<<m_lines<<endl; for ( uint i = 0;i < tabCount;i++ ) { MultiTabBarTab *tab = m_tabs.at( i ); if ( ! tab->visible() ) continue; cnt++; tmp += sizePerTab() + diff; if ( tmp > space ) { //kdDebug()<<"about to start new line"<<endl; if ( cnt > 1 ) { CALCDIFF( m_tabs, diff, i ) i--; } else { //kdDebug()<<"placing line on old line"<<endl; kdDebug() << "diff=" << diff << endl; tab->removeEventFilter( this ); tab->move( NEARBYINT( tmp - sizePerTab() ), lines * 24 ); // tab->setFixedWidth(tab->neededSize()+diff); tab->setFixedWidth( NEARBYINT( tmp + diff ) - tab->x() );; tab->installEventFilter( this ); CALCDIFF( m_tabs, diff, ( i + 1 ) ) } tmp = -diff; cnt = 0; lines++; //kdDebug()<<"starting new line:"<<lines<<endl; } else { //kdDebug()<<"Placing line on line:"<<lines<<" pos: (x/y)=("<<tmp-m_tabs.at(i)->neededSize()<<"/"<<lines*24<<")"<<endl; //kdDebug()<<"diff="<<diff<<endl; tab->removeEventFilter( this ); tab->move( NEARBYINT( tmp - sizePerTab() ), lines * 24 ); tab->setFixedWidth( NEARBYINT( tmp + diff ) - tab->x() );; //tab->setFixedWidth(tab->neededSize()+diff); tab->installEventFilter( this ); } } } else { // Left or Right setFixedWidth( lines * 24 ); box->setFixedWidth( lines * 24 ); m_lines = lines = width() / 24; lines = 0; CALCDIFF( m_tabs, diff, 0 ) tmp = -diff; for ( uint i = 0;i < tabCount;i++ ) { MultiTabBarTab *tab = m_tabs.at( i ); if ( ! tab->visible() ) continue; cnt++; tmp += sizePerTab() + diff; if ( tmp > space ) { if ( cnt > 1 ) { CALCDIFF( m_tabs, diff, i ); tmp = -diff; i--; } else { tab->removeEventFilter( this ); tab->move( lines * 24, NEARBYINT( tmp - sizePerTab() ) ); tab->setFixedHeight( NEARBYINT( tmp + diff ) - tab->y() );; tab->installEventFilter( this ); } cnt = 0; tmp = -diff; lines++; } else { tab->removeEventFilter( this ); tab->move( lines * 24, NEARBYINT( tmp - sizePerTab() ) ); tab->setFixedHeight( NEARBYINT( tmp + diff ) - tab->y() ); tab->installEventFilter( this ); } } } //kdDebug()<<"needed lines:"<<m_lines<<endl; } else { int size = 0; /*move the calculation into another function and call it only on add tab and tab click events*/ for ( int i = 0;i < ( int ) m_tabs.count();i++ ) size += ( m_barMode == MultiTabBar::Vertical ? m_tabs.at( i ) ->height() : m_tabs.at( i ) ->width() ); if ( ( m_position == MultiTabBar::Bottom ) || ( m_position == MultiTabBar::Top ) ) box->setGeometry( 0, 0, size, height() ); else box->setGeometry( 0, 0, width(), size ); }}void MultiTabBarInternal::showActiveTabTexts( bool show ){ m_showActiveTabTexts = show;}MultiTabBarTab* MultiTabBarInternal::tab( int id ) const{ for ( QPtrListIterator<MultiTabBarTab> it( m_tabs );it.current();++it ) { if ( it.current() ->id() == id ) return it.current(); } return 0;}bool MultiTabBarInternal::eventFilter( QObject *, QEvent *e ){ if ( e->type() == QEvent::Resize ) resizeEvent( 0 ); //PATCH by markey: Allow switching of tabs with mouse wheel if ( e->type() == QEvent::Wheel ) { QWheelEvent* event = static_cast<QWheelEvent*>( e ); const int delta = event->delta() / 120; // Determine which tab is currently active uint i; for( i = 0; i < m_tabs.count(); i++ ) if ( m_tabs.at( i )->isOn() ) break; // Calculate index of the new tab to activate int newTab = i - delta; while (true) { if ( newTab < 0 ) { newTab = i; break; } if ( newTab > (int)m_tabs.count() - 1 ) { newTab = i; break; } if ( m_tabs.at( newTab )->visible() && m_tabs.at( newTab )->isEnabled() ) break; // try one tab more newTab -= delta; } if ( i < m_tabs.count() && newTab != (int)i ) m_tabs.at( newTab )->animateClick(); // Must return true here for the wheel to work properly return true; } return false;}int MultiTabBarInternal::appendTab( const QPixmap &pic , int id, const QString& text, const QString& identifier ){ MultiTabBarTab * tab; m_tabs.append( tab = new MultiTabBarTab( pic, text, id, box, m_position, m_style ) ); tab->setIdentifier( identifier ); tab->installEventFilter( this ); tab->showActiveTabText( m_showActiveTabTexts ); tab->setVisible( Amarok::config( "BrowserBar" )->readBoolEntry( identifier, true ) ); if ( m_style == MultiTabBar::KONQSBC ) { if ( m_expandedTabSize < tab->neededSize() ) { m_expandedTabSize = tab->neededSize(); for ( uint i = 0;i < m_tabs.count();i++ ) m_tabs.at( i ) ->setSize( m_expandedTabSize ); } else tab->setSize( m_expandedTabSize ); } else tab->updateState(); if ( tab->visible() ) { tab->show(); resizeEvent( 0 ); } else tab->hide(); return 0;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -