• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

akregator

  • sources
  • kde-4.14
  • kdepim
  • akregator
  • src
tabwidget.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Akregator.
3 
4  Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net>
5 
6  This program 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 2 of the License, or
9  (at your option) any later version.
10 
11  This program 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 this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20  As a special exception, permission is given to link this program
21  with any edition of Qt, and distribute the resulting executable,
22  without including the source code for Qt in the source distribution.
23 */
24 
25 #include "tabwidget.h"
26 
27 #include <QStyle>
28 #include <QApplication>
29 #include <QIcon>
30 #include <QClipboard>
31 #include <QHash>
32 #include <QString>
33 #include <QToolButton>
34 
35 #include <QMenu>
36 #include <QStyleOption>
37 
38 #include <kapplication.h>
39 #include <kdebug.h>
40 #include <ktabwidget.h>
41 #include <ktabbar.h>
42 #include <kmenu.h>
43 #include <krun.h>
44 #include <klocale.h>
45 #include <KIcon>
46 #include <kiconloader.h>
47 #include <ktoolinvocation.h>
48 #include <kurl.h>
49 #include <kmimetype.h>
50 #include <kio/global.h>
51 
52 #include "actionmanager.h"
53 #include "akregatorconfig.h"
54 #include "frame.h"
55 #include "framemanager.h"
56 #include "kernel.h"
57 #include "openurlrequest.h"
58 #include "utils/temporaryvalue.h"
59 
60 #include <cassert>
61 
62 namespace Akregator {
63 
64 class TabWidget::Private
65 {
66 private:
67  TabWidget* const q;
68 
69 public:
70  explicit Private( TabWidget * qq ) : q( qq ), currentMaxLength( 30 ), currentItem( 0 ), tabsClose( 0 ) {}
71 
72  QHash<QWidget*, Frame*> frames;
73  QHash<int, Frame*> framesById;
74  int currentMaxLength;
75  QWidget* currentItem;
76  QToolButton* tabsClose;
77 
78  QWidget* selectedWidget() const {
79  return ( currentItem && q->indexOf(currentItem) != -1 ) ? currentItem : q->currentWidget();
80  }
81 
82  uint tabBarWidthForMaxChars(int maxLength);
83  void setTitle(const QString &title , QWidget* sender);
84  void updateTabBarVisibility();
85  Frame* currentFrame();
86 };
87 
88 void TabWidget::Private::updateTabBarVisibility()
89 {
90  q->setTabBarHidden( ( q->count() <= 1 ) && !Settings::alwaysShowTabBar() );
91  if (q->count() >= 1 && Settings::closeButtonOnTabs())
92  q->tabBar()->tabButton(0, QTabBar::RightSide)->hide();
93 }
94 
95 TabWidget::TabWidget(QWidget * parent)
96  :KTabWidget(parent), d(new Private( this ) )
97 {
98  setMinimumSize(250,150);
99  setMovable(false);
100  setDocumentMode(true);
101  connect( this, SIGNAL(currentChanged(int)),
102  this, SLOT(slotTabChanged(int)) );
103  connect(this, SIGNAL(closeRequest(QWidget*)),
104  this, SLOT(slotCloseRequest(QWidget*)));
105  setTabsClosable(Settings::closeButtonOnTabs());
106 
107  d->tabsClose = new QToolButton(this);
108  connect( d->tabsClose, SIGNAL(clicked()), this,
109  SLOT(slotRemoveCurrentFrame()) );
110 
111  d->tabsClose->setIcon( KIcon( "tab-close" ) );
112  d->tabsClose->setEnabled( false );
113  d->tabsClose->adjustSize();
114  d->tabsClose->setToolTip( i18n("Close the current tab"));
115 
116 #ifndef QT_NO_ACCESSIBILITY
117  d->tabsClose->setAccessibleName( i18n( "Close tab" ) );
118 #endif
119 
120  setCornerWidget( d->tabsClose, Qt::TopRightCorner );
121  d->updateTabBarVisibility();
122 }
123 
124 TabWidget::~TabWidget()
125 {
126  delete d;
127 }
128 
129 void TabWidget::slotSettingsChanged()
130 {
131  if (tabsClosable() != Settings::closeButtonOnTabs())
132  setTabsClosable(Settings::closeButtonOnTabs());
133  d->updateTabBarVisibility();
134 }
135 
136 void TabWidget::slotNextTab()
137 {
138  setCurrentIndex((currentIndex()+1) % count());
139 }
140 
141 void TabWidget::slotPreviousTab()
142 {
143  if (currentIndex() == 0)
144  setCurrentIndex(count()-1);
145  else
146  setCurrentIndex(currentIndex()-1);
147 }
148 void TabWidget::slotSelectFrame(int frameId)
149 {
150  Frame* frame = d->framesById.value(frameId);
151  if (frame && frame != d->currentFrame())
152  {
153  setCurrentWidget(frame);
154  if (frame->part() && frame->part()->widget())
155  {
156  frame->part()->widget()->setFocus();
157  }
158  else
159  {
160  frame->setFocus();
161  }
162  }
163 }
164 
165 void TabWidget::slotAddFrame(Frame* frame)
166 {
167  if (!frame)
168  return;
169  d->frames.insert(frame, frame);
170  d->framesById.insert( frame->id(), frame );
171  addTab(frame, frame->title());
172  connect(frame, SIGNAL(signalTitleChanged(Akregator::Frame*,QString)),
173  this, SLOT(slotSetTitle(Akregator::Frame*,QString)));
174  connect(frame, SIGNAL(signalIconChanged(Akregator::Frame*,QIcon)),
175  this, SLOT(slotSetIcon(Akregator::Frame*,QIcon)));
176 
177  if(frame->id() > 0) // MainFrame doesn't emit signalPartDestroyed signals, neither should it
178  connect(frame, SIGNAL(signalPartDestroyed(int)), this, SLOT(slotRemoveFrame(int)));
179  slotSetTitle(frame, frame->title());
180 }
181 
182 Frame * TabWidget::Private::currentFrame()
183 {
184  QWidget* w = q->currentWidget();
185  assert( frames.value( w ) );
186  return w ? frames.value(w) : 0;
187 }
188 
189 void TabWidget::slotFrameZoomIn()
190 {
191  if ( !d->currentFrame() )
192  return;
193  emit signalZoomInFrame( d->currentFrame()->id() );
194 }
195 
196 void TabWidget::slotFrameZoomOut()
197 {
198  if ( !d->currentFrame() )
199  return;
200  emit signalZoomOutFrame( d->currentFrame()->id() );
201 }
202 
203 
204 void TabWidget::slotTabChanged(int index)
205 {
206 
207  Frame* frame = d->frames.value(widget(index));
208  d->tabsClose->setEnabled(frame && frame->isRemovable());
209  emit signalCurrentFrameChanged(frame ? frame->id() : -1);
210 }
211 
212 void TabWidget::tabInserted( int )
213 {
214  d->updateTabBarVisibility();
215 }
216 
217 
218 void TabWidget::tabRemoved( int )
219 {
220  d->updateTabBarVisibility();
221 }
222 
223 void TabWidget::slotRemoveCurrentFrame()
224 {
225  Frame* const frame = d->currentFrame();
226  if (frame)
227  emit signalRemoveFrameRequest(frame->id());
228 }
229 
230 void TabWidget::slotRemoveFrame(int frameId)
231 {
232  if (!d->framesById.contains(frameId))
233  return;
234  Frame* f = d->framesById.value(frameId);
235  d->frames.remove(f);
236  d->framesById.remove(frameId);
237  f->disconnect( this );
238  removeTab(indexOf(f));
239  emit signalRemoveFrameRequest(f->id());
240  if (d->currentFrame())
241  d->setTitle( d->currentFrame()->title(), currentWidget() );
242 }
243 
244 // copied wholesale from KonqFrameTabs
245 uint TabWidget::Private::tabBarWidthForMaxChars( int maxLength )
246 {
247  int hframe;
248  QStyleOption o;
249  hframe = q->tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabHSpace, &o, q );
250 
251  QFontMetrics fm = q->tabBar()->fontMetrics();
252  int x = 0;
253  for (int i = 0; i < q->count(); ++i)
254  {
255  Frame* f = frames.value(q->widget(i));
256  if (!f) {
257  continue; // frames is out of sync, e.g. because tabInserted wasn't called yet - #185597
258  }
259  QString newTitle = f->title();
260  if ( newTitle.length() > maxLength )
261  newTitle = newTitle.left( maxLength-3 ) + "...";
262 
263  int lw = fm.width( newTitle );
264  int iw = q->tabBar()->tabIcon( i ).pixmap( q->tabBar()->style()->pixelMetric(
265 QStyle::PM_SmallIconSize ), QIcon::Normal
266 ).width() + 4;
267 
268  x += ( q->tabBar()->style()->sizeFromContents( QStyle::CT_TabBarTab, &o,
269  QSize( qMax( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), q ) ).width();
270  }
271  return x;
272 }
273 
274 void TabWidget::slotSetTitle(Frame* frame, const QString& title)
275 {
276  d->setTitle(title, frame);
277 }
278 
279 void TabWidget::slotSetIcon(Akregator::Frame* frame, const QIcon& icon)
280 {
281  const int idx = indexOf( frame );
282  if ( idx < 0 )
283  return;
284  setTabIcon( idx, icon );
285 }
286 
287 void TabWidget::Private::setTitle( const QString &title, QWidget* sender)
288 {
289  int senderIndex = q->indexOf(sender);
290 
291  q->setTabToolTip( senderIndex, QString() );
292 
293  uint lcw=0, rcw=0;
294  int tabBarHeight = q->tabBar()->sizeHint().height();
295 
296  QWidget* leftCorner = q->cornerWidget( Qt::TopLeftCorner );
297 
298  if ( leftCorner && leftCorner->isVisible() )
299  lcw = qMax( leftCorner->width(), tabBarHeight );
300 
301  QWidget* rightCorner = q->cornerWidget( Qt::TopRightCorner );
302 
303  if ( rightCorner && rightCorner->isVisible() )
304  rcw = qMax( rightCorner->width(), tabBarHeight );
305  uint maxTabBarWidth = q->width() - lcw - rcw;
306 
307  int newMaxLength = 30;
308 
309  for ( ; newMaxLength > 3; newMaxLength-- )
310  {
311  if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
312  break;
313  }
314 
315  QString newTitle = title;
316  if ( newTitle.length() > newMaxLength )
317  {
318  q->setTabToolTip( senderIndex, newTitle );
319  newTitle = newTitle.left( newMaxLength-3 ) + "...";
320  }
321 
322  newTitle.replace( '&', "&&" );
323 
324  if ( q->tabText(senderIndex) != newTitle )
325  q->setTabText( senderIndex, newTitle );
326 
327  if( newMaxLength != currentMaxLength )
328  {
329  for( int i = 0; i < q->count(); ++i)
330  {
331  Frame* f = frames.value(q->widget(i));
332  if ( !f ) {
333  continue; // frames is out of sync, e.g. because tabInserted wasn't called yet - #185597
334  }
335  newTitle = f->title();
336  int index = q->indexOf(q->widget( i ));
337  q->setTabToolTip( index, QString() );
338 
339  if ( newTitle.length() > newMaxLength )
340  {
341  q->setTabToolTip( index, newTitle );
342  newTitle = newTitle.left( newMaxLength-3 ) + "...";
343  }
344 
345  newTitle.replace( '&', "&&" );
346  if ( newTitle != q->tabText( index ) )
347  q->setTabText( index, newTitle );
348  }
349  currentMaxLength = newMaxLength;
350  }
351 }
352 
353 void TabWidget::contextMenu(int i, const QPoint &p)
354 {
355  QWidget* w = ActionManager::getInstance()->container("tab_popup");
356  TemporaryValue<QWidget*> tmp( d->currentItem, widget( i ) );
357  //kDebug() << indexOf(d->currentItem);
358  // FIXME: do not hardcode index of maintab
359  if (w && indexOf(d->currentItem) != 0)
360  static_cast<QMenu *>(w)->exec(p);
361 }
362 
363 void TabWidget::slotDetachTab()
364 {
365  Frame* frame = d->frames.value( d->selectedWidget() );
366 
367  if (frame && frame->url().isValid() && frame->isRemovable())
368  {
369  OpenUrlRequest request;
370  request.setUrl(frame->url());
371  request.setOptions(OpenUrlRequest::ExternalBrowser);
372  emit signalOpenUrlRequest(request);
373  slotCloseTab();
374  }
375 }
376 
377 void TabWidget::slotCopyLinkAddress()
378 {
379  Frame* frame = d->frames.value( d->selectedWidget() );
380 
381  if (frame && frame->url().isValid())
382  {
383  KUrl url = frame->url();
384  // don't set url to selection as it's a no-no according to a fd.o spec
385  //kapp->clipboard()->setText(url.prettyUrl(), QClipboard::Selection);
386  kapp->clipboard()->setText(url.prettyUrl(), QClipboard::Clipboard);
387  }
388 }
389 
390 void TabWidget::slotCloseTab()
391 {
392  QWidget* widget = d->selectedWidget();
393  Frame* frame = d->frames.value( widget );
394 
395  if (frame == 0 || !frame->isRemovable() )
396  return;
397 
398  emit signalRemoveFrameRequest(frame->id());
399 }
400 
401 void TabWidget::initiateDrag(int tab)
402 {
403  Frame* frame = d->frames.value(widget(tab));
404 
405  if (frame && frame->url().isValid())
406  {
407  KUrl::List lst;
408  lst.append( frame->url() );
409  QDrag* drag = new QDrag( this );
410  QMimeData *md = new QMimeData;
411  drag->setMimeData( md );
412  lst.populateMimeData( md );
413  drag->setPixmap( KIO::pixmapForUrl( lst.first(), 0, KIconLoader::Small ) );
414  drag->start();
415  }
416 }
417 
418 void TabWidget::slotReloadAllTabs()
419 {
420  Q_FOREACH(Frame* frame,d->frames.values())
421  {
422  frame->slotReload();
423  }
424 }
425 
426 
427 void TabWidget::slotCloseRequest(QWidget* widget)
428 {
429  if (d->frames.value(widget))
430  emit signalRemoveFrameRequest(d->frames.value(widget)->id());
431 }
432 
433 void TabWidget::slotActivateTab()
434 {
435  setCurrentIndex( sender()->objectName().right( 2 ).toInt() -1 );
436 }
437 
438 
439 } // namespace Akregator
440 
Akregator::Frame
Definition: frame.h:53
Akregator::TabWidget::slotActivateTab
void slotActivateTab()
Definition: tabwidget.cpp:433
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QWidget
openurlrequest.h
Akregator::TabWidget::TabWidget
TabWidget(QWidget *parent=0)
Definition: tabwidget.cpp:95
Akregator::TabWidget::~TabWidget
~TabWidget()
Definition: tabwidget.cpp:124
Akregator::Frame::isRemovable
bool isRemovable() const
Returns whether the frame can be removed from Akregator (via detach or close tab etc.) Usually all tabs but the main tab can be removed.
Definition: frame.cpp:122
QDrag::setMimeData
void setMimeData(QMimeData *data)
QDrag::start
Qt::DropAction start(QFlags< Qt::DropAction > request)
kernel.h
QDrag::setPixmap
void setPixmap(const QPixmap &pixmap)
Akregator::TabWidget::slotRemoveFrame
void slotRemoveFrame(int frameId)
Definition: tabwidget.cpp:230
Akregator::TabWidget::signalRemoveFrameRequest
void signalRemoveFrameRequest(int)
uint
unsigned int uint
Definition: article.h:41
QWidget::isVisible
bool isVisible() const
Akregator::TabWidget::slotFrameZoomOut
void slotFrameZoomOut()
Definition: tabwidget.cpp:196
Akregator::TabWidget::slotFrameZoomIn
void slotFrameZoomIn()
Definition: tabwidget.cpp:189
Akregator::TabWidget::signalZoomOutFrame
void signalZoomOutFrame(int)
QPoint
QFontMetrics
Akregator::TabWidget::slotSettingsChanged
void slotSettingsChanged()
Definition: tabwidget.cpp:129
actionmanager.h
Akregator::TabWidget::signalZoomInFrame
void signalZoomInFrame(int)
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QMimeData
QApplication::globalStrut
QSize globalStrut()
Akregator::TabWidget::slotPreviousTab
void slotPreviousTab()
Definition: tabwidget.cpp:141
QWidget::width
width
QStyleOption
tabwidget.h
QHash
Definition: feedlist.h:41
QWidget::setFocus
void setFocus()
Akregator::Frame::id
int id() const
Definition: frame.cpp:112
frame.h
QDrag
Akregator::Frame::part
virtual KParts::ReadOnlyPart * part() const =0
Akregator::ActionManager::container
virtual QWidget * container(const char *name)=0
QString
Akregator::TabWidget::slotNextTab
void slotNextTab()
Definition: tabwidget.cpp:136
Akregator::TabWidget::slotReloadAllTabs
void slotReloadAllTabs()
Definition: tabwidget.cpp:418
Akregator::Frame::slotReload
virtual void slotReload()
reloads the current content, if possible.
Definition: frame.h:127
Akregator::OpenUrlRequest::ExternalBrowser
open in external browser
Definition: openurlrequest.h:54
QToolButton
Akregator::Frame::title
QString title() const
Definition: frame.cpp:141
QMenu
Akregator::TabWidget::signalOpenUrlRequest
void signalOpenUrlRequest(Akregator::OpenUrlRequest &)
QSize
Akregator::TabWidget::slotRemoveCurrentFrame
void slotRemoveCurrentFrame()
Definition: tabwidget.cpp:223
QFontMetrics::width
int width(const QString &text, int len) const
QString::replace
QString & replace(int position, int n, QChar after)
Akregator::TabWidget::slotSetTitle
void slotSetTitle(Akregator::Frame *frame, const QString &title)
Definition: tabwidget.cpp:274
Akregator::ActionManager::getInstance
static ActionManager * getInstance()
Definition: actionmanager.cpp:35
Akregator::TabWidget::slotAddFrame
void slotAddFrame(Akregator::Frame *f)
Definition: tabwidget.cpp:165
QString::length
int length() const
Akregator::TabWidget::slotSelectFrame
void slotSelectFrame(int frameId)
Definition: tabwidget.cpp:148
QString::left
QString left(int n) const
temporaryvalue.h
framemanager.h
Akregator::TabWidget::slotSetIcon
void slotSetIcon(Akregator::Frame *frame, const QIcon &icon)
Definition: tabwidget.cpp:279
Akregator::TabWidget::signalCurrentFrameChanged
void signalCurrentFrameChanged(int)
QIcon
KTabWidget
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:00 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akregator

Skip menu "akregator"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal