akregator/src

tabwidget.cpp
1/*
2 This file is part of Akregator.
3
4 Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
20 As a special exception, permission is given to link this program
21 with any edition of TQt, and distribute the resulting executable,
22 without including the source code for TQt in the source distribution.
23*/
24
25#include "tabwidget.h"
26
27#include <tqstyle.h>
28#include <tqapplication.h>
29#include <tqiconset.h>
30#include <tqclipboard.h>
31#include <tqmap.h>
32#include <tqptrdict.h>
33#include <tqstring.h>
34#include <tqtoolbutton.h>
35#include <tqtooltip.h>
36
37#include <tdeapplication.h>
38#include <kdebug.h>
39#include <ktabwidget.h>
40#include <ktabbar.h>
41#include <tdepopupmenu.h>
42#include <krun.h>
43#include <tdelocale.h>
44#include <tdehtmlview.h>
45#include <tdehtml_part.h>
46#include <kiconloader.h>
47#include <kurl.h>
48#include <kurldrag.h>
49#include <kmimetype.h>
50
51#include "actionmanager.h"
52#include "frame.h"
53#include "akregatorconfig.h"
54
55namespace Akregator {
56
57class TabWidget::TabWidgetPrivate
58{
59 public:
60 TQPtrDict<Frame> frames;
61 uint CurrentMaxLength;
62 TQWidget* currentItem;
63 TQToolButton* tabsClose;
64};
65
66TabWidget::TabWidget(TQWidget * parent, const char *name)
67 :KTabWidget(parent, name), d(new TabWidgetPrivate)
68{
69 d->CurrentMaxLength = 30;
70 d->currentItem = 0;
71 setMinimumSize(250,150);
72 setTabReorderingEnabled(false);
73 connect( this, TQ_SIGNAL( currentChanged(TQWidget *) ), this,
74 TQ_SLOT( slotTabChanged(TQWidget *) ) );
75 connect(this, TQ_SIGNAL(closeRequest(TQWidget*)), this, TQ_SLOT(slotCloseRequest(TQWidget*)));
76 setHoverCloseButton(Settings::closeButtonOnTabs());
77
78 d->tabsClose = new TQToolButton(this);
79 d->tabsClose->setAccel(TQKeySequence("Ctrl+W"));
80 connect( d->tabsClose, TQ_SIGNAL( clicked() ), this,
81 TQ_SLOT( slotRemoveCurrentFrame() ) );
82
83 d->tabsClose->setIconSet( SmallIconSet( "tab_remove" ) );
84 d->tabsClose->adjustSize();
85 TQToolTip::add(d->tabsClose, i18n("Close the current tab"));
86 setCornerWidget( d->tabsClose, TopRight );
87}
88
89TabWidget::~TabWidget()
90{
91 delete d;
92 d = 0;
93}
94
95void TabWidget::slotSettingsChanged()
96{
97 if (hoverCloseButton() != Settings::closeButtonOnTabs())
98 setHoverCloseButton(Settings::closeButtonOnTabs());
99}
100
101void TabWidget::slotNextTab()
102{
103 setCurrentPage((currentPageIndex()+1) % count());
104}
105
106void TabWidget::slotPreviousTab()
107{
108 if (currentPageIndex() == 0)
109 setCurrentPage(count()-1);
110 else
111 setCurrentPage(currentPageIndex()-1);
112}
113
114void TabWidget::addFrame(Frame *f)
115{
116 if (!f || !f->widget())
117 return;
118 d->frames.insert(f->widget(), f);
119 addTab(f->widget(), f->title());
120 connect(f, TQ_SIGNAL(titleChanged(Frame*, const TQString& )), this, TQ_SLOT(slotSetTitle(Frame*, const TQString& )));
121 slotSetTitle(f, f->title());
122}
123
124Frame *TabWidget::currentFrame()
125{
126 TQWidget* w = currentPage();
127
128 return w ? d->frames[w] : 0;
129}
130
131TQPtrList<Frame> TabWidget::frames() const
132{
133 TQPtrList<Frame> result;
134 TQPtrDictIterator<Frame> it(d->frames);
135 while (it.current())
136 {
137 result.append(it.current());
138 ++it;
139 }
140
141 return result;
142}
143
144void TabWidget::slotTabChanged(TQWidget *w)
145{
146 // FIXME: Don't hardcode the tab position of main frame
147 d->tabsClose->setDisabled(currentPageIndex() == 0);
148 emit currentFrameChanged(d->frames[w]);
149}
150
151void TabWidget::slotRemoveCurrentFrame()
152{
153 removeFrame(currentFrame());
154}
155
156void TabWidget::removeFrame(Frame *f)
157{
158 f->setCompleted();
159 d->frames.remove(f->widget());
160 removePage(f->widget());
161 delete f;
162 setTitle( currentFrame()->title(), currentPage() );
163}
164
165// copied wholesale from KonqFrameTabs
166uint TabWidget::tabBarWidthForMaxChars( uint maxLength )
167{
168 int hframe, overlap;
169 hframe = tabBar()->style().pixelMetric( TQStyle::PM_TabBarTabHSpace, this );
170 overlap = tabBar()->style().pixelMetric( TQStyle::PM_TabBarTabOverlap, this );
171
172 TQFontMetrics fm = tabBar()->fontMetrics();
173 int x = 0;
174 for( int i=0; i < count(); ++i ) {
175 Frame *f=d->frames[page(i)];
176 TQString newTitle=f->title();
177 if ( newTitle.length() > maxLength )
178 newTitle = newTitle.left( maxLength-3 ) + "...";
179
180 TQTab* tab = tabBar()->tabAt( i );
181 int lw = fm.width( newTitle );
182 int iw = 0;
183 if ( tab->iconSet() )
184 iw = tab->iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4;
185
186 x += ( tabBar()->style().sizeFromContents( TQStyle::CT_TabBarTab, this, TQSize( TQMAX( lw + hframe + iw, TQApplication::globalStrut().width() ), 0 ), TQStyleOption( tab ) ) ).width();
187 }
188 return x;
189}
190
191void TabWidget::slotSetTitle(Frame* frame, const TQString& title)
192{
193 setTitle(title, frame->widget());
194}
195
196void TabWidget::setTitle( const TQString &title , TQWidget* sender)
197{
198 removeTabToolTip( sender );
199
200 uint lcw=0, rcw=0;
201 int tabBarHeight = tabBar()->sizeHint().height();
202 if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() )
203 lcw = TQMAX( cornerWidget( TopLeft )->width(), tabBarHeight );
204 if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() )
205 rcw = TQMAX( cornerWidget( TopRight )->width(), tabBarHeight );
206 uint maxTabBarWidth = width() - lcw - rcw;
207
208 uint newMaxLength=30;
209 for ( ; newMaxLength > 3; newMaxLength-- )
210{
211 if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
212 break;
213 }
214 TQString newTitle = title;
215 if ( newTitle.length() > newMaxLength )
216 {
217 setTabToolTip( sender, newTitle );
218 newTitle = newTitle.left( newMaxLength-3 ) + "...";
219 }
220
221 newTitle.replace( '&', "&&" );
222 if ( tabLabel( sender ) != newTitle )
223 changeTab( sender, newTitle );
224
225 if( newMaxLength != d->CurrentMaxLength )
226 {
227 for( int i = 0; i < count(); ++i)
228 {
229 Frame *f=d->frames[page(i)];
230 newTitle=f->title();
231 removeTabToolTip( page( i ) );
232 if ( newTitle.length() > newMaxLength )
233 {
234 setTabToolTip( page( i ), newTitle );
235 newTitle = newTitle.left( newMaxLength-3 ) + "...";
236 }
237
238 newTitle.replace( '&', "&&" );
239 if ( newTitle != tabLabel( page( i ) ) )
240 changeTab( page( i ), newTitle );
241 }
242 d->CurrentMaxLength = newMaxLength;
243 }
244}
245
246void TabWidget::contextMenu(int i, const TQPoint &p)
247{
248 TQWidget* w = ActionManager::getInstance()->container("tab_popup");
249 d->currentItem = page(i);
250 //kdDebug() << indexOf(d->currentItem) << endl;
251 if (w && indexOf(d->currentItem) != 0)
252 static_cast<TQPopupMenu *>(w)->exec(p);
253 d->currentItem = 0;
254}
255
256void TabWidget::slotDetachTab()
257{
258 if (!d->currentItem || indexOf(d->currentItem) == -1)
259 d->currentItem = currentPage();
260
261 if (indexOf(d->currentItem) == 0)
262 return;
263
264 KURL url;
265 TDEHTMLView* view = dynamic_cast<TDEHTMLView*>(d->currentItem);
266
267 if (!view)
268 return;
269
270 url = view->part()->url();
271
272 tdeApp->invokeBrowser(url.url(), "0");
273 slotCloseTab();
274}
275
276void TabWidget::slotCopyLinkAddress()
277{
278 if(!d->currentItem || indexOf(d->currentItem) == -1)
279 d->currentItem = currentPage();
280 if(indexOf(d->currentItem) == 0)
281 return;
282
283 KURL url;
284 TDEHTMLView* view = dynamic_cast<TDEHTMLView*>(d->currentItem);
285
286 if (!view)
287 return;
288
289 url = view->part()->url();
290
291 tdeApp->clipboard()->setText(url.prettyURL(), TQClipboard::Selection);
292 tdeApp->clipboard()->setText(url.prettyURL(), TQClipboard::Clipboard);
293}
294
295void TabWidget::slotCloseTab()
296{
297 if (!d->currentItem || indexOf(d->currentItem) == -1)
298 d->currentItem = currentPage();
299 if (indexOf(d->currentItem) == 0)
300 return;
301 if (d->frames.find(d->currentItem) != NULL)
302 removeFrame(d->frames.find(d->currentItem));
303 delete d->currentItem;
304 d->currentItem = 0;
305}
306
307void TabWidget::initiateDrag(int tab)
308{
309 if (tab == 0) // don't initiate drag for the main tab
310 return;
311
312 Frame* frame = d->frames[page(tab)];
313
314 if (frame != 0)
315 {
316 KURL::List lst;
317 lst.append( frame->part()->url() );
318 KURLDrag* drag = new KURLDrag( lst, this );
319 drag->setPixmap( KMimeType::pixmapForURL( lst.first(), 0, TDEIcon::Small ) );
320 drag->dragCopy();
321 }
322}
323
324void TabWidget::slotCloseRequest(TQWidget* widget)
325{
326 if (d->frames.find(widget) != NULL)
327 removeFrame(d->frames.find(widget));
328}
329} // namespace Akregator
330
331#include "tabwidget.moc"