diff options
Diffstat (limited to 'akregator/src/tabwidget.cpp')
-rw-r--r-- | akregator/src/tabwidget.cpp | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/akregator/src/tabwidget.cpp b/akregator/src/tabwidget.cpp new file mode 100644 index 000000000..561b93e5d --- /dev/null +++ b/akregator/src/tabwidget.cpp @@ -0,0 +1,331 @@ +/* + This file is part of Akregator. + + Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include "tabwidget.h" + +#include <qstyle.h> +#include <qapplication.h> +#include <qiconset.h> +#include <qclipboard.h> +#include <qmap.h> +#include <qptrdict.h> +#include <qstring.h> +#include <qtoolbutton.h> +#include <qtooltip.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <ktabwidget.h> +#include <ktabbar.h> +#include <kpopupmenu.h> +#include <krun.h> +#include <klocale.h> +#include <khtmlview.h> +#include <khtml_part.h> +#include <kiconloader.h> +#include <kurl.h> +#include <kurldrag.h> +#include <kmimetype.h> + +#include "actionmanager.h" +#include "frame.h" +#include "akregatorconfig.h" + +namespace Akregator { + +class TabWidget::TabWidgetPrivate +{ + public: + QPtrDict<Frame> frames; + uint CurrentMaxLength; + QWidget* currentItem; + QToolButton* tabsClose; +}; + +TabWidget::TabWidget(QWidget * parent, const char *name) + :KTabWidget(parent, name), d(new TabWidgetPrivate) +{ + d->CurrentMaxLength = 30; + d->currentItem = 0; + setMinimumSize(250,150); + setTabReorderingEnabled(false); + connect( this, SIGNAL( currentChanged(QWidget *) ), this, + SLOT( slotTabChanged(QWidget *) ) ); + connect(this, SIGNAL(closeRequest(QWidget*)), this, SLOT(slotCloseRequest(QWidget*))); + setHoverCloseButton(Settings::closeButtonOnTabs()); + + d->tabsClose = new QToolButton(this); + d->tabsClose->setAccel(QKeySequence("Ctrl+W")); + connect( d->tabsClose, SIGNAL( clicked() ), this, + SLOT( slotRemoveCurrentFrame() ) ); + + d->tabsClose->setIconSet( SmallIconSet( "tab_remove" ) ); + d->tabsClose->adjustSize(); + QToolTip::add(d->tabsClose, i18n("Close the current tab")); + setCornerWidget( d->tabsClose, TopRight ); +} + +TabWidget::~TabWidget() +{ + delete d; + d = 0; +} + +void TabWidget::slotSettingsChanged() +{ + if (hoverCloseButton() != Settings::closeButtonOnTabs()) + setHoverCloseButton(Settings::closeButtonOnTabs()); +} + +void TabWidget::slotNextTab() +{ + setCurrentPage((currentPageIndex()+1) % count()); +} + +void TabWidget::slotPreviousTab() +{ + if (currentPageIndex() == 0) + setCurrentPage(count()-1); + else + setCurrentPage(currentPageIndex()-1); +} + +void TabWidget::addFrame(Frame *f) +{ + if (!f || !f->widget()) + return; + d->frames.insert(f->widget(), f); + addTab(f->widget(), f->title()); + connect(f, SIGNAL(titleChanged(Frame*, const QString& )), this, SLOT(slotSetTitle(Frame*, const QString& ))); + slotSetTitle(f, f->title()); +} + +Frame *TabWidget::currentFrame() +{ + QWidget* w = currentPage(); + + return w ? d->frames[w] : 0; +} + +QPtrList<Frame> TabWidget::frames() const +{ + QPtrList<Frame> result; + QPtrDictIterator<Frame> it(d->frames); + while (it.current()) + { + result.append(it.current()); + ++it; + } + + return result; +} + +void TabWidget::slotTabChanged(QWidget *w) +{ + // FIXME: Don't hardcode the tab position of main frame + d->tabsClose->setDisabled(currentPageIndex() == 0); + emit currentFrameChanged(d->frames[w]); +} + +void TabWidget::slotRemoveCurrentFrame() +{ + removeFrame(currentFrame()); +} + +void TabWidget::removeFrame(Frame *f) +{ + f->setCompleted(); + d->frames.remove(f->widget()); + removePage(f->widget()); + delete f; + setTitle( currentFrame()->title(), currentPage() ); +} + +// copied wholesale from KonqFrameTabs +uint TabWidget::tabBarWidthForMaxChars( uint maxLength ) +{ + int hframe, overlap; + hframe = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabHSpace, this ); + overlap = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabOverlap, this ); + + QFontMetrics fm = tabBar()->fontMetrics(); + int x = 0; + for( int i=0; i < count(); ++i ) { + Frame *f=d->frames[page(i)]; + QString newTitle=f->title(); + if ( newTitle.length() > maxLength ) + newTitle = newTitle.left( maxLength-3 ) + "..."; + + QTab* tab = tabBar()->tabAt( i ); + int lw = fm.width( newTitle ); + int iw = 0; + if ( tab->iconSet() ) + iw = tab->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4; + + x += ( tabBar()->style().sizeFromContents( QStyle::CT_TabBarTab, this, QSize( QMAX( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), QStyleOption( tab ) ) ).width(); + } + return x; +} + +void TabWidget::slotSetTitle(Frame* frame, const QString& title) +{ + setTitle(title, frame->widget()); +} + +void TabWidget::setTitle( const QString &title , QWidget* sender) +{ + removeTabToolTip( sender ); + + uint lcw=0, rcw=0; + int tabBarHeight = tabBar()->sizeHint().height(); + if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() ) + lcw = QMAX( cornerWidget( TopLeft )->width(), tabBarHeight ); + if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() ) + rcw = QMAX( cornerWidget( TopRight )->width(), tabBarHeight ); + uint maxTabBarWidth = width() - lcw - rcw; + + uint newMaxLength=30; + for ( ; newMaxLength > 3; newMaxLength-- ) +{ + if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth ) + break; + } + QString newTitle = title; + if ( newTitle.length() > newMaxLength ) + { + setTabToolTip( sender, newTitle ); + newTitle = newTitle.left( newMaxLength-3 ) + "..."; + } + + newTitle.replace( '&', "&&" ); + if ( tabLabel( sender ) != newTitle ) + changeTab( sender, newTitle ); + + if( newMaxLength != d->CurrentMaxLength ) + { + for( int i = 0; i < count(); ++i) + { + Frame *f=d->frames[page(i)]; + newTitle=f->title(); + removeTabToolTip( page( i ) ); + if ( newTitle.length() > newMaxLength ) + { + setTabToolTip( page( i ), newTitle ); + newTitle = newTitle.left( newMaxLength-3 ) + "..."; + } + + newTitle.replace( '&', "&&" ); + if ( newTitle != tabLabel( page( i ) ) ) + changeTab( page( i ), newTitle ); + } + d->CurrentMaxLength = newMaxLength; + } +} + +void TabWidget::contextMenu(int i, const QPoint &p) +{ + QWidget* w = ActionManager::getInstance()->container("tab_popup"); + d->currentItem = page(i); + //kdDebug() << indexOf(d->currentItem) << endl; + if (w && indexOf(d->currentItem) != 0) + static_cast<QPopupMenu *>(w)->exec(p); + d->currentItem = 0; +} + +void TabWidget::slotDetachTab() +{ + if (!d->currentItem || indexOf(d->currentItem) == -1) + d->currentItem = currentPage(); + + if (indexOf(d->currentItem) == 0) + return; + + KURL url; + KHTMLView* view = dynamic_cast<KHTMLView*>(d->currentItem); + + if (!view) + return; + + url = view->part()->url(); + + kapp->invokeBrowser(url.url(), "0"); + slotCloseTab(); +} + +void TabWidget::slotCopyLinkAddress() +{ + if(!d->currentItem || indexOf(d->currentItem) == -1) + d->currentItem = currentPage(); + if(indexOf(d->currentItem) == 0) + return; + + KURL url; + KHTMLView* view = dynamic_cast<KHTMLView*>(d->currentItem); + + if (!view) + return; + + url = view->part()->url(); + + kapp->clipboard()->setText(url.prettyURL(), QClipboard::Selection); + kapp->clipboard()->setText(url.prettyURL(), QClipboard::Clipboard); +} + +void TabWidget::slotCloseTab() +{ + if (!d->currentItem || indexOf(d->currentItem) == -1) + d->currentItem = currentPage(); + if (indexOf(d->currentItem) == 0) + return; + if (d->frames.find(d->currentItem) != NULL) + removeFrame(d->frames.find(d->currentItem)); + delete d->currentItem; + d->currentItem = 0; +} + +void TabWidget::initiateDrag(int tab) +{ + if (tab == 0) // don't initiate drag for the main tab + return; + + Frame* frame = d->frames[page(tab)]; + + if (frame != 0) + { + KURL::List lst; + lst.append( frame->part()->url() ); + KURLDrag* drag = new KURLDrag( lst, this ); + drag->setPixmap( KMimeType::pixmapForURL( lst.first(), 0, KIcon::Small ) ); + drag->dragCopy(); + } +} + +void TabWidget::slotCloseRequest(QWidget* widget) +{ + if (d->frames.find(widget) != NULL) + removeFrame(d->frames.find(widget)); +} +} // namespace Akregator + +#include "tabwidget.moc" |