summaryrefslogtreecommitdiffstats
path: root/akregator/src/tabwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'akregator/src/tabwidget.cpp')
-rw-r--r--akregator/src/tabwidget.cpp331
1 files changed, 331 insertions, 0 deletions
diff --git a/akregator/src/tabwidget.cpp b/akregator/src/tabwidget.cpp
new file mode 100644
index 00000000..561b93e5
--- /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"