File indexing completed on 2025-01-19 04:24:10

0001 /****************************************************************************************
0002  * Copyright (c) 2010 Rainer Sigle <rainer.sigle@web.de>                                *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #include "TabsView.h"
0018 #include "TabsItem.h"
0019 #include "core/support/Debug.h"
0020 #include "PaletteHandler.h"
0021 #include "widgets/PrettyTreeView.h"
0022 
0023 #include <KTextBrowser>
0024 #include <Plasma/ScrollBar>
0025 #include <Plasma/TextBrowser>
0026 
0027 #include <QGraphicsLinearLayout>
0028 
0029 // Subclassed to override the access level of some methods.
0030 // The TabsTreeView and the TabsView are so highly coupled that this is acceptable, imo.
0031 class TabsTreeView : public Amarok::PrettyTreeView
0032 {
0033     public:
0034         TabsTreeView( QWidget *parent = 0 )
0035             : Amarok::PrettyTreeView( parent )
0036         {
0037             setAttribute( Qt::WA_NoSystemBackground );
0038             viewport()->setAutoFillBackground( false );
0039 
0040             setHeaderHidden( true );
0041             setIconSize( QSize( 36, 36 ) );
0042             setDragDropMode( QAbstractItemView::DragOnly );
0043             setSelectionMode( QAbstractItemView::SingleSelection );
0044             setSelectionBehavior( QAbstractItemView::SelectItems );
0045             setAnimated( true );
0046             setRootIsDecorated( false );
0047             setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
0048             setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
0049             setFixedWidth( 48 );
0050 
0051         }
0052     protected:
0053 
0054         // Override access level to make it public. Only visible to the TabsView.
0055         // Used for context menu methods.
0056         QModelIndexList selectedIndexes() const { return PrettyTreeView::selectedIndexes(); }
0057 };
0058 
0059 
0060 TabsView::TabsView( QGraphicsWidget *parent )
0061     : QGraphicsProxyWidget( parent )
0062 {
0063     // tree view which holds the collection of fetched tabs
0064     m_treeView = new TabsTreeView( 0 );
0065     connect( m_treeView, SIGNAL(clicked(QModelIndex)),
0066              this, SLOT(itemClicked(QModelIndex)) );
0067 
0068     m_model = new QStandardItemModel();
0069     m_model->setColumnCount( 1 );
0070     m_treeView->setModel( m_model );
0071 
0072     m_treeProxy = new QGraphicsProxyWidget( this );
0073     m_treeProxy->setWidget( m_treeView );
0074 
0075     // the textbrowser widget to display the tabs
0076     m_tabTextBrowser = new Plasma::TextBrowser( );
0077     KTextBrowser *browserWidget = m_tabTextBrowser->nativeWidget();
0078     browserWidget->setFrameShape( QFrame::StyledPanel );
0079     browserWidget->setAttribute( Qt::WA_NoSystemBackground );
0080     browserWidget->setOpenExternalLinks( true );
0081     browserWidget->setUndoRedoEnabled( true );
0082     browserWidget->setAutoFillBackground( false );
0083     browserWidget->setWordWrapMode( QTextOption::NoWrap );
0084     browserWidget->viewport()->setAutoFillBackground( true );
0085     browserWidget->viewport()->setAttribute( Qt::WA_NoSystemBackground );
0086     browserWidget->setTextInteractionFlags( Qt::TextBrowserInteraction | Qt::TextSelectableByKeyboard );
0087 
0088     QScrollBar *treeScrollBar = m_treeView->verticalScrollBar();
0089     m_scrollBar = new Plasma::ScrollBar( this );
0090     m_scrollBar->setFocusPolicy( Qt::NoFocus );
0091 
0092     // synchronize scrollbars
0093     connect( treeScrollBar, SIGNAL(rangeChanged(int,int)), SLOT(slotScrollBarRangeChanged(int,int)) );
0094     connect( treeScrollBar, SIGNAL(valueChanged(int)), m_scrollBar, SLOT(setValue(int)) );
0095     connect( m_scrollBar, SIGNAL(valueChanged(int)), treeScrollBar, SLOT(setValue(int)) );
0096     m_scrollBar->setRange( treeScrollBar->minimum(), treeScrollBar->maximum() );
0097     m_scrollBar->setPageStep( treeScrollBar->pageStep() );
0098     m_scrollBar->setSingleStep( treeScrollBar->singleStep() );
0099 
0100     // arrange textbrowser and treeview in a horizontal layout
0101     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout( Qt::Horizontal );
0102     layout->addItem( m_treeProxy );
0103     layout->addItem( m_scrollBar );
0104     layout->addItem( m_tabTextBrowser );
0105     layout->setSpacing( 2 );
0106     layout->setContentsMargins( 0, 0, 0, 0 );
0107     setLayout( layout );
0108     setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
0109     updateScrollBarVisibility();
0110 }
0111 
0112 TabsView::~TabsView()
0113 {
0114     delete m_model;
0115     delete m_treeProxy;
0116 }
0117 
0118 void
0119 TabsView::appendTab( TabsItem *tabsItem  )
0120 {
0121     if( tabsItem )
0122         m_model->appendRow( tabsItem );
0123 }
0124 
0125 void
0126 TabsView::clear()
0127 {
0128     qDeleteAll( m_model->findItems(QLatin1String("*"), Qt::MatchWildcard) );
0129     m_model->clear();
0130 }
0131 
0132 void
0133 TabsView::clearTabBrowser()
0134 {
0135     m_tabTextBrowser->nativeWidget()->clear();
0136 }
0137 
0138 void
0139 TabsView::showTab( TabsItem *tab )
0140 {
0141     if( tab )
0142     {
0143         QString tabText = tab->getTabData();
0144         if( tabText.length() > 0 )
0145         {
0146             tabText.replace( '\n', "<br></br>", Qt::CaseInsensitive );
0147 
0148             QFont tabFont( "monospace");
0149             tabFont.setStyleHint( QFont::Courier );
0150             tabFont.setStyleStrategy( QFont::PreferAntialias );
0151             tabFont.setWeight( QFont::Normal );
0152             tabFont.setPointSize( QFont().pointSize() );
0153 
0154             QFont headingFont( "sans-serif" );
0155             headingFont.setPointSize( tabFont.pointSize() + 2 );
0156             headingFont.setStyleHint( QFont::SansSerif );
0157             headingFont.setStyleStrategy( QFont::PreferAntialias );
0158             headingFont.setWeight( QFont::Black );
0159             QString linkColor = The::paletteHandler()->palette().link().color().name();
0160             QString textColor = The::paletteHandler()->palette().text().color().name();
0161             int headingWeight = 600;
0162 
0163             QString htmlData = "<html>";
0164                     htmlData += "<body style=\"font-family:'" + tabFont.family() + "';";
0165                     htmlData += "font-size:" + QString::number( tabFont.pointSize() ) + "pt;";
0166                     htmlData += "font-weight:" + QString::number( tabFont.weight() ) + ';';
0167                     htmlData += "color:" + textColor + ";\">";
0168 
0169                     // tab heading + tab source
0170                     htmlData += "<p><span style=\"font-family:'" + headingFont.family() + "';";
0171                     htmlData += "font-size:" + QString::number( headingFont.pointSize() ) + "pt;";
0172                     htmlData += "font-weight:" + QString::number( headingWeight ) + ";\">";
0173                     htmlData += tab->getTabTitle();
0174                     htmlData += " (" + i18nc( "Guitar tablature", "tab provided from: " ) + "<a href=\"" + tab->getTabUrl() + "\">";
0175                     htmlData += "<span style=\"text-decoration: underline; color:" + linkColor + ";\">";
0176                     htmlData += tab->getTabSource() + "</a>";
0177                     htmlData += ")</span></p>";
0178 
0179                     // tab data
0180                     htmlData += tabText + "</body></html>";
0181 
0182             // backup current scrollbar position
0183             QScrollBar *vbar = m_tabTextBrowser->nativeWidget()->verticalScrollBar();
0184             int scrollPosition = vbar->isVisible() ? vbar->value() : vbar->minimum();
0185 
0186             m_tabTextBrowser->nativeWidget()->setHtml( htmlData );
0187 
0188             // re-apply scrollbar position
0189             vbar->setSliderPosition( scrollPosition );
0190         }
0191     }
0192 }
0193 
0194 void
0195 TabsView::itemClicked( const QModelIndex &index )
0196 {
0197     const QStandardItemModel *itemModel = static_cast<QStandardItemModel*>( m_treeView->model() );
0198 
0199     QStandardItem *item = itemModel->itemFromIndex( index );
0200     TabsItem *tab = dynamic_cast<TabsItem*>( item );
0201     if( tab )
0202         showTab( tab );
0203 }
0204 
0205 void
0206 TabsView::resizeEvent( QGraphicsSceneResizeEvent *event )
0207 {
0208     QGraphicsWidget::resizeEvent( event );
0209 }
0210 
0211 void
0212 TabsView::slotScrollBarRangeChanged( int min, int max )
0213 {
0214     m_scrollBar->setRange( min, max );
0215     m_scrollBar->setPageStep( m_treeView->verticalScrollBar()->pageStep() );
0216     m_scrollBar->setSingleStep( m_treeView->verticalScrollBar()->singleStep() );
0217     updateScrollBarVisibility();
0218 }
0219 
0220 void
0221 TabsView::updateScrollBarVisibility()
0222 {
0223     QGraphicsLinearLayout *lo = static_cast<QGraphicsLinearLayout*>( layout() );
0224     if( m_scrollBar->maximum() == 0 )
0225     {
0226         if( lo->count() > 2 && lo->itemAt( 1 ) == m_scrollBar )
0227         {
0228             lo->removeAt( 1 );
0229             m_scrollBar->hide();
0230         }
0231     }
0232     else if( lo->count() == 2 )
0233     {
0234         lo->insertItem( 1, m_scrollBar );
0235         m_scrollBar->show();
0236     }
0237 }
0238 
0239 
0240 #include <TabsView.moc>
0241