00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "ViewContainer.h"
00024
00025
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
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
00053 #include "ViewProperties.h"
00054
00055
00056 #include "ProfileListWidget.h"
00057
00058 using namespace Konsole;
00059
00060 ViewContainer::ViewContainer(NavigationPosition position , QObject* parent)
00061 : QObject(parent)
00062 , _navigationDisplayMode(AlwaysShowNavigation)
00063 , _navigationPosition(position)
00064 {
00065 }
00066 ViewContainer::~ViewContainer()
00067 {
00068 foreach( QWidget* view , _views )
00069 {
00070 disconnect(view,SIGNAL(destroyed(QObject*)),this,SLOT(viewDestroyed(QObject*)));
00071 }
00072
00073 emit destroyed(this);
00074 }
00075 void ViewContainer::moveViewWidget( int , int ) {}
00076 void ViewContainer::setFeatures(Features features)
00077 { _features = features; }
00078 ViewContainer::Features ViewContainer::features() const
00079 { return _features; }
00080 void ViewContainer::moveActiveView( MoveDirection direction )
00081 {
00082 const int currentIndex = _views.indexOf( activeView() ) ;
00083 int newIndex = -1;
00084
00085 switch ( direction )
00086 {
00087 case MoveViewLeft:
00088 newIndex = qMax( currentIndex-1 , 0 );
00089 break;
00090 case MoveViewRight:
00091 newIndex = qMin( currentIndex+1 , _views.count() -1 );
00092 break;
00093 }
00094
00095 Q_ASSERT( newIndex != -1 );
00096
00097 moveViewWidget( currentIndex , newIndex );
00098
00099 _views.swap(currentIndex,newIndex);
00100
00101 setActiveView( _views[newIndex] );
00102 }
00103
00104 void ViewContainer::setNavigationDisplayMode(NavigationDisplayMode mode)
00105 {
00106 _navigationDisplayMode = mode;
00107 navigationDisplayModeChanged(mode);
00108 }
00109 ViewContainer::NavigationPosition ViewContainer::navigationPosition() const
00110 {
00111 return _navigationPosition;
00112 }
00113 void ViewContainer::setNavigationPosition(NavigationPosition position)
00114 {
00115
00116 Q_ASSERT( supportedNavigationPositions().contains(position) );
00117
00118 _navigationPosition = position;
00119
00120 navigationPositionChanged(position);
00121 }
00122 QList<ViewContainer::NavigationPosition> ViewContainer::supportedNavigationPositions() const
00123 {
00124 return QList<NavigationPosition>() << NavigationPositionTop;
00125 }
00126 ViewContainer::NavigationDisplayMode ViewContainer::navigationDisplayMode() const
00127 {
00128 return _navigationDisplayMode;
00129 }
00130 void ViewContainer::addView(QWidget* view , ViewProperties* item, int index)
00131 {
00132 if (index == -1)
00133 _views.append(view);
00134 else
00135 _views.insert(index,view);
00136
00137 _navigation[view] = item;
00138
00139 connect( view , SIGNAL(destroyed(QObject*)) , this , SLOT( viewDestroyed(QObject*) ) );
00140
00141 addViewWidget(view,index);
00142
00143 emit viewAdded(view,item);
00144 }
00145 void ViewContainer::viewDestroyed(QObject* object)
00146 {
00147 QWidget* widget = static_cast<QWidget*>(object);
00148
00149 _views.removeAll(widget);
00150 _navigation.remove(widget);
00151
00152
00153
00154
00155
00156
00157
00158
00159 removeViewWidget(widget);
00160
00161 emit viewRemoved(widget);
00162
00163 if (_views.count() == 0)
00164 emit empty(this);
00165 }
00166 void ViewContainer::removeView(QWidget* view)
00167 {
00168 _views.removeAll(view);
00169 _navigation.remove(view);
00170
00171 disconnect( view , SIGNAL(destroyed(QObject*)) , this , SLOT( viewDestroyed(QObject*) ) );
00172
00173 removeViewWidget(view);
00174
00175 emit viewRemoved(view);
00176
00177 if (_views.count() == 0)
00178 emit empty(this);
00179
00180 }
00181
00182 const QList<QWidget*> ViewContainer::views()
00183 {
00184 return _views;
00185 }
00186
00187 void ViewContainer::activateNextView()
00188 {
00189 QWidget* active = activeView();
00190
00191 int index = _views.indexOf(active);
00192
00193 if ( index == -1 )
00194 return;
00195
00196 if ( index == _views.count() - 1 )
00197 index = 0;
00198 else
00199 index++;
00200
00201 setActiveView( _views.at(index) );
00202 }
00203
00204 void ViewContainer::activatePreviousView()
00205 {
00206 QWidget* active = activeView();
00207
00208 int index = _views.indexOf(active);
00209
00210 if ( index == -1 )
00211 return;
00212
00213 if ( index == 0 )
00214 index = _views.count() - 1;
00215 else
00216 index--;
00217
00218 setActiveView( _views.at(index) );
00219 }
00220
00221 ViewProperties* ViewContainer::viewProperties( QWidget* widget )
00222 {
00223 Q_ASSERT( _navigation.contains(widget) );
00224
00225 return _navigation[widget];
00226 }
00227
00228 QList<QWidget*> ViewContainer::widgetsForItem(ViewProperties* item) const
00229 {
00230 return _navigation.keys(item);
00231 }
00232
00233 TabbedViewContainer::TabbedViewContainer(NavigationPosition position , QObject* parent) :
00234 ViewContainer(position,parent)
00235 ,_newSessionButton(0)
00236 ,_tabContextMenu(0)
00237 ,_tabSelectColorMenu(0)
00238 ,_tabColorSelector(0)
00239 ,_tabColorCells(0)
00240 ,_contextMenuTab(0)
00241 {
00242 _tabWidget = new KTabWidget();
00243 _tabContextMenu = new KMenu(_tabWidget);
00244
00245 _newSessionButton = new QToolButton(_tabWidget);
00246 _newSessionButton->setAutoRaise(true);
00247 _newSessionButton->setIcon( KIcon("tab-new") );
00248 _newSessionButton->setText( i18n("New") );
00249 _newSessionButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
00250 _newSessionButton->setPopupMode(QToolButton::MenuButtonPopup);
00251
00252 QToolButton* closeButton = new QToolButton(_tabWidget);
00253 closeButton->setIcon( KIcon("tab-close") );
00254 closeButton->setAutoRaise(true);
00255 connect( closeButton , SIGNAL(clicked()) , this , SLOT(closeTabClicked()) );
00256
00257 _tabWidget->setCornerWidget(_newSessionButton,Qt::TopLeftCorner);
00258 _tabWidget->setCornerWidget(closeButton,Qt::TopRightCorner);
00259
00260
00261 QString paletteName;
00262 QStringList availablePalettes = KColorCollection::installedCollections();
00263
00264 if (availablePalettes.contains("40.colors"))
00265 paletteName = "40.colors";
00266
00267 KColorCollection palette(paletteName);
00268
00269
00270
00271
00272
00273
00274 if ( palette.count() > 0 )
00275 {
00276 _tabColorCells = new KColorCells(_tabWidget,palette.count()/8,8);
00277
00278 for (int i=0;i<palette.count();i++)
00279 _tabColorCells->setColor(i,palette.color(i));
00280
00281
00282 _tabSelectColorMenu = new KMenu(_tabWidget);
00283 connect( _tabSelectColorMenu, SIGNAL(aboutToShow()) , this, SLOT(prepareColorCells()) );
00284 _tabColorSelector = new QWidgetAction(_tabSelectColorMenu);
00285 _tabColorSelector->setDefaultWidget(_tabColorCells);
00286
00287 _tabSelectColorMenu->addAction( _tabColorSelector );
00288
00289 connect(_tabColorCells,SIGNAL(colorSelected(int)),this,SLOT(selectTabColor()));
00290 connect(_tabColorCells,SIGNAL(colorSelected(int)),_tabContextMenu,SLOT(hide()));
00291
00292 QAction* action = _tabSelectColorMenu->menuAction();
00293
00294 action->setIcon( KIcon("colors") );
00295 action->setText( i18n("Select &Tab Color") );
00296
00297 _viewActions << action;
00298 }
00299 else
00300 {
00301
00302
00303 }
00304
00305
00306 connect( _tabWidget , SIGNAL(currentChanged(int)) , this , SLOT(currentTabChanged(int)) );
00307 connect( _tabWidget , SIGNAL(contextMenu(QWidget*,const QPoint&)),
00308 SLOT(showContextMenu(QWidget*,const QPoint&)));
00309 }
00310
00311
00312
00313 void TabbedViewContainer::currentTabChanged(int tab)
00314 {
00315 if ( tab >= 0 )
00316 {
00317 emit activeViewChanged( _tabWidget->widget(tab) );
00318 }
00319 }
00320
00321 void TabbedViewContainer::closeTabClicked()
00322 {
00323 emit closeRequest(_tabWidget->currentWidget());
00324 }
00325
00326 TabbedViewContainer::~TabbedViewContainer()
00327 {
00328 _tabContextMenu->deleteLater();
00329 _tabWidget->deleteLater();
00330 }
00331
00332 void TabbedViewContainer::setNewSessionMenu(QMenu* menu)
00333 {
00334 _newSessionButton->setMenu(menu);
00335 }
00336 void TabbedViewContainer::showContextMenu(QWidget* widget , const QPoint& position)
00337 {
00338
00339 _contextMenuTab = _tabWidget->indexOf(widget);
00340
00341
00342 _tabContextMenu->clear();
00343
00344 _tabContextMenu->popup( position );
00345 }
00346
00347 void TabbedViewContainer::prepareColorCells()
00348 {
00349
00350
00351 QColor activeTabColor = _tabWidget->tabTextColor( _contextMenuTab );
00352
00353 for (int i=0;i<_tabColorCells->count();i++)
00354 if ( activeTabColor == _tabColorCells->color(i) )
00355 {
00356 _tabColorCells->setSelected(i);
00357 break;
00358 }
00359 }
00360
00361 void TabbedViewContainer::addViewWidget( QWidget* view , int )
00362 {
00363 ViewProperties* item = viewProperties(view);
00364 connect( item , SIGNAL(titleChanged(ViewProperties*)) , this , SLOT(updateTitle(ViewProperties*)));
00365 connect( item , SIGNAL(iconChanged(ViewProperties*) ) , this ,SLOT(updateIcon(ViewProperties*)));
00366 _tabWidget->addTab( view , item->icon() , item->title() );
00367 }
00368 void TabbedViewContainer::removeViewWidget( QWidget* view )
00369 {
00370 const int index = _tabWidget->indexOf(view);
00371
00372 if ( index != -1 )
00373 _tabWidget->removeTab( index );
00374 }
00375
00376 void TabbedViewContainer::updateIcon(ViewProperties* item)
00377 {
00378 QList<QWidget*> items = widgetsForItem(item);
00379 QListIterator<QWidget*> itemIter(items);
00380
00381 while ( itemIter.hasNext() )
00382 {
00383 int index = _tabWidget->indexOf( itemIter.next() );
00384 _tabWidget->setTabIcon( index , item->icon() );
00385 }
00386 }
00387 void TabbedViewContainer::updateTitle(ViewProperties* item)
00388 {
00389 QList<QWidget*> items = widgetsForItem(item);
00390 QListIterator<QWidget*> itemIter(items);
00391
00392 while ( itemIter.hasNext() )
00393 {
00394 int index = _tabWidget->indexOf( itemIter.next() );
00395 _tabWidget->setTabText( index , item->title() );
00396 }
00397
00398 }
00399
00400 QWidget* TabbedViewContainer::containerWidget() const
00401 {
00402 return _tabWidget;
00403 }
00404
00405 QWidget* TabbedViewContainer::activeView() const
00406 {
00407 return _tabWidget->widget(_tabWidget->currentIndex());
00408 }
00409
00410 void TabbedViewContainer::setActiveView(QWidget* view)
00411 {
00412 _tabWidget->setCurrentWidget(view);
00413 }
00414
00415 void TabbedViewContainer::selectTabColor()
00416 {
00417 QColor color;
00418
00419
00420
00421 if ( _tabColorCells )
00422 {
00423 color = _tabColorCells->color(_tabColorCells->selectedIndex());
00424
00425 if (!color.isValid())
00426 return;
00427 }
00428 else
00429 {
00430 QColor defaultColor = _tabWidget->palette().color( QPalette::Foreground );
00431 QColor tempColor = _tabWidget->tabTextColor( _contextMenuTab );
00432
00433 if ( KColorDialog::getColor(tempColor,defaultColor,_tabWidget) == KColorDialog::Accepted )
00434 color = tempColor;
00435 else
00436 return;
00437 }
00438
00439 _tabWidget->setTabTextColor( _contextMenuTab , color );
00440 }
00441
00442 ViewContainerTabBar::ViewContainerTabBar(QWidget* parent,TabbedViewContainerV2* container)
00443 : KTabBar(parent)
00444 , _container(container)
00445 , _dropIndicator(0)
00446 , _dropIndicatorIndex(-1)
00447 , _drawIndicatorDisabled(false)
00448 {
00449 }
00450 void ViewContainerTabBar::setDropIndicator(int index, bool drawDisabled)
00451 {
00452 if (!parentWidget() || _dropIndicatorIndex == index)
00453 return;
00454
00455 _dropIndicatorIndex = index;
00456 const int ARROW_SIZE = 22;
00457 bool north = shape() == QTabBar::RoundedNorth || shape() == QTabBar::TriangularNorth;
00458
00459 if (!_dropIndicator || _drawIndicatorDisabled != drawDisabled)
00460 {
00461 if (!_dropIndicator)
00462 {
00463 _dropIndicator = new QLabel(parentWidget());
00464 _dropIndicator->resize(ARROW_SIZE,ARROW_SIZE);
00465 }
00466
00467 QIcon::Mode drawMode = drawDisabled ? QIcon::Disabled : QIcon::Normal;
00468 const QString iconName = north ? "arrow-up" : "arrow-down";
00469 _dropIndicator->setPixmap(KIcon(iconName).pixmap(ARROW_SIZE,ARROW_SIZE,drawMode));
00470 _drawIndicatorDisabled = drawDisabled;
00471 }
00472
00473 if (index < 0)
00474 {
00475 _dropIndicator->hide();
00476 return;
00477 }
00478
00479 const QRect rect = tabRect(index < count() ? index : index-1);
00480
00481 QPoint pos;
00482 if (index < count())
00483 pos = rect.topLeft();
00484 else
00485 pos = rect.topRight();
00486
00487 if (north)
00488 pos.ry() += ARROW_SIZE;
00489 else
00490 pos.ry() -= ARROW_SIZE;
00491
00492 pos.rx() -= ARROW_SIZE/2;
00493
00494 _dropIndicator->move(mapTo(parentWidget(),pos));
00495 _dropIndicator->show();
00496
00497 }
00498 void ViewContainerTabBar::dragLeaveEvent(QDragLeaveEvent*)
00499 {
00500 setDropIndicator(-1);
00501 }
00502 void ViewContainerTabBar::dragEnterEvent(QDragEnterEvent* event)
00503 {
00504 if (event->mimeData()->hasFormat(ViewProperties::mimeType()) &&
00505 event->source() != 0)
00506 event->acceptProposedAction();
00507 }
00508 void ViewContainerTabBar::dragMoveEvent(QDragMoveEvent* event)
00509 {
00510 if (event->mimeData()->hasFormat(ViewProperties::mimeType())
00511 && event->source() != 0)
00512 {
00513 int index = dropIndex(event->pos());
00514 if (index == -1)
00515 index = count();
00516
00517 setDropIndicator(index,proposedDropIsSameTab(event));
00518
00519 event->acceptProposedAction();
00520 }
00521 }
00522 int ViewContainerTabBar::dropIndex(const QPoint& pos) const
00523 {
00524 int tab = tabAt(pos);
00525 if (tab < 0)
00526 return tab;
00527
00528
00529 QRect rect = tabRect(tab);
00530 if ( (pos.x()-rect.left()) > (rect.width()/2) )
00531 tab++;
00532
00533 if (tab == count())
00534 return -1;
00535
00536 return tab;
00537 }
00538 bool ViewContainerTabBar::proposedDropIsSameTab(const QDropEvent* event) const
00539 {
00540 int index = dropIndex(event->pos());
00541 int droppedId = ViewProperties::decodeMimeData(event->mimeData());
00542 bool sameTabBar = event->source() == this;
00543
00544 if (!sameTabBar)
00545 return false;
00546
00547 const QList<QWidget*> viewList = _container->views();
00548 int sourceIndex = -1;
00549 for (int i=0;i<count();i++)
00550 {
00551 int idAtIndex = _container->viewProperties(viewList[i])->identifier();
00552 if (idAtIndex == droppedId)
00553 sourceIndex = i;
00554 }
00555
00556 bool sourceAndDropAreLast = sourceIndex == count()-1 && index == -1;
00557 if (sourceIndex == index || sourceIndex == index-1 || sourceAndDropAreLast)
00558 return true;
00559 else
00560 return false;
00561 }
00562 void ViewContainerTabBar::dropEvent(QDropEvent* event)
00563 {
00564 setDropIndicator(-1);
00565
00566 if ( !event->mimeData()->hasFormat(ViewProperties::mimeType())
00567 || proposedDropIsSameTab(event) )
00568 {
00569 event->ignore();
00570 return;
00571 }
00572
00573 int index = dropIndex(event->pos());
00574 int droppedId = ViewProperties::decodeMimeData(event->mimeData());
00575 bool result = false;
00576 emit _container->moveViewRequest(index,droppedId,result);
00577
00578 if (result)
00579 event->accept();
00580 else
00581 event->ignore();
00582 }
00583
00584 QSize ViewContainerTabBar::tabSizeHint(int index) const
00585 {
00586 return QTabBar::tabSizeHint(index);
00587 }
00588 QPixmap ViewContainerTabBar::dragDropPixmap(int tab)
00589 {
00590 Q_ASSERT(tab >= 0 && tab < count());
00591
00592
00593
00594
00595 const QRect rect = tabRect(tab);
00596 const int borderWidth = 1;
00597
00598 QPixmap tabPixmap(rect.width()+borderWidth,
00599 rect.height()+borderWidth);
00600 QPainter painter(&tabPixmap);
00601 painter.drawPixmap(0,0,QPixmap::grabWidget(this,rect));
00602 QPen borderPen;
00603 borderPen.setBrush(palette().dark());
00604 borderPen.setWidth(borderWidth);
00605 painter.setPen(borderPen);
00606 painter.drawRect(0,0,rect.width(),rect.height());
00607 painter.end();
00608
00609 return tabPixmap;
00610 }
00611 TabbedViewContainerV2::TabbedViewContainerV2(NavigationPosition position , QObject* parent)
00612 : ViewContainer(position,parent)
00613 {
00614 _containerWidget = new QWidget;
00615 _stackWidget = new QStackedWidget();
00616 _tabBar = new ViewContainerTabBar(_containerWidget,this);
00617 _tabBar->setDrawBase(true);
00618
00619 const int cornerButtonWidth = 50;
00620 _newTabButton = new KPushButton(KIcon("tab-new"),QString(),_containerWidget);
00621
00622
00623 _newTabButton->setFixedWidth(cornerButtonWidth);
00624 _newTabButton->setFlat(true);
00625
00626
00627 _newTabButton->setHidden(true);
00628
00629 _closeTabButton = new KPushButton(KIcon("tab-close"),QString(),_containerWidget);
00630 _closeTabButton->setFixedWidth(cornerButtonWidth);
00631 _closeTabButton->setFlat(true);
00632 _closeTabButton->setHidden(true);
00633
00634 connect( _tabBar , SIGNAL(currentChanged(int)) , this , SLOT(currentTabChanged(int)) );
00635 connect( _tabBar , SIGNAL(tabDoubleClicked(int)) , this , SLOT(tabDoubleClicked(int)) );
00636 connect( _tabBar , SIGNAL(newTabRequest()) , this , SIGNAL(newViewRequest()) );
00637 connect( _tabBar , SIGNAL(wheelDelta(int)) , this , SLOT(wheelScrolled(int)) );
00638 connect( _tabBar , SIGNAL(mouseMiddleClick(int)) , this , SLOT(closeTab(int)) );
00639 connect( _tabBar , SIGNAL(closeRequest(int)) , this , SLOT(closeTab(int)) );
00640 connect( _tabBar , SIGNAL(initiateDrag(int)) , this , SLOT(startTabDrag(int)) );
00641
00642 connect( _newTabButton , SIGNAL(clicked()) , this , SIGNAL(newViewRequest()) );
00643 connect( _closeTabButton , SIGNAL(clicked()) , this , SLOT(closeCurrentTab()) );
00644
00645 _layout = new TabbedViewContainerV2Layout;
00646 _layout->setSpacing(0);
00647 _layout->setMargin(0);
00648 _tabBarLayout = new QHBoxLayout;
00649 _tabBarLayout->setSpacing(0);
00650 _tabBarLayout->setMargin(0);
00651 _tabBarLayout->addWidget(_newTabButton);
00652 _tabBarLayout->addWidget(_tabBar);
00653 _tabBarLayout->addWidget(_closeTabButton);
00654 _tabBarSpacer = new QSpacerItem(0,TabBarSpace);
00655
00656 _layout->addWidget(_stackWidget);
00657
00658 if ( position == NavigationPositionTop )
00659 {
00660 _layout->insertLayout(0,_tabBarLayout);
00661 _layout->insertItemAt(0,_tabBarSpacer);
00662 _tabBar->setShape(QTabBar::RoundedNorth);
00663 }
00664 else if ( position == NavigationPositionBottom )
00665 {
00666 _layout->insertLayout(-1,_tabBarLayout);
00667 _layout->insertItemAt(-1,_tabBarSpacer);
00668 _tabBar->setShape(QTabBar::RoundedSouth);
00669 }
00670 else
00671 Q_ASSERT(false);
00672
00673 _containerWidget->setLayout(_layout);
00674 }
00675 void TabbedViewContainerV2::setNewViewMenu(QMenu* menu)
00676 { _newTabButton->setDelayedMenu(menu); }
00677 ViewContainer::Features TabbedViewContainerV2::supportedFeatures() const
00678 { return QuickNewView|QuickCloseView; }
00679 void TabbedViewContainerV2::setFeatures(Features features)
00680 {
00681 ViewContainer::setFeatures(features);
00682
00683 const bool tabBarHidden = _tabBar->isHidden();
00684 _newTabButton->setVisible(!tabBarHidden && (features & QuickNewView));
00685 _closeTabButton->setVisible(!tabBarHidden && (features & QuickCloseView));
00686 }
00687 void TabbedViewContainerV2::closeCurrentTab()
00688 {
00689 if (_stackWidget->currentIndex() != -1)
00690 {
00691 closeTab(_stackWidget->currentIndex());
00692 }
00693 }
00694 void TabbedViewContainerV2::closeTab(int tab)
00695 {
00696 Q_ASSERT(tab >= 0 && tab < _stackWidget->count());
00697
00698 if (viewProperties(_stackWidget->widget(tab))->confirmClose())
00699 removeView(_stackWidget->widget(tab));
00700 }
00701 void TabbedViewContainerV2::setTabBarVisible(bool visible)
00702 {
00703 _tabBar->setVisible(visible);
00704 _newTabButton->setVisible(visible && (features() & QuickNewView));
00705 _closeTabButton->setVisible(visible && (features() & QuickCloseView));
00706 if ( visible )
00707 {
00708 _tabBarSpacer->changeSize(0,TabBarSpace);
00709 }
00710 else
00711 {
00712 _tabBarSpacer->changeSize(0,0);
00713 }
00714 }
00715 QList<ViewContainer::NavigationPosition> TabbedViewContainerV2::supportedNavigationPositions() const
00716 {
00717 return QList<NavigationPosition>() << NavigationPositionTop << NavigationPositionBottom;
00718 }
00719 void TabbedViewContainerV2::navigationPositionChanged(NavigationPosition position)
00720 {
00721
00722
00723 Q_ASSERT( _layout->count() == 3 );
00724
00725
00726 const int StackIndexWithTabBottom = 0;
00727
00728 if ( position == NavigationPositionTop
00729 && _layout->indexOf(_stackWidget) == StackIndexWithTabBottom )
00730 {
00731 _layout->removeItem(_tabBarLayout);
00732 _layout->removeItem(_tabBarSpacer);
00733
00734 _layout->insertLayout(0,_tabBarLayout);
00735 _layout->insertItemAt(0,_tabBarSpacer);
00736 _tabBar->setShape(QTabBar::RoundedNorth);
00737 }
00738 else if ( position == NavigationPositionBottom
00739 && _layout->indexOf(_stackWidget) != StackIndexWithTabBottom )
00740 {
00741 _layout->removeItem(_tabBarLayout);
00742 _layout->removeItem(_tabBarSpacer);
00743
00744 _layout->insertLayout(-1,_tabBarLayout);
00745 _layout->insertItemAt(-1,_tabBarSpacer);
00746 _tabBar->setShape(QTabBar::RoundedSouth);
00747 }
00748 }
00749 void TabbedViewContainerV2::navigationDisplayModeChanged(NavigationDisplayMode mode)
00750 {
00751 if ( mode == AlwaysShowNavigation && _tabBar->isHidden() )
00752 setTabBarVisible(true);
00753
00754 if ( mode == AlwaysHideNavigation && !_tabBar->isHidden() )
00755 setTabBarVisible(false);
00756
00757 if ( mode == ShowNavigationAsNeeded )
00758 dynamicTabBarVisibility();
00759 }
00760 void TabbedViewContainerV2::dynamicTabBarVisibility()
00761 {
00762 if ( _tabBar->count() > 1 && _tabBar->isHidden() )
00763 setTabBarVisible(true);
00764
00765 if ( _tabBar->count() < 2 && !_tabBar->isHidden() )
00766 setTabBarVisible(false);
00767 }
00768 TabbedViewContainerV2::~TabbedViewContainerV2()
00769 {
00770 _containerWidget->deleteLater();
00771 }
00772
00773 void TabbedViewContainerV2::startTabDrag(int tab)
00774 {
00775 QDrag* drag = new QDrag(_tabBar);
00776 const QRect tabRect = _tabBar->tabRect(tab);
00777 QPixmap tabPixmap = _tabBar->dragDropPixmap(tab);
00778
00779 drag->setPixmap(tabPixmap);
00780
00781 int id = viewProperties(views()[tab])->identifier();
00782 QWidget* view = views()[tab];
00783 drag->setMimeData(ViewProperties::createMimeData(id));
00784
00785
00786
00787
00788
00789
00790 if (drag->exec() == Qt::MoveAction && drag->target() != 0)
00791 {
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 drag->setParent(0);
00802 removeView(view);
00803 }
00804 }
00805 void TabbedViewContainerV2::tabDoubleClicked(int tab)
00806 {
00807 viewProperties( views()[tab] )->rename();
00808 }
00809 void TabbedViewContainerV2::moveViewWidget( int fromIndex , int toIndex )
00810 {
00811 QString text = _tabBar->tabText(fromIndex);
00812 QIcon icon = _tabBar->tabIcon(fromIndex);
00813
00814
00815
00816
00817 _tabBar->removeTab(fromIndex);
00818 _tabBar->insertTab(toIndex,icon,text);
00819
00820 QWidget* widget = _stackWidget->widget(fromIndex);
00821 _stackWidget->removeWidget(widget);
00822 _stackWidget->insertWidget(toIndex,widget);
00823 }
00824 void TabbedViewContainerV2::currentTabChanged(int index)
00825 {
00826 _stackWidget->setCurrentIndex(index);
00827 if (_stackWidget->widget(index))
00828 emit activeViewChanged(_stackWidget->widget(index));
00829
00830
00831 setTabActivity(index,false);
00832 }
00833
00834 void TabbedViewContainerV2::wheelScrolled(int delta)
00835 {
00836 if ( delta < 0 )
00837 activateNextView();
00838 else
00839 activatePreviousView();
00840 }
00841
00842 QWidget* TabbedViewContainerV2::containerWidget() const
00843 {
00844 return _containerWidget;
00845 }
00846 QWidget* TabbedViewContainerV2::activeView() const
00847 {
00848 return _stackWidget->currentWidget();
00849 }
00850 void TabbedViewContainerV2::setActiveView(QWidget* view)
00851 {
00852 const int index = _stackWidget->indexOf(view);
00853
00854 Q_ASSERT( index != -1 );
00855
00856 _stackWidget->setCurrentWidget(view);
00857 _tabBar->setCurrentIndex(index);
00858 }
00859 void TabbedViewContainerV2::addViewWidget( QWidget* view , int index)
00860 {
00861 _stackWidget->insertWidget(index,view);
00862 _stackWidget->updateGeometry();
00863
00864 ViewProperties* item = viewProperties(view);
00865 connect( item , SIGNAL(titleChanged(ViewProperties*)) , this ,
00866 SLOT(updateTitle(ViewProperties*)));
00867 connect( item , SIGNAL(iconChanged(ViewProperties*) ) , this ,
00868 SLOT(updateIcon(ViewProperties*)));
00869 connect( item , SIGNAL(activity(ViewProperties*)) , this ,
00870 SLOT(updateActivity(ViewProperties*)));
00871
00872 _tabBar->insertTab( index , item->icon() , item->title() );
00873
00874 if ( navigationDisplayMode() == ShowNavigationAsNeeded )
00875 dynamicTabBarVisibility();
00876 }
00877 void TabbedViewContainerV2::removeViewWidget( QWidget* view )
00878 {
00879 const int index = _stackWidget->indexOf(view);
00880
00881 Q_ASSERT( index != -1 );
00882
00883 _stackWidget->removeWidget(view);
00884 _tabBar->removeTab(index);
00885
00886 if ( navigationDisplayMode() == ShowNavigationAsNeeded )
00887 dynamicTabBarVisibility();
00888 }
00889
00890 void TabbedViewContainerV2::setTabActivity(int index , bool activity)
00891 {
00892 const QPalette& palette = _tabBar->palette();
00893 KColorScheme colorScheme(palette.currentColorGroup());
00894 const QColor colorSchemeActive = colorScheme.foreground(KColorScheme::ActiveText).color();
00895
00896 const QColor normalColor = palette.text().color();
00897 const QColor activityColor = KColorUtils::mix(normalColor,colorSchemeActive);
00898
00899 QColor color = activity ? activityColor : QColor();
00900
00901 if ( color != _tabBar->tabTextColor(index) )
00902 _tabBar->setTabTextColor(index,color);
00903 }
00904
00905 void TabbedViewContainerV2::updateActivity(ViewProperties* item)
00906 {
00907 QListIterator<QWidget*> iter(widgetsForItem(item));
00908 while ( iter.hasNext() )
00909 {
00910 const int index = _stackWidget->indexOf(iter.next());
00911
00912 if ( index != _stackWidget->currentIndex() )
00913 {
00914 setTabActivity(index,true);
00915 }
00916 }
00917 }
00918
00919 void TabbedViewContainerV2::updateTitle(ViewProperties* item)
00920 {
00921
00922
00923
00924
00925
00926
00927 const int MAX_TAB_TEXT_LENGTH = 20;
00928
00929 QListIterator<QWidget*> iter(widgetsForItem(item));
00930 while ( iter.hasNext() )
00931 {
00932 const int index = _stackWidget->indexOf( iter.next() );
00933
00934 QString tabText = item->title();
00935 if (tabText.count() > MAX_TAB_TEXT_LENGTH)
00936 tabText = tabText.right(MAX_TAB_TEXT_LENGTH).prepend("...");
00937
00938 _tabBar->setTabText( index , tabText );
00939 }
00940 }
00941 void TabbedViewContainerV2::updateIcon(ViewProperties* item)
00942 {
00943 QListIterator<QWidget*> iter(widgetsForItem(item));
00944 while ( iter.hasNext() )
00945 {
00946 const int index = _stackWidget->indexOf( iter.next() );
00947 _tabBar->setTabIcon( index , item->icon() );
00948 }
00949 }
00950
00951 StackedViewContainer::StackedViewContainer(QObject* parent)
00952 : ViewContainer(NavigationPositionTop,parent)
00953 {
00954 _stackWidget = new QStackedWidget;
00955 }
00956 StackedViewContainer::~StackedViewContainer()
00957 {
00958 _stackWidget->deleteLater();
00959 }
00960 QWidget* StackedViewContainer::containerWidget() const
00961 {
00962 return _stackWidget;
00963 }
00964 QWidget* StackedViewContainer::activeView() const
00965 {
00966 return _stackWidget->currentWidget();
00967 }
00968 void StackedViewContainer::setActiveView(QWidget* view)
00969 {
00970 _stackWidget->setCurrentWidget(view);
00971 }
00972 void StackedViewContainer::addViewWidget( QWidget* view , int )
00973 {
00974 _stackWidget->addWidget(view);
00975 }
00976 void StackedViewContainer::removeViewWidget( QWidget* view )
00977 {
00978 const int index = _stackWidget->indexOf(view);
00979
00980 Q_ASSERT( index != -1);
00981
00982 _stackWidget->removeWidget(view);
00983 }
00984
00985 ListViewContainer::ListViewContainer(NavigationPosition position,QObject* parent)
00986 : ViewContainer(position,parent)
00987 {
00988 _splitter = new QSplitter;
00989 _stackWidget = new QStackedWidget(_splitter);
00990 _listWidget = new ProfileListWidget(_splitter);
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 _listWidget->setTextElideMode( Qt::ElideLeft );
01005 _listWidget->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
01006 _listWidget->setDragDropMode(QAbstractItemView::DragDrop);
01007 _splitter->addWidget(_listWidget);
01008 _splitter->addWidget(_stackWidget);
01009
01010 connect( _listWidget , SIGNAL(currentRowChanged(int)) , this , SLOT(rowChanged(int)) );
01011 }
01012
01013 ListViewContainer::~ListViewContainer()
01014 {
01015 _splitter->deleteLater();
01016 }
01017
01018 QWidget* ListViewContainer::containerWidget() const
01019 {
01020 return _splitter;
01021 }
01022
01023 QWidget* ListViewContainer::activeView() const
01024 {
01025 return _stackWidget->currentWidget();
01026 }
01027
01028 QBrush ListViewContainer::randomItemBackground(int r)
01029 {
01030 int i = r%6;
01031
01032
01033 static const int r1[] = {255,190,190,255,190,255};
01034 static const int r2[] = {255,180,180,255,180,255};
01035 static const int b1[] = {190,255,190,255,255,190};
01036 static const int b2[] = {180,255,180,255,255,180};
01037 static const int g1[] = {190,190,255,190,255,255};
01038 static const int g2[] = {180,180,255,180,255,255};
01039
01040
01041 QLinearGradient gradient( QPoint(0,0) , QPoint(0,32) );
01042 gradient.setColorAt(0,QColor(r1[i],g1[i],b1[i],100));
01043 gradient.setColorAt(0.5,QColor(r2[i],g2[i],b2[i],100));
01044 gradient.setColorAt(1,QColor(r1[i],g1[i],b1[i],100));
01045 return QBrush(gradient);
01046 }
01047
01048 void ListViewContainer::addViewWidget( QWidget* view , int )
01049 {
01050 _stackWidget->addWidget(view);
01051
01052 ViewProperties* properties = viewProperties(view);
01053
01054 QListWidgetItem* item = new QListWidgetItem(_listWidget);
01055 item->setText( properties->title() );
01056 item->setIcon( properties->icon() );
01057
01058 const int randomIndex = _listWidget->count();
01059 item->setData( Qt::BackgroundRole , randomItemBackground(randomIndex) );
01060
01061 connect( properties , SIGNAL(titleChanged(ViewProperties*)) , this , SLOT(updateTitle(ViewProperties*)));
01062 connect( properties , SIGNAL(iconChanged(ViewProperties*)) , this , SLOT(updateIcon(ViewProperties*)));
01063 }
01064
01065 void ListViewContainer::removeViewWidget( QWidget* view )
01066 {
01067 int index = _stackWidget->indexOf(view);
01068 _stackWidget->removeWidget(view);
01069 delete _listWidget->takeItem( index );
01070 }
01071
01072 void ListViewContainer::setActiveView( QWidget* view )
01073 {
01074 _stackWidget->setCurrentWidget(view);
01075 _listWidget->setCurrentRow(_stackWidget->indexOf(view));
01076 }
01077
01078 void ListViewContainer::rowChanged( int row )
01079 {
01080
01081 if ( row >= 0 )
01082 {
01083 _stackWidget->setCurrentIndex( row );
01084
01085 emit activeViewChanged( _stackWidget->currentWidget() );
01086 }
01087 }
01088
01089 void ListViewContainer::updateTitle( ViewProperties* properties )
01090 {
01091 QList<QWidget*> items = widgetsForItem(properties);
01092 QListIterator<QWidget*> itemIter(items);
01093
01094 while ( itemIter.hasNext() )
01095 {
01096 int index = _stackWidget->indexOf( itemIter.next() );
01097 _listWidget->item( index )->setText( properties->title() );
01098 }
01099 }
01100
01101 void ListViewContainer::updateIcon( ViewProperties* properties )
01102 {
01103 QList<QWidget*> items = widgetsForItem(properties);
01104 QListIterator<QWidget*> itemIter(items);
01105
01106 while ( itemIter.hasNext() )
01107 {
01108 int index = _stackWidget->indexOf( itemIter.next() );
01109 _listWidget->item( index )->setIcon( properties->icon() );
01110 }
01111 }
01112
01113 #include "ViewContainer.moc"