OSDN Git Service

remove code for KDE 3.1.x
[kita/kita.git] / kita / src / kitaui / tabwidgetbase.cpp
1 /***************************************************************************
2 *   Copyright (C) 2004 by Hideki Ikemoto , (c) 2004 by 421                *
3 *   ikemo@users.sourceforge.jp                                            *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 ***************************************************************************/
10
11 /* Basic class of Tab widget, Tab bar, and Dock widget. */
12
13 #include "tabwidgetbase.h"
14
15 #include "kita_misc.h"
16 #include "parsemisc.h"
17 #include "signalcollection.h"
18 #include "datmanager.h"
19
20 #include <klibloader.h>
21 #include <kpopupmenu.h>
22 #include <kdebug.h>
23 #include <kstdaccel.h>
24 #include <kaction.h>
25 #include <klocale.h>
26 #include <kkeydialog.h>
27 #include <kparts/dockmainwindow.h>
28 #include <kparts/factory.h>
29 #include <kdeversion.h>
30 #include <kglobal.h>
31 #include <kconfig.h>
32 #include <kstandarddirs.h>
33
34 #include <qapplication.h>
35 #include <qmessagebox.h>
36 #include <qptrlist.h>
37 #include <qfontmetrics.h>
38
39
40 /*--------------------------------------------------------------*/
41
42
43 KitaTabWidgetBase::KitaTabWidgetBase( QWidget* parent, const char* name, WFlags f )
44         : QTabWidget( parent, name, f )
45 {
46     connectSignals();
47     setupActions();
48
49     /* setup part manager */
50     m_manager = new KParts::PartManager( parent, this, "KitaPartManager" );
51     m_manager->addManagedTopLevelWidget( parent );
52 }
53
54
55 KitaTabWidgetBase::~KitaTabWidgetBase()
56 {
57     /* romove parts */
58     if ( m_manager && !( m_manager->parts() ->isEmpty() ) ) {
59         KParts::Part * part;
60         while ( ( part = m_manager->parts() ->getFirst() ) != NULL ) {
61             m_manager->removePart( part );
62             removePage( part->widget() );
63             delete part;
64         }
65     }
66     if ( m_manager ) delete m_manager;
67     m_manager = NULL;
68
69     /* remove widgets which don't belong to parts */
70     QWidget* view = currentPage();
71     while ( count() > 0 && view ) {
72         removePage( view );
73         delete view;
74         view = currentPage();
75     }
76 }
77
78
79 /* public */ /* virtual */
80 void KitaTabWidgetBase::addTab( QWidget* w, const QString& label )
81 {
82     KitaTabBase * tb = new KitaTabBase( label );  /* KitaTabBase is deleted automatically. */
83     static_cast< KitaTabBarBase* >( tabBar() ) ->adjustTabWidth( tb );
84     QTabWidget::addTab( w, tb );
85 }
86
87
88 /* public */ /* virtual */
89 void KitaTabWidgetBase::addTab( QWidget* w, const QIconSet & iconset, const QString& label )
90 {
91     KitaTabBase * tb = new KitaTabBase( label );  /* KitaTabBase is deleted automatically. */
92     tb->setIconSet( iconset );
93     static_cast< KitaTabBarBase* >( tabBar() ) ->adjustTabWidth( tb );
94     QTabWidget::addTab( w, tb );
95 }
96
97
98 /* public */ /* virtual */
99 void KitaTabWidgetBase::insertTab( QWidget* w, const QString& label, int index )
100 {
101     KitaTabBase * tb = new KitaTabBase( label );  /* KitaTabBase is deleted automatically. */
102     static_cast< KitaTabBarBase* >( tabBar() ) ->adjustTabWidth( tb );
103     QTabWidget::insertTab( w, tb, index );
104 }
105
106
107 /* public */ /* virtual */
108 void KitaTabWidgetBase::removePage( QWidget* w )
109 {
110     QTabWidget::removePage( w );
111     static_cast< KitaTabBarBase* >( tabBar() ) ->adjustTabWidth( NULL );
112 }
113
114
115 /* public */ /* virtual */
116 void KitaTabWidgetBase::setTabLabel( QWidget * w, const QString & label )
117 {
118     int idx = indexOf( w );
119     KitaTabBase* ktb = static_cast < KitaTabBase* >( tabBar() ->tabAt( idx ) );
120
121     if ( ktb->getFullText() != label ) {
122         ktb->setFullText( label );
123         QTabWidget::setTabLabel( w, label );
124         static_cast< KitaTabBarBase* >( tabBar() ) ->adjustTabWidth( NULL );
125     }
126 }
127
128
129 /* public slot  */
130 void KitaTabWidgetBase::slotCurrentChanged( QWidget * w )
131 {
132     if ( m_manager == NULL ) return ;
133     if ( w == NULL ) return ;
134     w->setActiveWindow();
135     w->setFocus();
136
137     KParts::Part* part = findPartFromWidget( w );
138     if ( part ) {
139         m_manager->setActivePart( part );
140     }
141 }
142
143
144 /* show url with part. */ /* public slot */
145 void KitaTabWidgetBase::slotShowPart( const KURL& url, const QString& libName, const QString& mimetype )
146 {
147     if ( m_manager == NULL ) return ;
148
149     KLibFactory *factory = KLibLoader::self() ->factory( libName );
150     if ( !factory ) {
151         QMessageBox::critical( parentWidget(), i18n( " Load Error" ),
152                                QString( i18n( "can't load %1." ) ).arg( libName ) );
153         return ;
154     }
155
156     if ( factory->inherits( "KParts::Factory" ) ) {
157         KParts::Part * part
158         = static_cast< KParts::Factory* >( factory ) ->createPart( this );
159         m_manager->addPart( part );
160         addTab( part->widget(), url.url() );
161         showPage( part->widget() );
162         setTabToolTip( currentPage(), url.url() );
163
164         KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( part );
165         if ( ext ) {
166             KParts::URLArgs arg( false, 0, 0, mimetype );
167             ext->setURLArgs( arg );
168         }
169
170         static_cast<KParts::ReadOnlyPart*>( part ) ->openURL( url );
171     }
172 }
173
174
175 /* close num-th tab       */
176 /* see also customEvent   */ /* public slot */
177 void KitaTabWidgetBase::slotCloseTab( int num )
178 {
179     CloseTabEvent * e = new CloseTabEvent( num );
180     QApplication::postEvent( this, e );  // Qt will delete it when done
181 }
182
183
184 /* Calling deleteWidget in the child part will be the
185    cause of crash.  So you need to call deleteWidget
186    via custom event.                                   */ /* protected */ /* virtual */
187 void KitaTabWidgetBase::customEvent( QCustomEvent * e )
188 {
189     if ( e->type() == EVENT_CloseTab ) {
190         deleteWidget ( page( static_cast< CloseTabEvent* >( e ) ->getIndex() ) );
191     }
192 }
193
194
195 /* protected */ /* virtual */
196 void KitaTabWidgetBase::deleteWidget( QWidget* w )
197 {
198     if ( w == NULL ) return ;
199
200     removePage( w );
201     KParts::Part* part = findPartFromWidget( w );
202     if ( part ) m_manager->removePart( part );
203     delete w;
204 }
205
206
207 /* protected */
208 KParts::Part* KitaTabWidgetBase::findPartFromWidget( QWidget* w )
209 {
210     if ( w == NULL ) return NULL;
211     if ( m_manager == NULL ) return NULL;
212     if ( m_manager->parts() ->isEmpty() ) return NULL;
213
214     KParts::Part *part;
215     QPtrListIterator<KParts::Part> it( *( m_manager->parts() ) );
216     while ( ( part = ( *it ) ) != NULL ) {
217         if ( part->widget() == w ) return part;
218         ++it;
219     }
220
221     return NULL;
222 }
223
224
225 /* private */
226 void KitaTabWidgetBase::connectSignals()
227 {
228     /* connect signals */
229     Kita::SignalCollection * signalCollection = Kita::SignalCollection::getInstance();
230
231     connect( this, SIGNAL( switchToBoard() ),
232              signalCollection, SIGNAL( switchToBoard() ) );
233
234     connect( this, SIGNAL( switchToSubject() ),
235              signalCollection, SIGNAL( switchToSubject() ) );
236
237     connect( this, SIGNAL( switchToThread() ),
238              signalCollection, SIGNAL( switchToThread() ) );
239
240     connect( this, SIGNAL( switchToKitanavi() ),
241              signalCollection, SIGNAL( switchToKitanavi() ) );
242
243     connect( this, SIGNAL( switchToImgview() ),
244              signalCollection, SIGNAL( switchToImgview() ) );
245
246     connect( this, SIGNAL( switchToWritedock() ),
247              signalCollection, SIGNAL( switchToWritedock() ) );
248
249     connect( this, SIGNAL( currentChanged ( QWidget * ) ),
250              SLOT( slotCurrentChanged ( QWidget * ) ) );
251
252     connect( this, SIGNAL( setMainStatusbar( const QString& ) ),
253              signalCollection, SIGNAL( setMainStatusbar ( const QString& ) ) );
254
255     connect( this, SIGNAL( setMainURLLine( const KURL& ) ),
256              signalCollection, SIGNAL( setMainURLLine( const KURL& ) ) );
257
258     connect( this, SIGNAL( setMainCaption( const QString& ) ),
259              signalCollection, SIGNAL( setMainCaption( const QString& ) ) );
260
261     connect( this, SIGNAL( openURLRequestExt(
262                                const KURL&, const KParts::URLArgs&, QString, int,
263                                const KURL& ) ),
264              signalCollection, SIGNAL( openURLRequestExt(
265                                            const KURL& , const KParts::URLArgs&, QString, int,
266                                            const KURL& ) ) );
267 }
268
269
270 /*------------------------------------*/
271 /* common tab actions */
272
273
274 /* private */
275 void KitaTabWidgetBase::setupActions()
276 {
277     actionCollection() ->setWidget( this );
278
279
280     QString str = i18n( "Configure S&hortcuts..." ) + "(" + QString( name() ) + ")";
281     new KAction( str,
282                  0,
283                  this,
284                  SLOT( slotConfigureKeys() ),
285                  actionCollection(),
286                  "tab_configkeys" );
287
288     new KAction( i18n( "Activate Next Tab" ),
289                  KStdAccel::tabNext(),
290                  this,
291                  SLOT( slotNextTab() ),
292                  actionCollection(),
293                  "tab_nexttab" );
294
295     new KAction( i18n( "Activate Previous Tab" ),
296                  KStdAccel::tabPrev(),
297                  this,
298                  SLOT( slotPrevTab() ),
299                  actionCollection(),
300                  "tab_prevtab" );
301
302     new KAction( i18n( "Close this tab" ),
303                  KStdAccel::close(),
304                  this,
305                  SLOT( slotCloseCurrentTab() ),
306                  actionCollection(),
307                  "tab_closetab" );
308
309     new KAction( i18n( "Close Other Tabs" ),
310                  0,
311                  this,
312                  SLOT( slotCloseOtherTab() ),
313                  actionCollection(),
314                  "tab_closeothertab" );
315
316     new KAction( i18n( "Close right tabs" ),
317                  0,
318                  this,
319                  SLOT( slotCloseRightTab() ),
320                  actionCollection(),
321                  "tab_closerighttab" );
322
323     new KAction( i18n( "Close left tabs" ),
324                  0,
325                  this,
326                  SLOT( slotCloseLeftTab() ),
327                  actionCollection(),
328                  "tab_closelefttab" );
329
330     new KAction( i18n( "Close all tabs" ),
331                  0,
332                  this,
333                  SLOT( slotCloseAllTab() ),
334                  actionCollection(),
335                  "tab_closealltab" );
336
337     new KAction( i18n( "Switch to Board" ),
338                  Key_1,
339                  this,
340                  SIGNAL( switchToBoard() ),
341                  actionCollection(),
342                  "tab_toboard" );
343
344     new KAction( i18n( "Switch to Subject" ),
345                  Key_2,
346                  this,
347                  SIGNAL( switchToSubject() ),
348                  actionCollection(),
349                  "tab_tosubject" );
350
351     new KAction( i18n( "Switch to Thread" ),
352                  Key_3,
353                  this,
354                  SIGNAL( switchToThread() ),
355                  actionCollection(),
356                  "tab_tothread" );
357
358     new KAction( i18n( "Switch to KitaNavi" ),
359                  Key_4,
360                  this,
361                  SIGNAL( switchToKitanavi() ),
362                  actionCollection(),
363                  "tab_tokitanavi" );
364
365     new KAction( i18n( "Switch to Imgviewer" ),
366                  Key_5,
367                  this,
368                  SIGNAL( switchToImgview() ),
369                  actionCollection(),
370                  "tab_toimgview" );
371
372     new KAction( i18n( "Switch to writedock" ),
373                  Key_6,
374                  this,
375                  SIGNAL( switchToWritedock() ),
376                  actionCollection(),
377                  "tab_towritedock" );
378 }
379
380
381
382 /* public slot */
383 void KitaTabWidgetBase::slotConfigureKeys()
384 {
385     QString str = "Tab Actions (" + QString( name() ) + ")";
386     KKeyDialog dlg( TRUE, this );
387     dlg.insert( actionCollection(), str );
388     dlg.configure();
389 }
390
391
392 /* public slot */
393 void KitaTabWidgetBase::slotPrevTab()
394 {
395     int max = count();
396     int curpage = currentPageIndex();
397     if ( max <= 1 ) return ;
398
399     if ( curpage == 0 ) setCurrentPage( max - 1 );
400     else setCurrentPage( curpage - 1 );
401 }
402
403 /* public slot */
404 void KitaTabWidgetBase::slotNextTab()
405 {
406     int max = count();
407     int curpage = currentPageIndex();
408     if ( max <= 1 ) return ;
409
410     if ( curpage == max - 1 ) setCurrentPage( 0 );
411     else setCurrentPage( curpage + 1 );
412 }
413
414
415 /* see also customEvent */ /* public slot */
416 void KitaTabWidgetBase::slotCloseCurrentTab()
417 {
418     slotCloseTab( currentPageIndex() );
419 }
420
421
422 /* see also customEvent */ /* public slot */
423 void KitaTabWidgetBase::slotCloseOtherTab( int idx )
424 {
425     int max = count();
426     if ( max == 0 ) return ;
427     if ( idx == -1 ) idx = currentPageIndex();
428
429     int i = 0;
430
431     while ( i < max && i != idx ) {
432         slotCloseTab( 0 );
433         i++;
434     }
435
436     i++;
437     while ( i < max ) {
438         slotCloseTab( 1 );
439         i++;
440     }
441 }
442
443
444 /* see also customEvent */ /* public slot */
445 void KitaTabWidgetBase::slotCloseRightTab( int idx )
446 {
447     int max = count();
448     if ( max == 0 ) return ;
449     if ( idx == -1 ) idx = currentPageIndex();
450
451     int i, i2;
452
453     i = i2 = idx + 1;
454     while ( i < max ) {
455         slotCloseTab( i2 );
456         i++;
457     }
458 }
459
460
461 /* see also customEvent */ /* public slot */
462 void KitaTabWidgetBase::slotCloseLeftTab( int idx )
463 {
464     int max = count();
465     if ( max == 0 ) return ;
466     if ( idx == -1 ) idx = currentPageIndex();
467
468     int i = 0;
469
470     while ( i < max && i != idx ) {
471         slotCloseTab( 0 );
472         i++;
473     }
474 }
475
476
477 /* see also customEvent */ /* public slot */
478 void KitaTabWidgetBase::slotCloseAllTab()
479 {
480     int max = count();
481     if ( max == 0 ) return ;
482
483     int i = 0;
484
485     while ( i < max ) {
486         slotCloseTab( 0 );
487         i++;
488     }
489 }
490
491
492
493
494
495 /*--------------------------------------------------------------------------------*/
496 /*--------------------------------------------------------------------------------*/
497 /*--------------------------------------------------------------------------------*/
498
499
500
501
502 KitaTabBarBase::KitaTabBarBase( QWidget* parent, const char* name ) : QTabBar( parent, name ) {}
503
504 KitaTabBarBase::~KitaTabBarBase() {}
505
506
507 /* protected */ /* virtual */
508 void KitaTabBarBase::mousePressEvent( QMouseEvent *e )
509 {
510     if ( e->button() == RightButton ) {
511         QTab * tab = selectTab( e->pos() );
512         if ( tab != NULL ) {
513             int idx = indexOf( tab->identifier() );
514             showPopupMenu( idx, mapToGlobal( e->pos() ) );
515             return ;
516         }
517     }
518     QTabBar::mousePressEvent( e );
519 }
520
521
522
523 /* private */ /* virtual */
524 void KitaTabBarBase::showPopupMenu( int idx, QPoint global )
525 {
526     enum{
527         MENU_CLOSE,
528         MENU_CLOSEOTHER,
529         MENU_CLOSELEFT,
530         MENU_CLOSERIGHT
531     };
532
533     KitaTabWidgetBase* tabwidget = static_cast<KitaTabWidgetBase*>( parentWidget() );
534     KActionCollection * collection = tabwidget->actionCollection();
535
536     KPopupMenu* popup = new KPopupMenu( this );
537     popup->clear();
538
539     popup->insertItem( i18n( "Close this tab" ) , MENU_CLOSE );
540     collection->action( "tab_prevtab" ) ->plug( popup );
541     collection->action( "tab_nexttab" ) ->plug( popup );
542     popup->insertSeparator();
543
544     popup->insertItem( i18n( "Close Other Tabs" ) , MENU_CLOSEOTHER );
545     popup->insertItem( i18n( "Close right tabs" ) , MENU_CLOSERIGHT );
546     popup->insertItem( i18n( "Close left tabs" ) , MENU_CLOSELEFT );
547     collection->action( "tab_closealltab" ) ->plug( popup );
548
549     popup->insertSeparator();
550     collection->action( "tab_configkeys" ) ->plug( popup );
551
552     int ret = popup->exec( global );
553     delete popup;
554
555     switch ( ret ) {
556     case MENU_CLOSE: tabwidget->slotCloseTab( idx ); break;
557     case MENU_CLOSEOTHER: tabwidget->slotCloseOtherTab( idx ); break;
558     case MENU_CLOSERIGHT: tabwidget->slotCloseRightTab( idx ); break;
559     case MENU_CLOSELEFT: tabwidget->slotCloseLeftTab( idx ); break;
560     }
561
562 }
563
564
565 /* public */
566 void KitaTabBarBase::adjustTabWidth( KitaTabBase* newTab )
567 {
568     if ( count() == 0 ) return ;
569     if ( tabAt( 0 ) ->text().length() == 0 ) return ; /* maybe this is image tab */
570
571     if ( !shrinkTab( newTab ) ) expandTab();
572 }
573
574
575 /* private */
576 bool KitaTabBarBase::shrinkTab( KitaTabBase* newTab )
577 {
578     const int minwidth = 240;
579     const int mrg = 32;
580
581     int beforewd = 0;
582     int afterwd = 0;
583     bool chgWidth = FALSE;
584     int tabnum = count();
585     if ( newTab ) ++tabnum;
586     unsigned int* lng = new unsigned int[ tabnum ];
587     int* tabwd = new int[ tabnum ];
588     KitaTabBase** ktb = new KitaTabBase * [ tabnum ];
589     int parentWidth = QMAX( minwidth, parentWidget() ->width() - mrg );
590     QFontMetrics fm( parentWidget() ->font() );
591     int tabmrg = tabAt( 0 ) ->rect().width() - fm.width( tabAt( 0 ) ->text() );
592
593     for ( int i = 0; i < count(); ++i ) ktb[ i ] = static_cast< KitaTabBase* >( tabAt( i ) );
594     if ( newTab ) ktb[ tabnum - 1 ] = newTab;
595
596     /* get the current width */
597     for ( int i = 0; i < tabnum; ++i ) {
598         lng[ i ] = ktb[ i ] ->text().length();
599         if ( lng[ i ] != ktb[ i ] ->getTextLng() ) lng[ i ] -= 2; /* remove the length of ".." */
600         tabwd[ i ] = fm.width( ktb[ i ] ->text() );
601         beforewd += ( tabwd[ i ] + tabmrg );
602     }
603     if ( beforewd <= parentWidth + mrg / 2 ) return FALSE;
604
605     afterwd = beforewd;
606     for ( ;; ) {
607
608         int maxwd;
609         int idx;
610
611         /* find the tab which has the largest width. */
612         maxwd = 0;
613         idx = -1;
614         for ( int i = 0; i < tabnum; ++i ) {
615             if ( lng[ i ] > 2 && tabwd[ i ] > maxwd ) {
616                 maxwd = tabwd[ i ];
617                 idx = i;
618             }
619         }
620         if ( idx == -1 ) break;
621
622         chgWidth = TRUE;
623         if ( lng[ idx ] == ktb[ idx ] ->getTextLng() ) lng[ idx ] = ktb[ idx ] ->getTextLng() - 3;
624         else --lng[ idx ];
625         afterwd -= tabwd[ idx ];
626         QString text = ktb[ idx ] ->getFullText().left( lng[ idx ] ) + "..";
627         tabwd[ idx ] = fm.width( text );
628         afterwd += tabwd[ idx ];
629
630         if ( afterwd <= parentWidth ) break;
631     }
632
633     /* set new texts */
634     if ( beforewd != afterwd && chgWidth ) {
635
636         for ( int i = 0; i < tabnum; ++i ) {
637
638             if ( lng[ i ] != ktb[ i ] ->text().length() ) {
639
640                 QString text = ktb[ i ] ->getFullText().left( lng[ i ] ) + "..";
641                 ktb[ i ] ->setText( text );
642             }
643         }
644     }
645
646     delete lng;
647     delete ktb;
648     delete tabwd;
649     return chgWidth;
650 }
651
652
653
654
655 /* private */
656 bool KitaTabBarBase::expandTab()
657 {
658     const int minwidth = 240;
659     const int mrg = 32;
660
661     int beforewd = 0;
662     int afterwd = 0;
663     bool chgWidth = FALSE;
664     int tabnum = count();
665     unsigned int* lng = new unsigned int[ tabnum ];
666     int* tabwd = new int[ tabnum ];
667     KitaTabBase** ktb = new KitaTabBase * [ tabnum ];
668     int parentWidth = QMAX( minwidth, parentWidget() ->width() - mrg );
669     QFontMetrics fm( parentWidget() ->font() );
670     int tabmrg = tabAt( 0 ) ->rect().width() - fm.width( tabAt( 0 ) ->text() );
671
672     for ( int i = 0; i < count(); ++i ) ktb[ i ] = static_cast< KitaTabBase* >( tabAt( i ) );
673
674     /* get the current width */
675     for ( int i = 0; i < tabnum; ++i ) {
676         lng[ i ] = ktb[ i ] ->text().length();
677         if ( lng[ i ] != ktb[ i ] ->getTextLng() ) lng[ i ] -= 2; /* remove the length of ".." */
678         tabwd[ i ] = fm.width( ktb[ i ] ->text() );
679         beforewd += ( tabwd[ i ] + tabmrg );
680     }
681     if ( parentWidth - mrg / 2 <= beforewd ) return FALSE;
682
683     afterwd = beforewd;
684     for ( ;; ) {
685
686         int minwd;
687         int idx;
688
689         /* find the tab which has the smallest width. */
690         minwd = parentWidth;
691         idx = -1;
692         for ( int i = 0; i < tabnum; ++i ) {
693             if ( lng[ i ] != ktb[ i ] ->getTextLng() && tabwd[ i ] < minwd ) {
694                 minwd = tabwd[ i ];
695                 idx = i;
696             }
697         }
698         if ( idx == -1 ) break;
699
700         chgWidth = TRUE;
701         if ( lng[ idx ] >= ktb[ idx ] ->getTextLng() - 3 ) lng[ idx ] = ktb[ idx ] ->getTextLng();
702         else ++lng[ idx ];
703         afterwd -= tabwd[ idx ];
704         QString text = ktb[ idx ] ->getFullText().left( lng[ idx ] );
705         if ( lng[ idx ] != ktb[ idx ] ->getTextLng() ) text += "..";
706         tabwd[ idx ] = fm.width( text );
707         afterwd += tabwd[ idx ];
708
709         if ( afterwd >= parentWidth ) break;
710     }
711
712     /* set new texts */
713     if ( beforewd != afterwd && chgWidth ) {
714
715         for ( int i = 0; i < tabnum; ++i ) {
716
717             if ( lng[ i ] != ktb[ i ] ->text().length() ) {
718
719                 QString fullText = ktb[ i ] ->getFullText();
720                 if ( lng[ i ] < ktb[ i ] ->getTextLng() ) ktb[ i ] ->setText( fullText.left( lng[ i ] ) + ".." );
721                 else ktb[ i ] ->setText( fullText );
722             }
723         }
724     }
725
726     delete lng;
727     delete ktb;
728     delete tabwd;
729     return chgWidth;
730 }
731
732
733 /* private */
734 int KitaTabBarBase::getWidthOfTabs()
735 {
736     int wd = 0;
737     for ( int i = 0; i < count(); ++i ) {
738         QTab* tb = tabAt( i );
739         wd += tb->rect().width();
740     }
741
742     return wd;
743 }
744
745
746
747 /*--------------------------------------------------------------------------------*/
748 /*--------------------------------------------------------------------------------*/
749 /*--------------------------------------------------------------------------------*/
750
751
752 KitaTabBase::KitaTabBase( const QString & text ) : QTab( text )
753 {
754     setFullText( text );
755 }
756
757 KitaTabBase::~KitaTabBase() {}
758
759
760 /* public */
761 QString KitaTabBase::getFullText() const
762 {
763     return m_fullText;
764 }
765
766
767 /* public */
768 const unsigned int KitaTabBase::getTextLng() const
769 {
770     return m_textlng;
771 }
772
773
774 /* public */
775 void KitaTabBase::setFullText( const QString& text )
776 {
777     m_fullText = text;
778     m_textlng = text.length();
779 }
780
781
782
783 /*--------------------------------------------------------------------------------*/
784 /*--------------------------------------------------------------------------------*/
785 /*--------------------------------------------------------------------------------*/
786
787
788
789 KitaDockWidgetBase::KitaDockWidgetBase( KDockManager* dockManager,
790                                         const char* name,
791                                         const QPixmap &pixmap,
792                                         QWidget* parent,
793                                         const QString& strCaption,
794                                         const QString& strTabPageLabel,
795                                         WFlags f )
796         : KDockWidget( dockManager, name, pixmap, parent, strCaption, strTabPageLabel, f )
797 {
798     setDockSite( KDockWidget::DockNone );
799     m_docked = TRUE;
800     m_parentDock = static_cast< KParts::DockMainWindow* >( parent );
801     m_closeButtonClicked = FALSE;
802
803     /* connect signals */
804     connect( this, SIGNAL( headerCloseButtonClicked() ), SLOT( slotHeaderCloseButtonClicked() ) );
805     connect( this, SIGNAL( iMBeingClosed() ), SLOT( slotSaveDocStatus() ) );
806
807     Kita::SignalCollection* signalCollection = Kita::SignalCollection::getInstance();
808
809     /* emit when this widget is deactivated */
810     connect( this, SIGNAL( windowDeactivated() ),
811              signalCollection, SIGNAL( windowDeactivated() ) );
812
813     /* If this widget is active and receives
814        signal isKitaActive, then emit signal kitaIsActive. */
815     /* see also KitaHTMLPart::slotOnURL                    */
816     connect( signalCollection, SIGNAL( isKitaActive() ),
817              this, SLOT( slotIsKitaActive() ) );
818
819     connect( this, SIGNAL( kitaIsActive() ),
820              signalCollection, SIGNAL( kitaIsActive() ) );
821 }
822
823
824 KitaDockWidgetBase::~KitaDockWidgetBase() {}
825
826
827 /* public slot */
828 void KitaDockWidgetBase::slotShowPart( const KURL& url, const QString& libName, const QString& mimetype )
829 {
830     slotShowDock( TRUE, TRUE );
831
832     static_cast<KitaTabWidgetBase*> ( getWidget() ) ->slotShowPart( url, libName, mimetype );
833 }
834
835
836 /* see also KitaMainWindow::KitaMainWindow() */ /* public */
837 void KitaDockWidgetBase::loadSession()
838 {
839     QString cfgPath = locateLocal( "appdata", "session.conf" );
840     KConfig cfg( cfgPath );
841     m_tabbed = cfg.readBoolEntry( name() + QString( "_Tabbed" ), FALSE );
842     m_docked = cfg.readBoolEntry( name() + QString( "_Docked" ), FALSE );
843 }
844
845
846 /* see also KitaMainWindow::~KitaMainWindow() */ /* public */
847 void KitaDockWidgetBase::saveSession()
848 {
849     /* copied from slotSaveDocStatus */
850     if ( isVisible() ) {
851         m_docked = FALSE;
852         m_tabbed = FALSE;
853         if ( parent() ) {
854             m_docked = TRUE;
855             if ( parentDockTabGroup() ) m_tabbed = TRUE;
856         }
857     }
858
859     QString cfgPath = locateLocal( "appdata", "session.conf" );
860     KConfig cfg( cfgPath );
861     cfg.writeEntry( name() + QString( "_Tabbed" ), m_tabbed );
862     cfg.writeEntry( name() + QString( "_Docked" ), m_docked );
863 }
864
865
866 /* see also KitaMainWindow::resetWindows() */ /* public */
867 void KitaDockWidgetBase::setSession( bool docked, bool tabbed )
868 {
869     m_docked = docked;
870     m_tabbed = tabbed;
871 }
872
873
874 /* save the current dock status.                      */
875 /* This slot is called before this widget is closed.  */
876 /* See also slotHeaderCloseButtonClicked(),           */
877 /* slotHideDock(), and closeEvent().                  */ /* private slot */
878 void KitaDockWidgetBase::slotSaveDocStatus()
879 {
880     if ( isVisible() ) {
881         m_docked = FALSE;
882         m_tabbed = FALSE;
883         /* This widget is docked.*/
884         if ( parent() ) {
885             m_docked = TRUE;
886             if ( parentDockTabGroup() ) m_tabbed = TRUE; /* This widget is in the tab group.*/
887         }
888
889         emit checkToggleAction( FALSE ); /* to KitaMainWindow. see also KitaMainWindow::setupView() */
890     }
891 }
892
893 /* This slot is called when user clicks the close button.      */
894 /* m_closeButtonClicked is set to prevent from re-openning     */
895 /* the dock. To reset m_closeButtonClicked, call showDock      */
896 /* with force = TRUE.   See also slotShowDock() and showDock() */ /* private slot */
897 void KitaDockWidgetBase::slotHeaderCloseButtonClicked()
898 {
899     m_closeButtonClicked = TRUE;
900     slotSaveDocStatus();
901 }
902
903
904 /* show this dock widget later.                   */
905 /* Usually, call this slot instead of showDock(). */
906 /* See also showDock() and customEvent().         */ /* public slot */
907 void KitaDockWidgetBase::slotShowDock( bool activate, bool force )
908 {
909     ShowDockEvent * e = new ShowDockEvent( activate, force );
910     QApplication::postEvent( this, e );  // Qt will delete it when done
911 }
912
913
914 /* show this dock widget immediately.          */
915 /* If activate is TRUE, activate this dock.    */
916 /* If force is TRUE, show this anyway.         */
917 /* If force is FALSE and tab has no children,  */
918 /* this dock is not shown.                     */ /* public */
919 void KitaDockWidgetBase::showDock( bool activate, bool force )
920 {
921     if ( force ) m_closeButtonClicked = FALSE; /* see also slotHeaderCloseButtonClicked() */
922     if ( m_closeButtonClicked ) return ;
923
924     QWidget* wd = getWidget();
925     KitaTabWidgetBase* w = NULL;
926     if ( wd && wd->inherits( "KitaTabWidgetBase" ) ) w = static_cast<KitaTabWidgetBase*> ( wd );
927     if ( !force && w && w->count() == 0 ) return ;
928
929     if ( !isVisible() ) {
930
931         if ( m_docked ) { /* This dock was docked to the other dock. */
932
933             /* Sometimes the dock widget loses the former brother DockWidget.
934                because the brogher widget had transformed. So, find and set new brogher widget here. */
935
936             /* find new brother dock widget */
937             KDockWidget * newBrsDock = dockManager() ->getDockWidgetFromName( "Thread" );
938
939             if ( newBrsDock ) {
940
941                 if ( !m_tabbed ) { /* This dock was not tabbed */
942
943                     /* Is thread dock on the tab? */
944                     QWidget * tmpwidget = newBrsDock->parentDockTabGroup();
945                     if ( tmpwidget ) {
946                         tmpwidget = tmpwidget->parentWidget();
947                         if ( tmpwidget->inherits( "KDockWidget" ) )
948                             newBrsDock = static_cast< KDockWidget* >( tmpwidget );
949                     }
950                 }
951
952                 setFormerBrotherDockWidget( newBrsDock );
953             }
954             makeDockVisible();
955         } else show();
956     }
957
958     if ( !activate ) return ;
959
960     if ( isMinimized() ) showNormal();
961     topLevelWidget() ->raise();
962     raise();
963     setActiveWindow();
964     emit checkToggleAction( TRUE ); /* to KitaMainWindow */
965
966     /* activate child Part */
967     if ( w ) w->slotCurrentChanged( w->currentPage() );
968     else if ( wd ) {
969         wd->setActiveWindow();
970         wd->setFocus();
971     }
972 }
973
974
975 /* public slot */
976 void KitaDockWidgetBase::slotHideDock()
977 {
978     if ( isVisible() ) {
979         slotSaveDocStatus();
980         m_parentDock->makeDockInvisible( this );
981     }
982 }
983
984
985 /* public slot */
986 void KitaDockWidgetBase::slotToggleShowHide()
987 {
988     if ( !isVisible() ) slotShowDock( TRUE, TRUE );
989     else slotHideDock();
990 }
991
992
993 /* when this widget is deactivated, emit signal
994    to popup vie SignalCollection.               */  /* protected */
995 void KitaDockWidgetBase::windowActivationChange ( bool )
996 {
997     if ( !isActiveWindow() ) emit windowDeactivated();
998 }
999
1000
1001 /* protected */
1002 void KitaDockWidgetBase::closeEvent( QCloseEvent* e )
1003 {
1004     slotSaveDocStatus();
1005     KDockWidget::closeEvent( e );
1006 }
1007
1008
1009 /* protected */ /* virtual */
1010 void KitaDockWidgetBase::customEvent( QCustomEvent * e )
1011 {
1012     if ( e->type() == EVENT_ShowDock ) {
1013         ShowDockEvent * sde = static_cast< ShowDockEvent* >( e );
1014         showDock( sde->getActivate(), sde->getForce() );
1015     }
1016 }
1017
1018
1019 /* see also KitaHTMLPart::slotOnURL */  /* private slot */
1020 void KitaDockWidgetBase::slotIsKitaActive()
1021 {
1022     if ( isActiveWindow() ) emit kitaIsActive();
1023 }
1024