akregator/src

tabwidget.cpp

00001 /*
00002     This file is part of Akregator.
00003 
00004     Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
00023 */
00024 
00025 #include "tabwidget.h"
00026 
00027 #include <qstyle.h>
00028 #include <qapplication.h>
00029 #include <qiconset.h>
00030 #include <qclipboard.h>
00031 #include <qmap.h>
00032 #include <qptrdict.h>
00033 #include <qstring.h>
00034 #include <qtoolbutton.h>
00035 #include <qtooltip.h>
00036 
00037 #include <kapplication.h>
00038 #include <kdebug.h>
00039 #include <ktabwidget.h>
00040 #include <ktabbar.h>
00041 #include <kpopupmenu.h>
00042 #include <krun.h>
00043 #include <klocale.h>
00044 #include <khtmlview.h>
00045 #include <khtml_part.h>
00046 #include <kiconloader.h>
00047 #include <kurl.h>
00048 #include <kurldrag.h>
00049 #include <kmimetype.h>
00050 
00051 #include "actionmanager.h"
00052 #include "frame.h"
00053 #include "akregatorconfig.h"
00054 
00055 namespace Akregator {
00056 
00057 class TabWidget::TabWidgetPrivate
00058 {
00059     public:
00060     QPtrDict<Frame> frames;
00061     uint CurrentMaxLength;
00062     QWidget* currentItem;
00063     QToolButton* tabsClose;
00064 };
00065 
00066 TabWidget::TabWidget(QWidget * parent, const char *name)
00067         :KTabWidget(parent, name), d(new TabWidgetPrivate)
00068 {
00069     d->CurrentMaxLength = 30;
00070     setMinimumSize(250,150);
00071     setTabReorderingEnabled(false);
00072     connect( this, SIGNAL( currentChanged(QWidget *) ), this,
00073             SLOT( slotTabChanged(QWidget *) ) );
00074     connect(this, SIGNAL(closeRequest(QWidget*)), this, SLOT(slotCloseRequest(QWidget*)));
00075     setHoverCloseButton(Settings::closeButtonOnTabs());
00076 
00077     d->tabsClose = new QToolButton(this);
00078     d->tabsClose->setAccel(QKeySequence("Ctrl+W"));
00079     connect( d->tabsClose, SIGNAL( clicked() ), this,
00080             SLOT( slotRemoveCurrentFrame() ) );
00081 
00082     d->tabsClose->setIconSet( SmallIconSet( "tab_remove" ) );
00083     d->tabsClose->adjustSize();
00084     QToolTip::add(d->tabsClose, i18n("Close the current tab"));
00085     setCornerWidget( d->tabsClose, TopRight );
00086 }
00087 
00088 TabWidget::~TabWidget()
00089 {
00090     delete d;
00091     d = 0;
00092 }
00093 
00094 void TabWidget::slotSettingsChanged()
00095 {
00096     if (hoverCloseButton() != Settings::closeButtonOnTabs())
00097         setHoverCloseButton(Settings::closeButtonOnTabs());
00098 }
00099 
00100 void TabWidget::slotNextTab()
00101 {
00102     setCurrentPage((currentPageIndex()+1) % count());
00103 }
00104 
00105 void TabWidget::slotPreviousTab()
00106 {
00107     if (currentPageIndex() == 0)
00108         setCurrentPage(count()-1);
00109     else
00110         setCurrentPage(currentPageIndex()-1);
00111 }
00112 
00113 void TabWidget::addFrame(Frame *f)
00114 {
00115     if (!f || !f->widget()) 
00116         return;
00117     d->frames.insert(f->widget(), f);
00118     addTab(f->widget(), f->title());
00119     connect(f, SIGNAL(titleChanged(Frame*, const QString& )), this, SLOT(slotSetTitle(Frame*, const QString& )));
00120     slotSetTitle(f, f->title());
00121 }
00122 
00123 Frame *TabWidget::currentFrame()
00124 {
00125     QWidget* w = currentPage();
00126     
00127     return w ? d->frames[w] : 0;
00128 }
00129 
00130 void TabWidget::slotTabChanged(QWidget *w)
00131 {
00132     // FIXME: Don't hardcode the tab position of main frame
00133     d->tabsClose->setDisabled(currentPageIndex() == 0);
00134     emit currentFrameChanged(d->frames[w]);
00135 }
00136 
00137 void TabWidget::slotRemoveCurrentFrame()
00138 {
00139     removeFrame(currentFrame());
00140 }
00141 
00142 void TabWidget::removeFrame(Frame *f)
00143 {
00144     f->setCompleted();
00145     d->frames.remove(f->widget());
00146     removePage(f->widget());
00147     delete f;
00148     setTitle( currentFrame()->title(), currentPage() );
00149 }
00150 
00151 // copied wholesale from KonqFrameTabs
00152 uint TabWidget::tabBarWidthForMaxChars( uint maxLength )
00153 {
00154     int hframe, overlap;
00155     hframe = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabHSpace, this );
00156     overlap = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabOverlap, this );
00157 
00158     QFontMetrics fm = tabBar()->fontMetrics();
00159     int x = 0;
00160     for( int i=0; i < count(); ++i ) {
00161         Frame *f=d->frames[page(i)];
00162         QString newTitle=f->title();
00163         if ( newTitle.length() > maxLength )
00164             newTitle = newTitle.left( maxLength-3 ) + "...";
00165 
00166         QTab* tab = tabBar()->tabAt( i );
00167         int lw = fm.width( newTitle );
00168         int iw = 0;
00169         if ( tab->iconSet() )
00170             iw = tab->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4;
00171 
00172         x += ( tabBar()->style().sizeFromContents( QStyle::CT_TabBarTab, this,                             QSize( QMAX( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), QStyleOption( tab ) ) ).width();
00173     }
00174     return x;
00175 }
00176 
00177 void TabWidget::slotSetTitle(Frame* frame, const QString& title)
00178 {
00179     setTitle(title, frame->widget());
00180 }
00181 
00182 void TabWidget::setTitle( const QString &title , QWidget* sender)
00183 {
00184     removeTabToolTip( sender );
00185    
00186     uint lcw=0, rcw=0;
00187     int tabBarHeight = tabBar()->sizeHint().height();
00188     if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() )
00189         lcw = QMAX( cornerWidget( TopLeft )->width(), tabBarHeight );
00190     if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() )
00191         rcw = QMAX( cornerWidget( TopRight )->width(), tabBarHeight );
00192     uint maxTabBarWidth = width() - lcw - rcw;
00193 
00194     uint newMaxLength=30;
00195     for ( ; newMaxLength > 3; newMaxLength-- ) 
00196 {
00197         if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
00198             break;
00199     }
00200     QString newTitle = title;
00201     if ( newTitle.length() > newMaxLength )
00202     {
00203         setTabToolTip( sender, newTitle );
00204         newTitle = newTitle.left( newMaxLength-3 ) + "...";
00205     }
00206 
00207     newTitle.replace( '&', "&&" );
00208     if ( tabLabel( sender ) != newTitle )
00209         changeTab( sender, newTitle );
00210 
00211     if( newMaxLength != d->CurrentMaxLength )
00212     {
00213         for( int i = 0; i < count(); ++i)
00214         {
00215             Frame *f=d->frames[page(i)];
00216             newTitle=f->title();
00217             removeTabToolTip( page( i ) );
00218             if ( newTitle.length() > newMaxLength )
00219             {
00220                 setTabToolTip( page( i ), newTitle );
00221                 newTitle = newTitle.left( newMaxLength-3 ) + "...";
00222             }
00223 
00224             newTitle.replace( '&', "&&" );
00225             if ( newTitle != tabLabel( page( i ) ) )
00226                     changeTab( page( i ), newTitle );
00227         }
00228         d->CurrentMaxLength = newMaxLength;
00229     }
00230 }
00231 
00232 void TabWidget::contextMenu(int i, const QPoint &p)
00233 {
00234     QWidget* w = ActionManager::getInstance()->container("tab_popup");
00235     d->currentItem = page(i);
00236     //kdDebug() << indexOf(d->currentItem) << endl;
00237     if (w && indexOf(d->currentItem) != 0)
00238         static_cast<QPopupMenu *>(w)->exec(p);
00239     d->currentItem = 0;
00240 }
00241 
00242 void TabWidget::slotDetachTab()
00243 {
00244     if (!d->currentItem || indexOf(d->currentItem) == -1) 
00245         d->currentItem = currentPage();
00246 
00247     if (indexOf(d->currentItem) == 0) 
00248         return;
00249 
00250     KURL url;
00251     KHTMLView* view = dynamic_cast<KHTMLView*>(d->currentItem);
00252     
00253     if (!view)
00254         return;
00255 
00256     url = view->part()->url();
00257 
00258     kapp->invokeBrowser(url.url(), "0");
00259     slotCloseTab();
00260 }
00261 
00262 void TabWidget::slotCopyLinkAddress()
00263 {
00264     if(!d->currentItem || indexOf(d->currentItem) == -1) 
00265         d->currentItem = currentPage();
00266     if(indexOf(d->currentItem) == 0) 
00267         return;
00268 
00269     KURL url;
00270     KHTMLView* view = dynamic_cast<KHTMLView*>(d->currentItem);
00271     
00272     if (!view)
00273         return;
00274 
00275     url = view->part()->url();
00276     
00277     kapp->clipboard()->setText(url.prettyURL(), QClipboard::Selection);
00278     kapp->clipboard()->setText(url.prettyURL(), QClipboard::Clipboard);
00279 }
00280 
00281 void TabWidget::slotCloseTab()
00282 {
00283     if (!d->currentItem || indexOf(d->currentItem) == -1) 
00284         d->currentItem = currentPage();
00285     if (indexOf(d->currentItem) == 0) 
00286         return;
00287     if (d->frames.find(d->currentItem) != NULL)
00288         removeFrame(d->frames.find(d->currentItem));
00289     delete d->currentItem;
00290     d->currentItem = 0;
00291 }
00292 
00293 void TabWidget::initiateDrag(int tab)
00294 {
00295     if (tab == 0) // don't initiate drag for the main tab
00296         return;
00297         
00298     Frame* frame = d->frames[page(tab)];
00299   
00300     if (frame != 0)
00301     {
00302         KURL::List lst;
00303         lst.append( frame->part()->url() );
00304         KURLDrag* drag = new KURLDrag( lst, this );
00305         drag->setPixmap( KMimeType::pixmapForURL( lst.first(), 0, KIcon::Small ) );
00306         drag->dragCopy();
00307     }
00308 }
00309 
00310 void TabWidget::slotCloseRequest(QWidget* widget)
00311 {
00312     if (d->frames.find(widget) != NULL)
00313         removeFrame(d->frames.find(widget));
00314 }
00315 } // namespace Akregator
00316 
00317 #include "tabwidget.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys