1 /****************************************************************************************
2 * Copyright (c) 2010 Rainer Sigle <rainer.sigle@web.de> *
3 * *
4 * This program is free software; you can redistribute it and/or modify it under *
5 * the terms of the GNU General Public License as published by the Free Software *
6 * Foundation; either version 2 of the License, or (at your option) any later *
7 * version. *
8 * *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
11 * PARTICULAR PURPOSE. See the GNU General Public License for more details. *
12 * *
13 * You should have received a copy of the GNU General Public License along with *
14 * this program. If not, see <http://www.gnu.org/licenses/>. *
15 ****************************************************************************************/
16
17 #include "TabsView.h"
18 #include "TabsItem.h"
19 #include "core/support/Debug.h"
20 #include "PaletteHandler.h"
21 #include "widgets/PrettyTreeView.h"
22
23 #include <KTextBrowser>
24 #include <Plasma/ScrollBar>
25 #include <Plasma/TextBrowser>
26
27 #include <QGraphicsLinearLayout>
28
29 // Subclassed to override the access level of some methods.
30 // The TabsTreeView and the TabsView are so highly coupled that this is acceptable, imo.
31 class TabsTreeView : public Amarok::PrettyTreeView
32 {
33 public:
TabsTreeView(QWidget * parent=0)34 TabsTreeView( QWidget *parent = 0 )
35 : Amarok::PrettyTreeView( parent )
36 {
37 setAttribute( Qt::WA_NoSystemBackground );
38 viewport()->setAutoFillBackground( false );
39
40 setHeaderHidden( true );
41 setIconSize( QSize( 36, 36 ) );
42 setDragDropMode( QAbstractItemView::DragOnly );
43 setSelectionMode( QAbstractItemView::SingleSelection );
44 setSelectionBehavior( QAbstractItemView::SelectItems );
45 setAnimated( true );
46 setRootIsDecorated( false );
47 setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
48 setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
49 setFixedWidth( 48 );
50
51 }
52 protected:
53
54 // Override access level to make it public. Only visible to the TabsView.
55 // Used for context menu methods.
selectedIndexes() const56 QModelIndexList selectedIndexes() const { return PrettyTreeView::selectedIndexes(); }
57 };
58
59
TabsView(QGraphicsWidget * parent)60 TabsView::TabsView( QGraphicsWidget *parent )
61 : QGraphicsProxyWidget( parent )
62 {
63 // tree view which holds the collection of fetched tabs
64 m_treeView = new TabsTreeView( 0 );
65 connect( m_treeView, SIGNAL(clicked(QModelIndex)),
66 this, SLOT(itemClicked(QModelIndex)) );
67
68 m_model = new QStandardItemModel();
69 m_model->setColumnCount( 1 );
70 m_treeView->setModel( m_model );
71
72 m_treeProxy = new QGraphicsProxyWidget( this );
73 m_treeProxy->setWidget( m_treeView );
74
75 // the textbrowser widget to display the tabs
76 m_tabTextBrowser = new Plasma::TextBrowser( );
77 KTextBrowser *browserWidget = m_tabTextBrowser->nativeWidget();
78 browserWidget->setFrameShape( QFrame::StyledPanel );
79 browserWidget->setAttribute( Qt::WA_NoSystemBackground );
80 browserWidget->setOpenExternalLinks( true );
81 browserWidget->setUndoRedoEnabled( true );
82 browserWidget->setAutoFillBackground( false );
83 browserWidget->setWordWrapMode( QTextOption::NoWrap );
84 browserWidget->viewport()->setAutoFillBackground( true );
85 browserWidget->viewport()->setAttribute( Qt::WA_NoSystemBackground );
86 browserWidget->setTextInteractionFlags( Qt::TextBrowserInteraction | Qt::TextSelectableByKeyboard );
87
88 QScrollBar *treeScrollBar = m_treeView->verticalScrollBar();
89 m_scrollBar = new Plasma::ScrollBar( this );
90 m_scrollBar->setFocusPolicy( Qt::NoFocus );
91
92 // synchronize scrollbars
93 connect( treeScrollBar, SIGNAL(rangeChanged(int,int)), SLOT(slotScrollBarRangeChanged(int,int)) );
94 connect( treeScrollBar, SIGNAL(valueChanged(int)), m_scrollBar, SLOT(setValue(int)) );
95 connect( m_scrollBar, SIGNAL(valueChanged(int)), treeScrollBar, SLOT(setValue(int)) );
96 m_scrollBar->setRange( treeScrollBar->minimum(), treeScrollBar->maximum() );
97 m_scrollBar->setPageStep( treeScrollBar->pageStep() );
98 m_scrollBar->setSingleStep( treeScrollBar->singleStep() );
99
100 // arrange textbrowser and treeview in a horizontal layout
101 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout( Qt::Horizontal );
102 layout->addItem( m_treeProxy );
103 layout->addItem( m_scrollBar );
104 layout->addItem( m_tabTextBrowser );
105 layout->setSpacing( 2 );
106 layout->setContentsMargins( 0, 0, 0, 0 );
107 setLayout( layout );
108 setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
109 updateScrollBarVisibility();
110 }
111
~TabsView()112 TabsView::~TabsView()
113 {
114 delete m_model;
115 delete m_treeProxy;
116 }
117
118 void
appendTab(TabsItem * tabsItem)119 TabsView::appendTab( TabsItem *tabsItem )
120 {
121 if( tabsItem )
122 m_model->appendRow( tabsItem );
123 }
124
125 void
clear()126 TabsView::clear()
127 {
128 qDeleteAll( m_model->findItems(QLatin1String("*"), Qt::MatchWildcard) );
129 m_model->clear();
130 }
131
132 void
clearTabBrowser()133 TabsView::clearTabBrowser()
134 {
135 m_tabTextBrowser->nativeWidget()->clear();
136 }
137
138 void
showTab(TabsItem * tab)139 TabsView::showTab( TabsItem *tab )
140 {
141 if( tab )
142 {
143 QString tabText = tab->getTabData();
144 if( tabText.length() > 0 )
145 {
146 tabText.replace( '\n', "<br></br>", Qt::CaseInsensitive );
147
148 QFont tabFont( "monospace");
149 tabFont.setStyleHint( QFont::Courier );
150 tabFont.setStyleStrategy( QFont::PreferAntialias );
151 tabFont.setWeight( QFont::Normal );
152 tabFont.setPointSize( QFont().pointSize() );
153
154 QFont headingFont( "sans-serif" );
155 headingFont.setPointSize( tabFont.pointSize() + 2 );
156 headingFont.setStyleHint( QFont::SansSerif );
157 headingFont.setStyleStrategy( QFont::PreferAntialias );
158 headingFont.setWeight( QFont::Black );
159 QString linkColor = The::paletteHandler()->palette().link().color().name();
160 QString textColor = The::paletteHandler()->palette().text().color().name();
161 int headingWeight = 600;
162
163 QString htmlData = "<html>";
164 htmlData += "<body style=\"font-family:'" + tabFont.family() + "';";
165 htmlData += "font-size:" + QString::number( tabFont.pointSize() ) + "pt;";
166 htmlData += "font-weight:" + QString::number( tabFont.weight() ) + ';';
167 htmlData += "color:" + textColor + ";\">";
168
169 // tab heading + tab source
170 htmlData += "<p><span style=\"font-family:'" + headingFont.family() + "';";
171 htmlData += "font-size:" + QString::number( headingFont.pointSize() ) + "pt;";
172 htmlData += "font-weight:" + QString::number( headingWeight ) + ";\">";
173 htmlData += tab->getTabTitle();
174 htmlData += " (" + i18nc( "Guitar tablature", "tab provided from: " ) + "<a href=\"" + tab->getTabUrl() + "\">";
175 htmlData += "<span style=\"text-decoration: underline; color:" + linkColor + ";\">";
176 htmlData += tab->getTabSource() + "</a>";
177 htmlData += ")</span></p>";
178
179 // tab data
180 htmlData += tabText + "</body></html>";
181
182 // backup current scrollbar position
183 QScrollBar *vbar = m_tabTextBrowser->nativeWidget()->verticalScrollBar();
184 int scrollPosition = vbar->isVisible() ? vbar->value() : vbar->minimum();
185
186 m_tabTextBrowser->nativeWidget()->setHtml( htmlData );
187
188 // re-apply scrollbar position
189 vbar->setSliderPosition( scrollPosition );
190 }
191 }
192 }
193
194 void
itemClicked(const QModelIndex & index)195 TabsView::itemClicked( const QModelIndex &index )
196 {
197 const QStandardItemModel *itemModel = static_cast<QStandardItemModel*>( m_treeView->model() );
198
199 QStandardItem *item = itemModel->itemFromIndex( index );
200 TabsItem *tab = dynamic_cast<TabsItem*>( item );
201 if( tab )
202 showTab( tab );
203 }
204
205 void
resizeEvent(QGraphicsSceneResizeEvent * event)206 TabsView::resizeEvent( QGraphicsSceneResizeEvent *event )
207 {
208 QGraphicsWidget::resizeEvent( event );
209 }
210
211 void
slotScrollBarRangeChanged(int min,int max)212 TabsView::slotScrollBarRangeChanged( int min, int max )
213 {
214 m_scrollBar->setRange( min, max );
215 m_scrollBar->setPageStep( m_treeView->verticalScrollBar()->pageStep() );
216 m_scrollBar->setSingleStep( m_treeView->verticalScrollBar()->singleStep() );
217 updateScrollBarVisibility();
218 }
219
220 void
updateScrollBarVisibility()221 TabsView::updateScrollBarVisibility()
222 {
223 QGraphicsLinearLayout *lo = static_cast<QGraphicsLinearLayout*>( layout() );
224 if( m_scrollBar->maximum() == 0 )
225 {
226 if( lo->count() > 2 && lo->itemAt( 1 ) == m_scrollBar )
227 {
228 lo->removeAt( 1 );
229 m_scrollBar->hide();
230 }
231 }
232 else if( lo->count() == 2 )
233 {
234 lo->insertItem( 1, m_scrollBar );
235 m_scrollBar->show();
236 }
237 }
238
239
240 #include <TabsView.moc>
241
242