47 #include <QHBoxLayout>
49 #include <QPushButton>
51 #include <QStackedWidget>
53 #include <QToolButton>
56 #define YUILogComponent "qt-pkg"
60 #include "YUIException.h"
61 #include "YApplication.h"
62 #include "YQPkgFilterTab.h"
63 #include "YQPkgDiskUsageList.h"
64 #include "YQSignalBlocker.h"
65 #include "YQIconPool.h"
71 typedef vector<YQPkgFilterPage *> YQPkgFilterPageVector;
73 #define SHOW_ONLY_IMPORTANT_PAGES 1
74 #define VIEW_BUTTON_LEFT 1
76 #define SETTINGS_DIR "YaST2"
79 #define MARGIN 5 // inner margin between 3D borders and content
80 #define TOP_EXTRA_MARGIN 3
81 #define SPLITTER_HALF_SPACING 2
87 : settingsName( name )
88 , baseClassWidgetStack(0)
91 , filtersWidgetStack(0)
96 , tabContextMenuPage(0)
100 QStackedWidget * baseClassWidgetStack;
101 QSplitter * outerSplitter;
102 QSplitter * leftPaneSplitter;
103 QStackedWidget * filtersWidgetStack;
106 QPushButton * viewButton;
107 QMenu * tabContextMenu;
108 QAction * actionMovePageLeft;
109 QAction * actionMovePageRight;
110 QAction * actionClosePage;
112 YQPkgFilterPageVector pages;
119 : QTabWidget( parent )
122 YUI_CHECK_NEW( priv );
129 priv->baseClassWidgetStack = findChild<QStackedWidget*>();
130 YUI_CHECK_PTR( priv->baseClassWidgetStack );
135 disconnect( tabBar(), &QTabBar::currentChanged, 0, 0 );
142 priv->outerSplitter =
new QSplitter( Qt::Horizontal,
this );
143 YUI_CHECK_NEW( priv->outerSplitter );
145 priv->outerSplitter->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
146 QSizePolicy::Expanding ) );
147 priv->baseClassWidgetStack->addWidget( priv->outerSplitter );
150 #if SHOW_ONLY_IMPORTANT_PAGES
156 QWidget * buttonBox =
new QWidget(
this );
157 YUI_CHECK_NEW( buttonBox );
158 setCornerWidget( buttonBox, Qt::TopRightCorner );
159 buttonBox->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
161 QHBoxLayout * buttonBoxLayout =
new QHBoxLayout( buttonBox );
162 YUI_CHECK_NEW( buttonBoxLayout );
163 buttonBox->setLayout( buttonBoxLayout );
164 buttonBoxLayout->setContentsMargins( 0, 0, 0, 0 );
172 priv->viewButton =
new QPushButton( _(
"&View" ),
this );
173 YUI_CHECK_NEW( priv->viewButton );
174 setCornerWidget( priv->viewButton, Qt::TopLeftCorner );
176 priv->viewButton =
new QPushButton( _(
"&View" ), buttonBox );
177 YUI_CHECK_NEW( priv->viewButton );
178 buttonBoxLayout->addWidget( priv->viewButton );
180 #endif // VIEW_BUTTON_LEFT
182 QMenu * menu =
new QMenu( priv->viewButton );
183 YUI_CHECK_NEW( menu );
184 priv->viewButton->setMenu( menu );
186 connect( menu, SIGNAL( triggered( QAction * ) ),
187 this, SLOT (
showPage ( QAction * ) ) );
189 #endif // SHOW_ONLY_IMPORTANT_PAGES
196 priv->leftPaneSplitter =
new QSplitter( Qt::Vertical, priv->outerSplitter );
197 YUI_CHECK_NEW( priv->leftPaneSplitter );
204 priv->filtersWidgetStack =
new QStackedWidget( priv->leftPaneSplitter );
205 YUI_CHECK_NEW( priv->filtersWidgetStack );
208 YUI_CHECK_NEW( priv->diskUsageList );
211 QSplitter * sp = priv->leftPaneSplitter;
212 sp->setStretchFactor( sp->indexOf( priv->filtersWidgetStack ), 1 );
213 sp->setStretchFactor( sp->indexOf( priv->diskUsageList ), 2 );
218 sizes << priv->leftPaneSplitter->height();
220 sp->setSizes( sizes );
228 priv->rightPane =
new QWidget( priv->outerSplitter );
229 YUI_CHECK_NEW( priv->rightPane );
236 QSplitter * sp = priv->outerSplitter;
237 sp->setStretchFactor( sp->indexOf( priv->leftPaneSplitter ), 0 );
238 sp->setStretchFactor( sp->indexOf( priv->rightPane ), 1 );
244 connect( tabBar(), &QTabBar::currentChanged,
247 tabBar()->installEventFilter(
this );
254 priv->baseClassWidgetStack->setContentsMargins( MARGIN,
255 MARGIN + TOP_EXTRA_MARGIN,
259 priv->leftPaneSplitter->setContentsMargins ( 0,
261 SPLITTER_HALF_SPACING,
272 for ( YQPkgFilterPageVector::iterator it = priv->pages.begin();
273 it != priv->pages.end();
286 return priv->rightPane;
293 return priv->diskUsageList;
299 QWidget * pageContent,
300 const QString & internalName )
305 YUI_CHECK_NEW( page );
307 priv->pages.push_back( page );
308 priv->filtersWidgetStack->addWidget( pageContent );
311 if ( priv->viewButton && priv->viewButton->menu() )
313 QAction * action =
new QAction( pageLabel,
this );
314 YUI_CHECK_NEW( action );
315 action->setData( qVariantFromValue( pageContent ) );
317 priv->viewButton->menu()->addAction( action );
320 #if ! SHOW_ONLY_IMPORTANT_PAGES
321 page->tabIndex = tabBar()->addTab( pageLabel );
330 YUI_CHECK_PTR( page );
340 YUI_CHECK_PTR( page );
362 QWidget * pageContent = action->data().value<QWidget *>();
370 YUI_CHECK_PTR( page );
371 YQSignalBlocker sigBlocker( tabBar() );
373 if ( page->tabIndex < 0 )
376 page->tabIndex = tabBar()->addTab( page->label );
379 priv->filtersWidgetStack->setCurrentWidget( page->content );
380 tabBar()->setCurrentIndex( page->tabIndex );
381 priv->tabContextMenuPage = page;
390 while ( tabBar()->count() > 0 )
392 tabBar()->removeTab( 0 );
395 for ( YQPkgFilterPageVector::iterator it = priv->pages.begin();
396 it != priv->pages.end();
399 (*it)->tabIndex = -1;
407 if ( tabBar()->count() > 1 )
409 int currentIndex = tabBar()->currentIndex();
413 currentPage->tabIndex = -1;
415 tabBar()->removeTab( currentIndex );
421 for ( YQPkgFilterPageVector::iterator it = priv->pages.begin();
422 it != priv->pages.end();
427 if ( page->tabIndex >= currentIndex )
431 showPage( tabBar()->currentIndex() );
439 for ( YQPkgFilterPageVector::iterator it = priv->pages.begin();
440 it != priv->pages.end();
443 if ( (*it)->content == pageContent )
454 for ( YQPkgFilterPageVector::iterator it = priv->pages.begin();
455 it != priv->pages.end();
458 if ( (*it)->id == internalName )
472 for ( YQPkgFilterPageVector::iterator it = priv->pages.begin();
473 it != priv->pages.end();
476 if ( (*it)->tabIndex == tabIndex )
487 return tabBar()->count();
494 if ( watchedObj == tabBar() &&
495 event && event->type() == QEvent::MouseButtonPress )
497 QMouseEvent * mouseEvent =
dynamic_cast<QMouseEvent *
> (event);
499 if ( mouseEvent && mouseEvent->button() == Qt::RightButton )
505 return QTabWidget::eventFilter( watchedObj, event );
512 int tabIndex = tabBar()->tabAt( pos );
516 priv->tabContextMenuPage =
findPage( tabIndex );
518 if ( priv->tabContextMenuPage )
520 if ( ! priv->tabContextMenu )
524 priv->tabContextMenu =
new QMenu(
this );
525 YUI_CHECK_NEW( priv->tabContextMenu );
528 priv->actionMovePageLeft =
new QAction( YUI::yApp()->reverseLayout() ?
529 YQIconPool::arrowRight() : YQIconPool::arrowLeft(),
530 _(
"Move page &left" ),
this );
531 YUI_CHECK_NEW( priv->actionMovePageLeft );
533 connect( priv->actionMovePageLeft, SIGNAL( triggered() ),
538 priv->actionMovePageRight =
new QAction( YUI::yApp()->reverseLayout() ?
539 YQIconPool::arrowLeft() : YQIconPool::arrowRight(),
540 _(
"Move page &right" ),
this );
541 YUI_CHECK_NEW( priv->actionMovePageRight );
543 connect( priv->actionMovePageRight, SIGNAL( triggered() ),
547 priv->actionClosePage =
new QAction( YQIconPool::tabRemove(), _(
"&Close page" ),
this );
548 YUI_CHECK_NEW( priv->actionClosePage );
550 connect( priv->actionClosePage, SIGNAL( triggered() ),
554 priv->tabContextMenu->addAction( priv->actionMovePageLeft );
555 priv->tabContextMenu->addAction( priv->actionMovePageRight );
556 priv->tabContextMenu->addAction( priv->actionClosePage );
561 priv->actionMovePageLeft->setEnabled( tabIndex > 0 );
562 priv->actionMovePageRight->setEnabled( tabIndex < ( tabBar()->count() - 1 ) );
563 priv->actionClosePage->setEnabled( tabBar()->count() > 1 && priv->tabContextMenuPage->closeEnabled );
565 priv->tabContextMenu->popup( tabBar()->mapToGlobal( pos ) );
578 if ( priv->tabContextMenuPage )
580 int contextPageIndex = priv->tabContextMenuPage->tabIndex;
581 int otherPageIndex = contextPageIndex-1;
583 if ( otherPageIndex >= 0 )
594 if ( priv->tabContextMenuPage )
596 int contextPageIndex = priv->tabContextMenuPage->tabIndex;
597 int otherPageIndex = contextPageIndex+1;
599 if ( otherPageIndex < tabBar()->count() )
610 if ( ! page1 or ! page2 )
613 int oldCurrentIndex = tabBar()->currentIndex();
614 std::swap( page1->tabIndex, page2->tabIndex );
615 tabBar()->setTabText( page1->tabIndex, page1->label );
616 tabBar()->setTabText( page2->tabIndex, page2->label );
622 if ( oldCurrentIndex == page1->tabIndex )
624 YQSignalBlocker sigBlocker( tabBar() );
625 tabBar()->setCurrentIndex( page2->tabIndex );
627 else if ( oldCurrentIndex == page2->tabIndex )
629 YQSignalBlocker sigBlocker( tabBar() );
630 tabBar()->setCurrentIndex( page1->tabIndex );
638 if ( priv->tabContextMenuPage )
640 int pageIndex = priv->tabContextMenuPage->tabIndex;
641 priv->tabContextMenuPage->tabIndex = -1;
642 tabBar()->removeTab( pageIndex );
649 for ( YQPkgFilterPageVector::iterator it = priv->pages.begin();
650 it != priv->pages.end();
655 if ( page->tabIndex >= pageIndex )
659 showPage( tabBar()->currentIndex() );
668 QSettings settings( QSettings::UserScope, SETTINGS_DIR, priv->settingsName );
670 int size = settings.beginReadArray(
"Tab_Pages" );
672 for (
int i=0; i < size; i++ )
674 settings.setArrayIndex(i);
675 QString
id = settings.value(
"Page_ID" ).toString();
680 yuiDebug() <<
"Restoring page \"" << toUTF8(
id ) <<
"\"" << std::endl;
684 yuiWarning() <<
"No page with ID \"" << toUTF8(
id ) <<
"\"" << std::endl;
689 QString
id = settings.value(
"Current_Page" ).toString();
691 if ( !
id.isEmpty() )
699 QSettings settings( QSettings::UserScope, SETTINGS_DIR, priv->settingsName );
701 settings.beginWriteArray(
"Tab_Pages" );
703 for (
int i=0; i < tabBar()->count(); i++ )
709 settings.setArrayIndex(i);
711 if ( page->id.isEmpty() )
712 yuiWarning() <<
"No ID for tab page \"" << page->label <<
"\"" << std::endl;
715 yuiDebug() <<
"Saving page #" << i <<
": \"" << toUTF8( page->id ) <<
"\"" << std::endl;
716 settings.setValue(
"Page_ID", page->id );
726 settings.setValue(
"Current_Page", currentPage->id );
731 #include "YQPkgFilterTab.moc"
void contextMovePageRight()
Move the current tab page (from the context menu) one position to the right.
bool postTabContextMenu(const QPoint &pos)
Open the tab context menu for the tab at the specified position.
void showPage(QWidget *page)
Show a page.
QWidget * rightPane() const
Return the right pane.
void saveSettings()
Save the current settings, including which tabs are currently open and in which order.
void addPage(const QString &pageLabel, QWidget *pageContent, const QString &internalName)
Add a page with a user-visible "pageLabel", a widget with the page content and an internal name (or I...
virtual ~YQPkgFilterTab()
Destructor.
YQPkgDiskUsageList * diskUsageList() const
Return the disk usage list widget or 0 if there is none.
YQPkgFilterTab(QWidget *parent, const QString &settingsName)
Constructor.
Widget for "tabbed browsing" in packages:
void swapTabs(YQPkgFilterPage *page1, YQPkgFilterPage *page2)
Swap two tabs and adjust their tab indices accordingly.
void closeAllPages()
Close all currently open pages.
void currentChanged(QWidget *newPageContent)
Emitted when the current page changes.
void loadSettings()
Load settings, including which tabs are to be opened and in which order.
virtual bool eventFilter(QObject *watchedObj, QEvent *event)
Event filter to catch mouse right clicks on open tabs for the tab context menu.
Helper class for filter pages.
YQPkgFilterPage * findPage(QWidget *pageContent)
Find a filter page by its content widget (the widget that was passed to addPage() )...
void contextMovePageLeft()
Move the current tab page (from the context menu) one position to the left.
void contextClosePage()
Close the current tab page (from the context menu).
int tabCount() const
Return the number of open tabs.
void closeCurrentPage()
Close the current page unless this is the last visible page.
List of disk usage of all attached partitions.