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 void TabWidget::slotTabChanged(QWidget *w)
00131 {
00132
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
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
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)
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 }
00316
00317 #include "tabwidget.moc"