• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Konsole

ViewContainer.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of the Konsole Terminal.
00003     
00004     Copyright 2006-2008 Robert Knight <robertknight@gmail.com>
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
00019     02110-1301  USA.
00020 */
00021 
00022 // Own
00023 #include "ViewContainer.h"
00024 
00025 // Qt
00026 #include <QtCore/QHash>
00027 #include <QtGui/QLabel>
00028 #include <QtGui/QLineEdit>
00029 #include <QtGui/QBrush>
00030 #include <QtGui/QListWidget>
00031 #include <QtGui/QSplitter>
00032 #include <QtGui/QStackedWidget>
00033 #include <QtGui/QTabBar>
00034 #include <QtGui/QToolButton>
00035 #include <QtGui/QWidgetAction>
00036 
00037 #include <QtGui/QDrag>
00038 #include <QtGui/QDragMoveEvent>
00039 #include <QMimeData>
00040 
00041 // KDE 
00042 #include <KColorDialog>
00043 #include <kcolorscheme.h>
00044 #include <kcolorutils.h>
00045 #include <kdebug.h>
00046 #include <kconfiggroup.h>
00047 #include <KLocale>
00048 #include <KMenu>
00049 #include <KColorCollection>
00050 #include <KTabWidget>
00051 
00052 // Konsole
00053 #include "IncrementalSearchBar.h"
00054 #include "ViewProperties.h"
00055 
00056 // TODO Perhaps move everything which is Konsole-specific into different files
00057 #include "ProfileListWidget.h"
00058 
00059 using namespace Konsole;
00060 
00061 ViewContainer::ViewContainer(NavigationPosition position , QObject* parent)
00062     : QObject(parent)
00063     , _navigationDisplayMode(AlwaysShowNavigation)
00064     , _navigationPosition(position)
00065     , _searchBar(0)
00066 {
00067 }
00068 
00069 ViewContainer::~ViewContainer()
00070 {
00071     foreach( QWidget* view , _views ) 
00072     {
00073         disconnect(view,SIGNAL(destroyed(QObject*)),this,SLOT(viewDestroyed(QObject*)));
00074     }
00075 
00076     if (_searchBar) {
00077         _searchBar->deleteLater();
00078     }
00079 
00080     emit destroyed(this);
00081 }
00082 void ViewContainer::moveViewWidget( int , int ) {}
00083 void ViewContainer::setFeatures(Features features)
00084 { _features = features; }
00085 ViewContainer::Features ViewContainer::features() const
00086 { return _features; }
00087 void ViewContainer::moveActiveView( MoveDirection direction )
00088 {
00089     const int currentIndex = _views.indexOf( activeView() ) ;
00090     int newIndex = -1; 
00091 
00092     switch ( direction )
00093     {
00094         case MoveViewLeft:
00095             newIndex = qMax( currentIndex-1 , 0 );
00096             break;
00097         case MoveViewRight:
00098             newIndex = qMin( currentIndex+1 , _views.count() -1 );
00099             break;
00100     }
00101 
00102     Q_ASSERT( newIndex != -1 );
00103 
00104     moveViewWidget( currentIndex , newIndex );   
00105 
00106     _views.swap(currentIndex,newIndex);
00107 
00108     setActiveView( _views[newIndex] );
00109 }
00110 
00111 void ViewContainer::setNavigationDisplayMode(NavigationDisplayMode mode)
00112 {
00113     _navigationDisplayMode = mode;
00114     navigationDisplayModeChanged(mode);
00115 }
00116 ViewContainer::NavigationPosition ViewContainer::navigationPosition() const
00117 {
00118     return _navigationPosition;
00119 }
00120 void ViewContainer::setNavigationPosition(NavigationPosition position)
00121 {
00122     // assert that this position is supported
00123     Q_ASSERT( supportedNavigationPositions().contains(position) );
00124 
00125     _navigationPosition = position;
00126 
00127     navigationPositionChanged(position);
00128 }
00129 QList<ViewContainer::NavigationPosition> ViewContainer::supportedNavigationPositions() const
00130 {
00131     return QList<NavigationPosition>() << NavigationPositionTop;
00132 }
00133 ViewContainer::NavigationDisplayMode ViewContainer::navigationDisplayMode() const
00134 {
00135     return _navigationDisplayMode;
00136 }
00137 void ViewContainer::addView(QWidget* view , ViewProperties* item, int index)
00138 {
00139     if (index == -1)
00140         _views.append(view);
00141     else
00142         _views.insert(index,view);
00143 
00144     _navigation[view] = item;
00145 
00146     connect( view , SIGNAL(destroyed(QObject*)) , this , SLOT( viewDestroyed(QObject*) ) );
00147 
00148     addViewWidget(view,index);
00149 
00150     emit viewAdded(view,item);
00151 }
00152 void ViewContainer::viewDestroyed(QObject* object)
00153 {
00154     QWidget* widget = static_cast<QWidget*>(object);
00155 
00156     _views.removeAll(widget);
00157     _navigation.remove(widget);
00158 
00159     // FIXME This can result in ViewContainerSubClass::removeViewWidget() being 
00160     // called after the widget's parent has been deleted or partially deleted
00161     // in the ViewContainerSubClass instance's destructor.
00162     //
00163     // Currently deleteLater() is used to remove child widgets in the subclass 
00164     // constructors to get around the problem, but this is a hack and needs
00165     // to be fixed. 
00166     removeViewWidget(widget);
00167     
00168     emit viewRemoved(widget);
00169 
00170     if (_views.count() == 0)
00171         emit empty(this);
00172 }
00173 void ViewContainer::removeView(QWidget* view)
00174 {
00175     _views.removeAll(view);
00176     _navigation.remove(view);
00177 
00178     disconnect( view , SIGNAL(destroyed(QObject*)) , this , SLOT( viewDestroyed(QObject*) ) );
00179 
00180     removeViewWidget(view);
00181     
00182     emit viewRemoved(view);
00183 
00184     if (_views.count() == 0)
00185         emit empty(this);
00186 
00187 }
00188 
00189 const QList<QWidget*> ViewContainer::views()
00190 {
00191     return _views;
00192 }
00193 
00194 IncrementalSearchBar* ViewContainer::searchBar()
00195 {
00196     if (!_searchBar) {
00197         _searchBar = new IncrementalSearchBar( IncrementalSearchBar::AllFeatures , 0);
00198         _searchBar->setVisible(false);
00199         connect(_searchBar, SIGNAL(destroyed(QObject*)), this, SLOT(searchBarDestroyed()));
00200     }
00201     return _searchBar;
00202 }
00203 
00204 void ViewContainer::searchBarDestroyed()
00205 {
00206     _searchBar = 0;
00207 }
00208 
00209 void ViewContainer::activateNextView()
00210 {
00211     QWidget* active = activeView();
00212 
00213     int index = _views.indexOf(active);
00214 
00215     if ( index == -1 )
00216         return;
00217 
00218     if ( index == _views.count() - 1 )
00219         index = 0;
00220     else
00221         index++;
00222 
00223     setActiveView( _views.at(index) );
00224 }
00225 
00226 void ViewContainer::activatePreviousView()
00227 {
00228     QWidget* active = activeView();
00229 
00230     int index = _views.indexOf(active);
00231 
00232     if ( index == -1 ) 
00233         return;
00234 
00235     if ( index == 0 )
00236         index = _views.count() - 1;
00237     else
00238         index--;
00239 
00240     setActiveView( _views.at(index) );
00241 }
00242 
00243 ViewProperties* ViewContainer::viewProperties( QWidget* widget )
00244 {
00245     Q_ASSERT( _navigation.contains(widget) );
00246 
00247     return _navigation[widget];    
00248 }
00249 
00250 QList<QWidget*> ViewContainer::widgetsForItem(ViewProperties* item) const
00251 {
00252     return _navigation.keys(item);
00253 }
00254 
00255 ViewContainerTabBar::ViewContainerTabBar(QWidget* parent,TabbedViewContainer* container)
00256     : KTabBar(parent)
00257     , _container(container)
00258     , _dropIndicator(0)
00259     , _dropIndicatorIndex(-1)
00260     , _drawIndicatorDisabled(false)
00261 {
00262 }
00263 void ViewContainerTabBar::setDropIndicator(int index, bool drawDisabled)
00264 {
00265     if (!parentWidget() || _dropIndicatorIndex == index)
00266         return;
00267 
00268     _dropIndicatorIndex = index;
00269     const int ARROW_SIZE = 22;
00270     bool north = shape() == QTabBar::RoundedNorth || shape() == QTabBar::TriangularNorth;
00271 
00272     if (!_dropIndicator || _drawIndicatorDisabled != drawDisabled)
00273     {
00274         if (!_dropIndicator)
00275         {
00276             _dropIndicator = new QLabel(parentWidget());
00277             _dropIndicator->resize(ARROW_SIZE,ARROW_SIZE);
00278         }
00279 
00280         QIcon::Mode drawMode = drawDisabled ? QIcon::Disabled : QIcon::Normal;
00281         const QString iconName = north ? "arrow-up" : "arrow-down";
00282         _dropIndicator->setPixmap(KIcon(iconName).pixmap(ARROW_SIZE,ARROW_SIZE,drawMode));
00283         _drawIndicatorDisabled = drawDisabled;
00284     }
00285 
00286     if (index < 0)
00287     {
00288         _dropIndicator->hide();
00289         return;
00290     }
00291 
00292     const QRect rect = tabRect(index < count() ? index : index-1);
00293 
00294     QPoint pos;
00295     if (index < count())
00296         pos = rect.topLeft();
00297     else
00298         pos = rect.topRight();
00299 
00300     if (north)
00301         pos.ry() += ARROW_SIZE;
00302     else
00303         pos.ry() -= ARROW_SIZE; 
00304 
00305     pos.rx() -= ARROW_SIZE/2; 
00306 
00307     _dropIndicator->move(mapTo(parentWidget(),pos));
00308     _dropIndicator->show();
00309 
00310 }
00311 void ViewContainerTabBar::dragLeaveEvent(QDragLeaveEvent*)
00312 {
00313     setDropIndicator(-1);
00314 }
00315 void ViewContainerTabBar::dragEnterEvent(QDragEnterEvent* event)
00316 {
00317     if (event->mimeData()->hasFormat(ViewProperties::mimeType()) &&
00318         event->source() != 0)
00319         event->acceptProposedAction();    
00320 }
00321 void ViewContainerTabBar::dragMoveEvent(QDragMoveEvent* event)
00322 {
00323     if (event->mimeData()->hasFormat(ViewProperties::mimeType())
00324         && event->source() != 0)
00325     {
00326         int index = dropIndex(event->pos());
00327         if (index == -1)
00328             index = count();
00329 
00330         setDropIndicator(index,proposedDropIsSameTab(event));
00331 
00332         event->acceptProposedAction();
00333     }
00334 }
00335 int ViewContainerTabBar::dropIndex(const QPoint& pos) const
00336 {
00337     int tab = tabAt(pos);
00338     if (tab < 0)
00339         return tab;
00340 
00341     // pick the closest tab boundary 
00342     QRect rect = tabRect(tab);
00343     if ( (pos.x()-rect.left()) > (rect.width()/2) )
00344         tab++;
00345 
00346     if (tab == count())
00347         return -1;
00348 
00349     return tab;
00350 }
00351 bool ViewContainerTabBar::proposedDropIsSameTab(const QDropEvent* event) const
00352 {
00353     int index = dropIndex(event->pos());
00354     int droppedId = ViewProperties::decodeMimeData(event->mimeData());
00355     bool sameTabBar = event->source() == this;
00356 
00357     if (!sameTabBar)
00358         return false;
00359 
00360     const QList<QWidget*> viewList = _container->views();
00361     int sourceIndex = -1;
00362     for (int i=0;i<count();i++)
00363     {
00364         int idAtIndex = _container->viewProperties(viewList[i])->identifier();
00365         if (idAtIndex == droppedId)
00366             sourceIndex = i;
00367     }
00368 
00369     bool sourceAndDropAreLast = sourceIndex == count()-1 && index == -1;
00370     if (sourceIndex == index || sourceIndex == index-1 || sourceAndDropAreLast)
00371         return true;
00372     else
00373         return false;
00374 }
00375 void ViewContainerTabBar::dropEvent(QDropEvent* event)
00376 {
00377     setDropIndicator(-1);
00378 
00379     if (    !event->mimeData()->hasFormat(ViewProperties::mimeType())
00380         ||  proposedDropIsSameTab(event) )
00381     {
00382         event->ignore();
00383         return;
00384     }
00385 
00386     int index = dropIndex(event->pos());
00387     int droppedId = ViewProperties::decodeMimeData(event->mimeData());
00388     bool result = false;
00389     emit _container->moveViewRequest(index,droppedId,result);
00390     
00391     if (result)
00392         event->accept();
00393     else
00394         event->ignore();
00395 }
00396 
00397 QSize ViewContainerTabBar::tabSizeHint(int index) const
00398 {
00399      return QTabBar::tabSizeHint(index);
00400 }
00401 QPixmap ViewContainerTabBar::dragDropPixmap(int tab) 
00402 {
00403     Q_ASSERT(tab >= 0 && tab < count());
00404 
00405     // TODO - grabWidget() works except that it includes part
00406     // of the tab bar outside the tab itself if the tab has 
00407     // curved corners
00408     const QRect rect = tabRect(tab);
00409     const int borderWidth = 1;
00410 
00411     QPixmap tabPixmap(rect.width()+borderWidth,
00412                       rect.height()+borderWidth);
00413     QPainter painter(&tabPixmap);
00414     painter.drawPixmap(0,0,QPixmap::grabWidget(this,rect));
00415     QPen borderPen;
00416     borderPen.setBrush(palette().dark());
00417     borderPen.setWidth(borderWidth);
00418     painter.setPen(borderPen);
00419     painter.drawRect(0,0,rect.width(),rect.height());
00420     painter.end();
00421 
00422     return tabPixmap;
00423 }
00424 TabbedViewContainer::TabbedViewContainer(NavigationPosition position , QObject* parent) 
00425 : ViewContainer(position,parent)
00426 {
00427     _containerWidget = new QWidget;
00428     _stackWidget = new QStackedWidget();
00429     _tabBar = new ViewContainerTabBar(_containerWidget,this);
00430     _tabBar->setDrawBase(true);
00431 
00432     const int cornerButtonWidth = 50;
00433     _newTabButton = new KPushButton(KIcon("tab-new"),QString(),_containerWidget);
00434     // The button width here is hard coded, it would be better to use the value from
00435     // the current style (see QTabWidget::setUpLayout())
00436     _newTabButton->setFixedWidth(cornerButtonWidth);
00437     _newTabButton->setFlat(true);
00438     // new tab button is initially hidden, it will be shown when setFeatures() is called
00439     // with the QuickNewView flag enabled
00440     _newTabButton->setHidden(true);
00441    
00442     _closeTabButton = new KPushButton(KIcon("tab-close"),QString(),_containerWidget);
00443     _closeTabButton->setFixedWidth(cornerButtonWidth);
00444     _closeTabButton->setFlat(true);
00445     _closeTabButton->setHidden(true);
00446 
00447     connect( _tabBar , SIGNAL(currentChanged(int)) , this , SLOT(currentTabChanged(int)) );
00448     connect( _tabBar , SIGNAL(tabDoubleClicked(int)) , this , SLOT(tabDoubleClicked(int)) );
00449     connect( _tabBar , SIGNAL(newTabRequest()) , this , SIGNAL(newViewRequest()) );
00450     connect( _tabBar , SIGNAL(wheelDelta(int)) , this , SLOT(wheelScrolled(int)) );
00451     connect( _tabBar , SIGNAL(closeRequest(int)) , this , SLOT(closeTab(int)) );
00452     connect( _tabBar , SIGNAL(initiateDrag(int)) , this , SLOT(startTabDrag(int)) );
00453 
00454     connect( _newTabButton , SIGNAL(clicked()) , this , SIGNAL(newViewRequest()) );
00455     connect( _closeTabButton , SIGNAL(clicked()) , this , SLOT(closeCurrentTab()) );
00456 
00457     _layout = new TabbedViewContainerLayout;
00458     _layout->setSpacing(0);
00459     _layout->setMargin(0);
00460     _tabBarLayout = new QHBoxLayout;
00461     _tabBarLayout->setSpacing(0);
00462     _tabBarLayout->setMargin(0);
00463     _tabBarLayout->addWidget(_newTabButton);
00464     _tabBarLayout->addWidget(_tabBar);
00465     _tabBarLayout->addWidget(_closeTabButton); 
00466     _tabBarSpacer = new QSpacerItem(0,TabBarSpace);
00467 
00468     _layout->addWidget(_stackWidget);
00469     searchBar()->setParent(_containerWidget);
00470     if ( position == NavigationPositionTop )
00471     {
00472         _layout->insertLayout(0,_tabBarLayout);
00473         _layout->insertItemAt(0,_tabBarSpacer);
00474         _layout->insertWidget(-1,searchBar());
00475         _tabBar->setShape(QTabBar::RoundedNorth);
00476     }
00477     else if ( position == NavigationPositionBottom )
00478     {
00479         _layout->insertWidget(-1,searchBar());
00480         _layout->insertLayout(-1,_tabBarLayout);
00481         _layout->insertItemAt(-1,_tabBarSpacer);
00482         _tabBar->setShape(QTabBar::RoundedSouth);
00483     }
00484     else
00485         Q_ASSERT(false); // position not supported
00486 
00487     _containerWidget->setLayout(_layout);
00488 }
00489 void TabbedViewContainer::setNewViewMenu(QMenu* menu)
00490 {
00491   _newTabButton->setDelayedMenu(menu); 
00492 }
00493 ViewContainer::Features TabbedViewContainer::supportedFeatures() const
00494 { 
00495   return QuickNewView|QuickCloseView;
00496 }
00497 void TabbedViewContainer::setFeatures(Features features)
00498 {
00499     ViewContainer::setFeatures(features);
00500 
00501     const bool tabBarHidden = _tabBar->isHidden();
00502     _newTabButton->setVisible(!tabBarHidden && (features & QuickNewView));
00503     _closeTabButton->setVisible(!tabBarHidden && (features & QuickCloseView));
00504 }
00505 void TabbedViewContainer::closeCurrentTab()
00506 {
00507     if (_stackWidget->currentIndex() != -1)
00508     {
00509         closeTab(_stackWidget->currentIndex());
00510     }
00511 }
00512 void TabbedViewContainer::closeTab(int tab)
00513 {
00514     Q_ASSERT(tab >= 0 && tab < _stackWidget->count());
00515     
00516     if (viewProperties(_stackWidget->widget(tab))->confirmClose())
00517         removeView(_stackWidget->widget(tab));
00518 }
00519 void TabbedViewContainer::setTabBarVisible(bool visible)
00520 {
00521     _tabBar->setVisible(visible);
00522     _newTabButton->setVisible(visible && (features() & QuickNewView));
00523     _closeTabButton->setVisible(visible && (features() & QuickCloseView));
00524     if ( visible )
00525     {
00526         _tabBarSpacer->changeSize(0,TabBarSpace);
00527     }
00528     else
00529     {
00530         _tabBarSpacer->changeSize(0,0);
00531     } 
00532 }
00533 QList<ViewContainer::NavigationPosition> TabbedViewContainer::supportedNavigationPositions() const
00534 {
00535     return QList<NavigationPosition>() << NavigationPositionTop << NavigationPositionBottom;
00536 }
00537 void TabbedViewContainer::navigationPositionChanged(NavigationPosition position)
00538 {
00539     // this method assumes that there are only three items 
00540     // in the layout
00541     Q_ASSERT( _layout->count() == 4 );
00542 
00543     // index of stack widget in the layout when tab bar is at the bottom
00544     const int StackIndexWithTabBottom = 0;
00545 
00546     if ( position == NavigationPositionTop 
00547             && _layout->indexOf(_stackWidget) == StackIndexWithTabBottom )
00548     {
00549         _layout->removeItem(_tabBarLayout);
00550         _layout->removeItem(_tabBarSpacer);
00551         _layout->removeWidget(searchBar());
00552 
00553         _layout->insertLayout(0,_tabBarLayout);
00554         _layout->insertItemAt(0,_tabBarSpacer);
00555         _layout->insertWidget(-1,searchBar());
00556         _tabBar->setShape(QTabBar::RoundedNorth);
00557     }
00558     else if ( position == NavigationPositionBottom 
00559             && _layout->indexOf(_stackWidget) != StackIndexWithTabBottom )
00560     {
00561         _layout->removeItem(_tabBarLayout);
00562         _layout->removeItem(_tabBarSpacer);
00563         _layout->removeWidget(searchBar());
00564 
00565         _layout->insertWidget(-1,searchBar());
00566         _layout->insertLayout(-1,_tabBarLayout);
00567         _layout->insertItemAt(-1,_tabBarSpacer);
00568         _tabBar->setShape(QTabBar::RoundedSouth);
00569     }
00570 }
00571 void TabbedViewContainer::navigationDisplayModeChanged(NavigationDisplayMode mode)
00572 {
00573     if ( mode == AlwaysShowNavigation && _tabBar->isHidden() )
00574         setTabBarVisible(true);
00575 
00576     if ( mode == AlwaysHideNavigation && !_tabBar->isHidden() )
00577         setTabBarVisible(false);
00578 
00579     if ( mode == ShowNavigationAsNeeded )
00580         dynamicTabBarVisibility();
00581 }
00582 void TabbedViewContainer::dynamicTabBarVisibility()
00583 {
00584     if ( _tabBar->count() > 1 && _tabBar->isHidden() )
00585         setTabBarVisible(true);
00586 
00587     if ( _tabBar->count() < 2 && !_tabBar->isHidden() )
00588         setTabBarVisible(false);    
00589 }
00590 TabbedViewContainer::~TabbedViewContainer()
00591 {
00592     if (!_containerWidget.isNull())
00593         _containerWidget->deleteLater();
00594 }
00595 
00596 void TabbedViewContainer::startTabDrag(int tab)
00597 {
00598     QDrag* drag = new QDrag(_tabBar);
00599     const QRect tabRect = _tabBar->tabRect(tab);
00600     QPixmap tabPixmap = _tabBar->dragDropPixmap(tab); 
00601 
00602     drag->setPixmap(tabPixmap);
00603     
00604     int id = viewProperties(views()[tab])->identifier();
00605     QWidget* view = views()[tab];
00606     drag->setMimeData(ViewProperties::createMimeData(id));
00607 
00608     // start drag, if drag-and-drop is successful the view at 'tab' will be
00609     // deleted
00610     //
00611     // if the tab was dragged onto another application
00612     // which blindly accepted the drop then ignore it
00613     if (drag->exec() == Qt::MoveAction && drag->target() != 0)
00614     {
00615         // Deleting the view may cause the view container to be deleted, which
00616         // will also delete the QDrag object.
00617         // This can cause a crash if Qt's internal drag-and-drop handling
00618         // tries to delete it later.  
00619         //
00620         // For now set the QDrag's parent to 0 so that it won't be deleted if 
00621         // this view container is destroyed.
00622         //
00623         // FIXME: Resolve this properly
00624         drag->setParent(0);
00625         removeView(view);
00626     }
00627 }
00628 void TabbedViewContainer::tabDoubleClicked(int tab)
00629 {
00630     viewProperties( views()[tab] )->rename();
00631 }
00632 void TabbedViewContainer::moveViewWidget( int fromIndex , int toIndex )
00633 {
00634     QString text = _tabBar->tabText(fromIndex);
00635     QIcon icon = _tabBar->tabIcon(fromIndex);
00636    
00637     // FIXME - This will lose properties of the tab other than
00638     // their text and icon when moving them
00639     
00640     _tabBar->removeTab(fromIndex);
00641     _tabBar->insertTab(toIndex,icon,text);
00642 
00643     QWidget* widget = _stackWidget->widget(fromIndex);
00644     _stackWidget->removeWidget(widget);
00645     _stackWidget->insertWidget(toIndex,widget);
00646 }
00647 void TabbedViewContainer::currentTabChanged(int index)
00648 {
00649     _stackWidget->setCurrentIndex(index);
00650     if (_stackWidget->widget(index))
00651         emit activeViewChanged(_stackWidget->widget(index));
00652 
00653     // clear activity indicators
00654     setTabActivity(index,false);
00655 }
00656 
00657 void TabbedViewContainer::wheelScrolled(int delta)
00658 {
00659     if ( delta < 0 )
00660     activateNextView();
00661     else
00662     activatePreviousView();
00663 }
00664 
00665 QWidget* TabbedViewContainer::containerWidget() const
00666 {
00667     return _containerWidget;
00668 }
00669 QWidget* TabbedViewContainer::activeView() const
00670 {
00671     return _stackWidget->currentWidget();
00672 }
00673 void TabbedViewContainer::setActiveView(QWidget* view)
00674 {
00675     const int index = _stackWidget->indexOf(view);
00676 
00677     Q_ASSERT( index != -1 );
00678 
00679    _stackWidget->setCurrentWidget(view);
00680    _tabBar->setCurrentIndex(index); 
00681 }
00682 void TabbedViewContainer::addViewWidget( QWidget* view , int index)
00683 {
00684     _stackWidget->insertWidget(index,view);
00685     _stackWidget->updateGeometry();
00686 
00687     ViewProperties* item = viewProperties(view);
00688     connect( item , SIGNAL(titleChanged(ViewProperties*)) , this , 
00689                     SLOT(updateTitle(ViewProperties*))); 
00690     connect( item , SIGNAL(iconChanged(ViewProperties*) ) , this , 
00691                     SLOT(updateIcon(ViewProperties*)));
00692     connect( item , SIGNAL(activity(ViewProperties*)) , this ,
00693                     SLOT(updateActivity(ViewProperties*)));
00694 
00695     _tabBar->insertTab( index , item->icon() , item->title() );
00696 
00697     if ( navigationDisplayMode() == ShowNavigationAsNeeded )
00698         dynamicTabBarVisibility();
00699 }
00700 void TabbedViewContainer::removeViewWidget( QWidget* view )
00701 {
00702     if (!_stackWidget)
00703         return;
00704     const int index = _stackWidget->indexOf(view);
00705 
00706     Q_ASSERT( index != -1 );
00707 
00708     _stackWidget->removeWidget(view);
00709     _tabBar->removeTab(index);
00710 
00711     if ( navigationDisplayMode() == ShowNavigationAsNeeded )
00712         dynamicTabBarVisibility();
00713 }
00714 
00715 void TabbedViewContainer::setTabActivity(int index , bool activity)
00716 {
00717     const QPalette& palette = _tabBar->palette();
00718     KColorScheme colorScheme(palette.currentColorGroup());
00719     const QColor colorSchemeActive = colorScheme.foreground(KColorScheme::ActiveText).color();    
00720     
00721     const QColor normalColor = palette.text().color();
00722     const QColor activityColor = KColorUtils::mix(normalColor,colorSchemeActive); 
00723     
00724     QColor color = activity ? activityColor : QColor();
00725 
00726     if ( color != _tabBar->tabTextColor(index) )
00727         _tabBar->setTabTextColor(index,color);
00728 }
00729 
00730 void TabbedViewContainer::updateActivity(ViewProperties* item)
00731 {
00732     QListIterator<QWidget*> iter(widgetsForItem(item));
00733     while ( iter.hasNext() )
00734     {
00735         const int index = _stackWidget->indexOf(iter.next());
00736 
00737         if ( index != _stackWidget->currentIndex() )
00738         {
00739             setTabActivity(index,true);
00740         } 
00741     }
00742 }
00743 
00744 void TabbedViewContainer::updateTitle(ViewProperties* item)
00745 {
00746     // prevent tab titles from becoming overly-long as this limits the number
00747     // of tabs which can fit in the tab bar.  
00748     //
00749     // if the view's title is overly long then trim it and select the 
00750     // right-most 20 characters (assuming they contain the most useful
00751     // information) and insert an elide at the front
00752     const int MAX_TAB_TEXT_LENGTH = 20;
00753 
00754     QListIterator<QWidget*> iter(widgetsForItem(item));
00755     while ( iter.hasNext() )
00756     {
00757         const int index = _stackWidget->indexOf( iter.next() );
00758 
00759         QString tabText = item->title();
00760         if (tabText.count() > MAX_TAB_TEXT_LENGTH)
00761             tabText = tabText.right(MAX_TAB_TEXT_LENGTH).prepend("...");
00762 
00763         _tabBar->setTabText( index , tabText );
00764     }
00765 }
00766 void TabbedViewContainer::updateIcon(ViewProperties* item)
00767 {
00768     QListIterator<QWidget*> iter(widgetsForItem(item));
00769     while ( iter.hasNext() )
00770     {
00771         const int index = _stackWidget->indexOf( iter.next() );
00772         _tabBar->setTabIcon( index , item->icon() );
00773     }
00774 }
00775 
00776 StackedViewContainer::StackedViewContainer(QObject* parent) 
00777 : ViewContainer(NavigationPositionTop,parent)
00778 {
00779     _containerWidget = new QWidget;
00780     QVBoxLayout *layout = new QVBoxLayout(_containerWidget);
00781 
00782     _stackWidget = new QStackedWidget(_containerWidget);
00783 
00784     searchBar()->setParent(_containerWidget);
00785     layout->addWidget(searchBar());
00786     layout->addWidget(_stackWidget);
00787 }
00788 StackedViewContainer::~StackedViewContainer()
00789 {
00790     if (!_containerWidget.isNull())
00791         _containerWidget->deleteLater();
00792 }
00793 QWidget* StackedViewContainer::containerWidget() const
00794 {
00795     return _containerWidget;
00796 }
00797 QWidget* StackedViewContainer::activeView() const
00798 {
00799     return _stackWidget->currentWidget();
00800 }
00801 void StackedViewContainer::setActiveView(QWidget* view)
00802 {
00803    _stackWidget->setCurrentWidget(view); 
00804 }
00805 void StackedViewContainer::addViewWidget( QWidget* view , int )
00806 {
00807     _stackWidget->addWidget(view);
00808 }
00809 void StackedViewContainer::removeViewWidget( QWidget* view )
00810 {
00811     if (!_stackWidget)
00812         return;
00813     const int index = _stackWidget->indexOf(view);
00814 
00815     Q_ASSERT( index != -1);
00816 
00817     _stackWidget->removeWidget(view);
00818 }
00819 
00820 ListViewContainer::ListViewContainer(NavigationPosition position,QObject* parent)
00821     : ViewContainer(position,parent)
00822 {
00823     _splitter = new QSplitter;
00824     _listWidget = new ProfileListWidget(_splitter);
00825 
00826     QWidget *contentArea = new QWidget(_splitter);
00827     QVBoxLayout *layout = new QVBoxLayout(contentArea);
00828     _stackWidget = new QStackedWidget(contentArea);
00829     searchBar()->setParent(contentArea);
00830     layout->addWidget(_stackWidget);
00831     layout->addWidget(searchBar());
00832 
00833     // elide left is used because the most informative part of the session name is often
00834     // the rightmost part
00835     //
00836     // this means you get entries looking like:
00837     //
00838     // ...dirA ...dirB ...dirC  ( helpful )
00839     //
00840     // instead of
00841     //
00842     // johnSmith@comput... johnSmith@comput...  ( not so helpful )
00843     //
00844 
00845     _listWidget->setTextElideMode( Qt::ElideLeft );
00846     _listWidget->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
00847     _listWidget->setDragDropMode(QAbstractItemView::DragDrop);
00848     _splitter->addWidget(_listWidget);
00849     _splitter->addWidget(contentArea);
00850         
00851     connect( _listWidget , SIGNAL(currentRowChanged(int)) , this , SLOT(rowChanged(int)) ); 
00852 }
00853 
00854 ListViewContainer::~ListViewContainer()
00855 {
00856     _splitter->deleteLater();
00857 }
00858 
00859 QWidget* ListViewContainer::containerWidget() const
00860 {
00861     return _splitter;
00862 }
00863 
00864 QWidget* ListViewContainer::activeView() const
00865 {
00866     return _stackWidget->currentWidget();
00867 }
00868 
00869 QBrush ListViewContainer::randomItemBackground(int r)
00870 {
00871     int i = r%6;
00872 
00873     //and now for something truly unpleasant:
00874     static const int r1[] = {255,190,190,255,190,255};
00875     static const int r2[] = {255,180,180,255,180,255};
00876     static const int b1[] = {190,255,190,255,255,190};
00877     static const int b2[] = {180,255,180,255,255,180};
00878     static const int g1[] = {190,190,255,190,255,255};
00879     static const int g2[] = {180,180,255,180,255,255};
00880 
00881     // hardcoded assumes item height is 32px
00882     QLinearGradient gradient( QPoint(0,0) , QPoint(0,32) );
00883     gradient.setColorAt(0,QColor(r1[i],g1[i],b1[i],100));
00884     gradient.setColorAt(0.5,QColor(r2[i],g2[i],b2[i],100));
00885     gradient.setColorAt(1,QColor(r1[i],g1[i],b1[i],100));
00886     return QBrush(gradient);
00887 }
00888 
00889 void ListViewContainer::addViewWidget( QWidget* view , int )
00890 {
00891     _stackWidget->addWidget(view);
00892 
00893     ViewProperties* properties = viewProperties(view);
00894 
00895     QListWidgetItem* item = new QListWidgetItem(_listWidget);
00896     item->setText( properties->title() );
00897     item->setIcon( properties->icon() );
00898 
00899     const int randomIndex = _listWidget->count();
00900     item->setData( Qt::BackgroundRole , randomItemBackground(randomIndex) );
00901    
00902     connect( properties , SIGNAL(titleChanged(ViewProperties*)) , this , SLOT(updateTitle(ViewProperties*)));
00903     connect( properties , SIGNAL(iconChanged(ViewProperties*)) , this , SLOT(updateIcon(ViewProperties*)));
00904 }
00905 
00906 void ListViewContainer::removeViewWidget( QWidget* view )
00907 {
00908     if (!_stackWidget)
00909         return;
00910     int index = _stackWidget->indexOf(view);
00911     _stackWidget->removeWidget(view);
00912     delete _listWidget->takeItem( index );
00913 }
00914 
00915 void ListViewContainer::setActiveView( QWidget* view )
00916 {
00917     _stackWidget->setCurrentWidget(view);
00918     _listWidget->setCurrentRow(_stackWidget->indexOf(view));
00919 }
00920 
00921 void ListViewContainer::rowChanged( int row )
00922 {
00923     // row may be -1 if the last row has been removed from the model
00924     if ( row >= 0 )
00925     {
00926         _stackWidget->setCurrentIndex( row );
00927 
00928         emit activeViewChanged( _stackWidget->currentWidget() );
00929     }
00930 }
00931 
00932 void ListViewContainer::updateTitle( ViewProperties* properties )
00933 {
00934     QList<QWidget*> items = widgetsForItem(properties);
00935     QListIterator<QWidget*> itemIter(items);
00936 
00937     while ( itemIter.hasNext() )
00938     {
00939         int index = _stackWidget->indexOf( itemIter.next() );
00940         _listWidget->item( index )->setText( properties->title() );
00941     }
00942 }
00943 
00944 void ListViewContainer::updateIcon( ViewProperties* properties )
00945 {
00946     QList<QWidget*> items = widgetsForItem(properties);
00947     QListIterator<QWidget*> itemIter(items);
00948 
00949     while ( itemIter.hasNext() )
00950     {
00951         int index = _stackWidget->indexOf( itemIter.next() );
00952         _listWidget->item( index )->setIcon( properties->icon() );
00953     }
00954 }
00955 
00956 #include "ViewContainer.moc"

Konsole

Skip menu "Konsole"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • Konsole
  • Libraries
  •   libkonq
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal