00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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 QPtrList<Frame> TabWidget::frames() const
00131 {
00132 QPtrList<Frame> result;
00133 QPtrDictIterator<Frame> it(d->frames);
00134 while (it.current())
00135 {
00136 result.append(it.current());
00137 ++it;
00138 }
00139
00140 return result;
00141 }
00142
00143 void TabWidget::slotTabChanged(QWidget *w)
00144 {
00145
00146 d->tabsClose->setDisabled(currentPageIndex() == 0);
00147 emit currentFrameChanged(d->frames[w]);
00148 }
00149
00150 void TabWidget::slotRemoveCurrentFrame()
00151 {
00152 removeFrame(currentFrame());
00153 }
00154
00155 void TabWidget::removeFrame(Frame *f)
00156 {
00157 f->setCompleted();
00158 d->frames.remove(f->widget());
00159 removePage(f->widget());
00160 delete f;
00161 setTitle( currentFrame()->title(), currentPage() );
00162 }
00163
00164
00165 uint TabWidget::tabBarWidthForMaxChars( uint maxLength )
00166 {
00167 int hframe, overlap;
00168 hframe = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabHSpace, this );
00169 overlap = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabOverlap, this );
00170
00171 QFontMetrics fm = tabBar()->fontMetrics();
00172 int x = 0;
00173 for( int i=0; i < count(); ++i ) {
00174 Frame *f=d->frames[page(i)];
00175 QString newTitle=f->title();
00176 if ( newTitle.length() > maxLength )
00177 newTitle = newTitle.left( maxLength-3 ) + "...";
00178
00179 QTab* tab = tabBar()->tabAt( i );
00180 int lw = fm.width( newTitle );
00181 int iw = 0;
00182 if ( tab->iconSet() )
00183 iw = tab->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4;
00184
00185 x += ( tabBar()->style().sizeFromContents( QStyle::CT_TabBarTab, this, QSize( QMAX( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), QStyleOption( tab ) ) ).width();
00186 }
00187 return x;
00188 }
00189
00190 void TabWidget::slotSetTitle(Frame* frame, const QString& title)
00191 {
00192 setTitle(title, frame->widget());
00193 }
00194
00195 void TabWidget::setTitle( const QString &title , QWidget* sender)
00196 {
00197 removeTabToolTip( sender );
00198
00199 uint lcw=0, rcw=0;
00200 int tabBarHeight = tabBar()->sizeHint().height();
00201 if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() )
00202 lcw = QMAX( cornerWidget( TopLeft )->width(), tabBarHeight );
00203 if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() )
00204 rcw = QMAX( cornerWidget( TopRight )->width(), tabBarHeight );
00205 uint maxTabBarWidth = width() - lcw - rcw;
00206
00207 uint newMaxLength=30;
00208 for ( ; newMaxLength > 3; newMaxLength-- )
00209 {
00210 if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
00211 break;
00212 }
00213 QString newTitle = title;
00214 if ( newTitle.length() > newMaxLength )
00215 {
00216 setTabToolTip( sender, newTitle );
00217 newTitle = newTitle.left( newMaxLength-3 ) + "...";
00218 }
00219
00220 newTitle.replace( '&', "&&" );
00221 if ( tabLabel( sender ) != newTitle )
00222 changeTab( sender, newTitle );
00223
00224 if( newMaxLength != d->CurrentMaxLength )
00225 {
00226 for( int i = 0; i < count(); ++i)
00227 {
00228 Frame *f=d->frames[page(i)];
00229 newTitle=f->title();
00230 removeTabToolTip( page( i ) );
00231 if ( newTitle.length() > newMaxLength )
00232 {
00233 setTabToolTip( page( i ), newTitle );
00234 newTitle = newTitle.left( newMaxLength-3 ) + "...";
00235 }
00236
00237 newTitle.replace( '&', "&&" );
00238 if ( newTitle != tabLabel( page( i ) ) )
00239 changeTab( page( i ), newTitle );
00240 }
00241 d->CurrentMaxLength = newMaxLength;
00242 }
00243 }
00244
00245 void TabWidget::contextMenu(int i, const QPoint &p)
00246 {
00247 QWidget* w = ActionManager::getInstance()->container("tab_popup");
00248 d->currentItem = page(i);
00249
00250 if (w && indexOf(d->currentItem) != 0)
00251 static_cast<QPopupMenu *>(w)->exec(p);
00252 d->currentItem = 0;
00253 }
00254
00255 void TabWidget::slotDetachTab()
00256 {
00257 if (!d->currentItem || indexOf(d->currentItem) == -1)
00258 d->currentItem = currentPage();
00259
00260 if (indexOf(d->currentItem) == 0)
00261 return;
00262
00263 KURL url;
00264 KHTMLView* view = dynamic_cast<KHTMLView*>(d->currentItem);
00265
00266 if (!view)
00267 return;
00268
00269 url = view->part()->url();
00270
00271 kapp->invokeBrowser(url.url(), "0");
00272 slotCloseTab();
00273 }
00274
00275 void TabWidget::slotCopyLinkAddress()
00276 {
00277 if(!d->currentItem || indexOf(d->currentItem) == -1)
00278 d->currentItem = currentPage();
00279 if(indexOf(d->currentItem) == 0)
00280 return;
00281
00282 KURL url;
00283 KHTMLView* view = dynamic_cast<KHTMLView*>(d->currentItem);
00284
00285 if (!view)
00286 return;
00287
00288 url = view->part()->url();
00289
00290 kapp->clipboard()->setText(url.prettyURL(), QClipboard::Selection);
00291 kapp->clipboard()->setText(url.prettyURL(), QClipboard::Clipboard);
00292 }
00293
00294 void TabWidget::slotCloseTab()
00295 {
00296 if (!d->currentItem || indexOf(d->currentItem) == -1)
00297 d->currentItem = currentPage();
00298 if (indexOf(d->currentItem) == 0)
00299 return;
00300 if (d->frames.find(d->currentItem) != NULL)
00301 removeFrame(d->frames.find(d->currentItem));
00302 delete d->currentItem;
00303 d->currentItem = 0;
00304 }
00305
00306 void TabWidget::initiateDrag(int tab)
00307 {
00308 if (tab == 0)
00309 return;
00310
00311 Frame* frame = d->frames[page(tab)];
00312
00313 if (frame != 0)
00314 {
00315 KURL::List lst;
00316 lst.append( frame->part()->url() );
00317 KURLDrag* drag = new KURLDrag( lst, this );
00318 drag->setPixmap( KMimeType::pixmapForURL( lst.first(), 0, KIcon::Small ) );
00319 drag->dragCopy();
00320 }
00321 }
00322
00323 void TabWidget::slotCloseRequest(QWidget* widget)
00324 {
00325 if (d->frames.find(widget) != NULL)
00326 removeFrame(d->frames.find(widget));
00327 }
00328 }
00329
00330 #include "tabwidget.moc"