mirror of
https://invent.kde.org/graphics/okular
synced 2024-11-05 18:34:53 +00:00
ac79610a8b
Should never happen, but as it is the "main" widget of the part it might end up there if someone just says part->mainwidget->setfocus or something like that At least this way the focus does not go down the drain and ends up in the sidebar list, which is not optimal but is better than getting the keyboard focus lost
712 lines
22 KiB
C++
712 lines
22 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2007 by Pino Toscano <pino@kde.org> *
|
|
* Copyright (C) 2009 by Eike Hein <hein@kde.org> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
***************************************************************************/
|
|
|
|
#include "sidebar.h"
|
|
|
|
#include <qabstractitemdelegate.h>
|
|
#include <qaction.h>
|
|
#include <qapplication.h>
|
|
#include <qevent.h>
|
|
#include <qfont.h>
|
|
#include <qfontmetrics.h>
|
|
#include <qlabel.h>
|
|
#include <qlayout.h>
|
|
#include <qlist.h>
|
|
#include <qlistwidget.h>
|
|
#include <qpainter.h>
|
|
#include <qscrollbar.h>
|
|
#include <qsplitter.h>
|
|
#include <qstackedwidget.h>
|
|
|
|
#include <kglobalsettings.h>
|
|
#include <kiconloader.h>
|
|
#include <klocale.h>
|
|
#include <kmenu.h>
|
|
|
|
#include "settings.h"
|
|
|
|
static const int SidebarItemType = QListWidgetItem::UserType + 1;
|
|
|
|
/* List item representing a sidebar entry. */
|
|
class SidebarItem : public QListWidgetItem
|
|
{
|
|
public:
|
|
SidebarItem( QWidget* w, const QIcon &icon, const QString &text )
|
|
: QListWidgetItem( 0, SidebarItemType ),
|
|
m_widget( w )
|
|
{
|
|
setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
|
|
setIcon( icon );
|
|
setText( text );
|
|
setToolTip( text );
|
|
}
|
|
|
|
QWidget* widget() const
|
|
{
|
|
return m_widget;
|
|
}
|
|
|
|
private:
|
|
QWidget *m_widget;
|
|
};
|
|
|
|
|
|
/* A simple delegate to paint the icon of each item */
|
|
#define ITEM_MARGIN_LEFT 5
|
|
#define ITEM_MARGIN_TOP 5
|
|
#define ITEM_MARGIN_RIGHT 5
|
|
#define ITEM_MARGIN_BOTTOM 5
|
|
#define ITEM_PADDING 5
|
|
|
|
class SidebarDelegate : public QAbstractItemDelegate
|
|
{
|
|
public:
|
|
SidebarDelegate( QObject *parent = 0 );
|
|
~SidebarDelegate();
|
|
|
|
void setShowText( bool show );
|
|
bool isTextShown() const;
|
|
|
|
// from QAbstractItemDelegate
|
|
void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
|
|
QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
|
|
|
|
private:
|
|
bool m_showText;
|
|
};
|
|
|
|
SidebarDelegate::SidebarDelegate( QObject *parent )
|
|
: QAbstractItemDelegate( parent ), m_showText( true )
|
|
{
|
|
}
|
|
|
|
SidebarDelegate::~SidebarDelegate()
|
|
{
|
|
}
|
|
|
|
void SidebarDelegate::setShowText( bool show )
|
|
{
|
|
m_showText = show;
|
|
}
|
|
|
|
bool SidebarDelegate::isTextShown() const
|
|
{
|
|
return m_showText;
|
|
}
|
|
|
|
void SidebarDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
|
|
{
|
|
QBrush backBrush;
|
|
QColor foreColor;
|
|
bool disabled = false;
|
|
bool hover = false;
|
|
if ( !( option.state & QStyle::State_Enabled ) )
|
|
{
|
|
backBrush = option.palette.brush( QPalette::Disabled, QPalette::Base );
|
|
foreColor = option.palette.color( QPalette::Disabled, QPalette::Text );
|
|
disabled = true;
|
|
}
|
|
else if ( option.state & ( QStyle::State_HasFocus | QStyle::State_Selected ) )
|
|
{
|
|
backBrush = option.palette.brush( QPalette::Highlight );
|
|
foreColor = option.palette.color( QPalette::HighlightedText );
|
|
}
|
|
else if ( option.state & QStyle::State_MouseOver )
|
|
{
|
|
backBrush = option.palette.color( QPalette::Highlight ).light( 115 );
|
|
foreColor = option.palette.color( QPalette::HighlightedText );
|
|
hover = true;
|
|
}
|
|
else /*if ( option.state & QStyle::State_Enabled )*/
|
|
{
|
|
backBrush = option.palette.brush( QPalette::Base );
|
|
foreColor = option.palette.color( QPalette::Text );
|
|
}
|
|
QStyle *style = QApplication::style();
|
|
QStyleOptionViewItemV4 opt( option );
|
|
// KStyle provides an "hover highlight" effect for free;
|
|
// but we want that for non-KStyle-based styles too
|
|
if ( !style->inherits( "KStyle" ) && hover )
|
|
{
|
|
Qt::BrushStyle bs = opt.backgroundBrush.style();
|
|
if ( bs > Qt::NoBrush && bs < Qt::TexturePattern )
|
|
opt.backgroundBrush = opt.backgroundBrush.color().light( 115 );
|
|
else
|
|
opt.backgroundBrush = backBrush;
|
|
}
|
|
painter->save();
|
|
style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, 0 );
|
|
painter->restore();
|
|
QIcon icon = index.data( Qt::DecorationRole ).value< QIcon >();
|
|
if ( !icon.isNull() )
|
|
{
|
|
QPoint iconpos(
|
|
( option.rect.width() - option.decorationSize.width() ) / 2,
|
|
ITEM_MARGIN_TOP
|
|
);
|
|
iconpos += option.rect.topLeft();
|
|
QIcon::Mode iconmode = disabled ? QIcon::Disabled : QIcon::Normal;
|
|
painter->drawPixmap( iconpos, icon.pixmap( option.decorationSize, iconmode ) );
|
|
}
|
|
|
|
if ( m_showText )
|
|
{
|
|
QString text = index.data( Qt::DisplayRole ).toString();
|
|
QRect fontBoundaries = QFontMetrics( option.font ).boundingRect( text );
|
|
QPoint textPos(
|
|
ITEM_MARGIN_LEFT + ( option.rect.width() - ITEM_MARGIN_LEFT - ITEM_MARGIN_RIGHT - fontBoundaries.width() ) / 2,
|
|
ITEM_MARGIN_TOP + option.decorationSize.height() + ITEM_PADDING
|
|
);
|
|
fontBoundaries.translate( -fontBoundaries.topLeft() );
|
|
fontBoundaries.translate( textPos );
|
|
fontBoundaries.translate( option.rect.topLeft() );
|
|
painter->setPen( foreColor );
|
|
painter->drawText( fontBoundaries, Qt::AlignCenter, text );
|
|
}
|
|
}
|
|
|
|
QSize SidebarDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
|
|
{
|
|
QSize baseSize( option.decorationSize.width(), option.decorationSize.height() );
|
|
if ( m_showText )
|
|
{
|
|
QRect fontBoundaries = QFontMetrics( option.font ).boundingRect( index.data( Qt::DisplayRole ).toString() );
|
|
baseSize.setWidth( qMax( fontBoundaries.width(), baseSize.width() ) );
|
|
baseSize.setHeight( baseSize.height() + fontBoundaries.height() + ITEM_PADDING );
|
|
}
|
|
return baseSize + QSize( ITEM_MARGIN_LEFT + ITEM_MARGIN_RIGHT, ITEM_MARGIN_TOP + ITEM_MARGIN_BOTTOM );
|
|
}
|
|
|
|
|
|
/* A custom list widget that ignores the events for disabled items */
|
|
class SidebarListWidget : public QListWidget
|
|
{
|
|
public:
|
|
SidebarListWidget( QWidget *parent = 0 );
|
|
~SidebarListWidget();
|
|
|
|
protected:
|
|
// from QListWidget
|
|
void mouseDoubleClickEvent( QMouseEvent *event );
|
|
void mouseMoveEvent( QMouseEvent *event );
|
|
void mousePressEvent( QMouseEvent *event );
|
|
void mouseReleaseEvent( QMouseEvent *event );
|
|
|
|
QModelIndex moveCursor( QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers );
|
|
|
|
private:
|
|
// These two are used to keep track of the row an initial mousePress-
|
|
// Event() occurs on and the row the cursor moves over while the left
|
|
// mouse button is pressed, respectively, as well as for event compre-
|
|
// ssion, to avoid calling SideBar::itemClicked() multiple times for
|
|
// the same item in a row on mouseMoveEvent()'s. This code is written
|
|
// under the assumption that the number and positions of items in the
|
|
// list won't change while the user interacts with it using the mouse.
|
|
// Future work here must see to that this assumption continues to hold
|
|
// up, or achieve calling SideBar::itemClicked() differently.
|
|
int mousePressedRow;
|
|
int rowUnderMouse;
|
|
};
|
|
|
|
SidebarListWidget::SidebarListWidget( QWidget *parent )
|
|
: QListWidget( parent )
|
|
{
|
|
mousePressedRow = -1;
|
|
rowUnderMouse = -1;
|
|
}
|
|
|
|
SidebarListWidget::~SidebarListWidget()
|
|
{
|
|
}
|
|
|
|
void SidebarListWidget::mouseDoubleClickEvent( QMouseEvent *event )
|
|
{
|
|
QModelIndex index = indexAt( event->pos() );
|
|
if ( index.isValid() && !( index.flags() & Qt::ItemIsSelectable ) )
|
|
return;
|
|
|
|
QListWidget::mouseDoubleClickEvent( event );
|
|
}
|
|
|
|
void SidebarListWidget::mouseMoveEvent( QMouseEvent *event )
|
|
{
|
|
QModelIndex index = indexAt( event->pos() );
|
|
|
|
if ( index.isValid() )
|
|
{
|
|
if ( index.flags() & Qt::ItemIsSelectable )
|
|
{
|
|
if ( event->buttons() & Qt::LeftButton
|
|
&& index.row() != mousePressedRow
|
|
&& index.row() != rowUnderMouse )
|
|
{
|
|
mousePressedRow = -1;
|
|
rowUnderMouse = index.row();
|
|
|
|
QMetaObject::invokeMethod(parent(), "itemClicked", Qt::DirectConnection,
|
|
Q_ARG(QListWidgetItem*, item(index.row())));
|
|
}
|
|
}
|
|
else
|
|
return;
|
|
}
|
|
|
|
QListWidget::mouseMoveEvent( event );
|
|
}
|
|
|
|
void SidebarListWidget::mousePressEvent( QMouseEvent *event )
|
|
{
|
|
QModelIndex index = indexAt( event->pos() );
|
|
|
|
if ( index.isValid() )
|
|
{
|
|
if ( index.flags() & Qt::ItemIsSelectable )
|
|
{
|
|
if ( event->buttons() & Qt::LeftButton )
|
|
mousePressedRow = index.row();
|
|
}
|
|
else
|
|
return;
|
|
}
|
|
|
|
QListWidget::mousePressEvent( event );
|
|
}
|
|
|
|
void SidebarListWidget::mouseReleaseEvent( QMouseEvent *event )
|
|
{
|
|
QModelIndex index = indexAt( event->pos() );
|
|
|
|
if ( index.isValid() )
|
|
{
|
|
if ( index.flags() & Qt::ItemIsSelectable )
|
|
{
|
|
if ( event->button() == Qt::LeftButton
|
|
&& index.row() != rowUnderMouse )
|
|
{
|
|
QMetaObject::invokeMethod(parent(), "itemClicked", Qt::DirectConnection,
|
|
Q_ARG(QListWidgetItem*, item(index.row())));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mousePressedRow = -1;
|
|
rowUnderMouse = -1;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
mousePressedRow = -1;
|
|
rowUnderMouse = -1;
|
|
|
|
QListWidget::mouseReleaseEvent( event );
|
|
}
|
|
|
|
QModelIndex SidebarListWidget::moveCursor( QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers )
|
|
{
|
|
Q_UNUSED( modifiers )
|
|
QModelIndex oldindex = currentIndex();
|
|
QModelIndex newindex = oldindex;
|
|
switch ( cursorAction )
|
|
{
|
|
case MoveUp:
|
|
case MovePrevious:
|
|
{
|
|
int row = oldindex.row() - 1;
|
|
while ( row > -1 && !( model()->index( row, 0 ).flags() & Qt::ItemIsSelectable ) ) --row;
|
|
if ( row > -1 )
|
|
newindex = model()->index( row, 0 );
|
|
break;
|
|
}
|
|
case MoveDown:
|
|
case MoveNext:
|
|
{
|
|
int row = oldindex.row() + 1;
|
|
int max = model()->rowCount();
|
|
while ( row < max && !( model()->index( row, 0 ).flags() & Qt::ItemIsSelectable ) ) ++row;
|
|
if ( row < max )
|
|
newindex = model()->index( row, 0 );
|
|
break;
|
|
}
|
|
case MoveHome:
|
|
case MovePageUp:
|
|
{
|
|
int row = 0;
|
|
while ( row < oldindex.row() && !( model()->index( row, 0 ).flags() & Qt::ItemIsSelectable ) ) ++row;
|
|
if ( row < oldindex.row() )
|
|
newindex = model()->index( row, 0 );
|
|
break;
|
|
}
|
|
case MoveEnd:
|
|
case MovePageDown:
|
|
{
|
|
int row = model()->rowCount() - 1;
|
|
while ( row > oldindex.row() && !( model()->index( row, 0 ).flags() & Qt::ItemIsSelectable ) ) --row;
|
|
if ( row > oldindex.row() )
|
|
newindex = model()->index( row, 0 );
|
|
break;
|
|
}
|
|
// no navigation possible for these
|
|
case MoveLeft:
|
|
case MoveRight:
|
|
break;
|
|
}
|
|
|
|
// dirty hack to change item when the key cursor changes item
|
|
if ( oldindex != newindex )
|
|
{
|
|
emit itemClicked( itemFromIndex( newindex ) );
|
|
}
|
|
return newindex;
|
|
}
|
|
|
|
|
|
/* Private storage. */
|
|
class Sidebar::Private
|
|
{
|
|
public:
|
|
Private()
|
|
: sideWidget( 0 ), bottomWidget( 0 ), splitterSizesSet( false ),
|
|
itemsHeight( 0 )
|
|
{
|
|
}
|
|
|
|
void adjustListSize( bool recalc, bool expand = true );
|
|
|
|
SidebarListWidget *list;
|
|
QSplitter *splitter;
|
|
QStackedWidget *stack;
|
|
QWidget *sideContainer;
|
|
QLabel *sideTitle;
|
|
QVBoxLayout *vlay;
|
|
QWidget *sideWidget;
|
|
QWidget *bottomWidget;
|
|
QList< SidebarItem* > pages;
|
|
bool splitterSizesSet;
|
|
int itemsHeight;
|
|
SidebarDelegate *sideDelegate;
|
|
};
|
|
|
|
void Sidebar::Private::adjustListSize( bool recalc, bool expand )
|
|
{
|
|
QRect bottomElemRect(
|
|
QPoint( 0, 0 ),
|
|
list->sizeHintForIndex( list->model()->index( list->count() - 1, 0 ) )
|
|
);
|
|
if ( recalc )
|
|
{
|
|
int w = 0;
|
|
for ( int i = 0; i < list->count(); ++i )
|
|
{
|
|
QSize s = list->sizeHintForIndex( list->model()->index( i, 0 ) );
|
|
if ( s.width() > w )
|
|
w = s.width();
|
|
}
|
|
bottomElemRect.setWidth( w );
|
|
}
|
|
bottomElemRect.translate( 0, bottomElemRect.height() * ( list->count() - 1 ) );
|
|
itemsHeight = bottomElemRect.height() * list->count();
|
|
list->setMinimumHeight( itemsHeight + list->frameWidth() * 2 );
|
|
int curWidth = list->minimumWidth();
|
|
int newWidth = expand
|
|
? qMax( bottomElemRect.width() + list->frameWidth() * 2, curWidth )
|
|
: qMin( bottomElemRect.width() + list->frameWidth() * 2, curWidth );
|
|
list->setFixedWidth( newWidth );
|
|
}
|
|
|
|
|
|
Sidebar::Sidebar( QWidget *parent )
|
|
: QWidget( parent ), d( new Private )
|
|
{
|
|
QHBoxLayout *mainlay = new QHBoxLayout( this );
|
|
mainlay->setMargin( 0 );
|
|
mainlay->setSpacing( 0 );
|
|
|
|
setAutoFillBackground( true );
|
|
|
|
d->list = new SidebarListWidget( this );
|
|
mainlay->addWidget( d->list );
|
|
d->list->setMouseTracking( true );
|
|
d->list->viewport()->setAttribute( Qt::WA_Hover );
|
|
d->sideDelegate = new SidebarDelegate( d->list );
|
|
d->sideDelegate->setShowText( Okular::Settings::sidebarShowText() );
|
|
d->list->setItemDelegate( d->sideDelegate );
|
|
d->list->setUniformItemSizes( true );
|
|
d->list->setSelectionMode( QAbstractItemView::SingleSelection );
|
|
int iconsize = Okular::Settings::sidebarIconSize();
|
|
d->list->setIconSize( QSize( iconsize, iconsize ) );
|
|
d->list->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
|
d->list->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
|
d->list->setContextMenuPolicy( Qt::CustomContextMenu );
|
|
d->list->viewport()->setAutoFillBackground( false );
|
|
d->list->setFont( KGlobalSettings::toolBarFont() );
|
|
|
|
d->splitter = new QSplitter( this );
|
|
mainlay->addWidget( d->splitter );
|
|
d->splitter->setOpaqueResize( true );
|
|
d->splitter->setChildrenCollapsible( false );
|
|
|
|
d->sideContainer = new QWidget( d->splitter );
|
|
d->sideContainer->setMinimumWidth( 90 );
|
|
d->sideContainer->setMaximumWidth( 600 );
|
|
d->vlay = new QVBoxLayout( d->sideContainer );
|
|
d->vlay->setMargin( 0 );
|
|
|
|
d->sideTitle = new QLabel( d->sideContainer );
|
|
d->vlay->addWidget( d->sideTitle );
|
|
QFont tf = d->sideTitle->font();
|
|
tf.setBold( true );
|
|
d->sideTitle->setFont( tf );
|
|
d->sideTitle->setMargin( 3 );
|
|
d->sideTitle->setIndent( 3 );
|
|
|
|
d->stack = new QStackedWidget( d->sideContainer );
|
|
d->vlay->addWidget( d->stack );
|
|
d->sideContainer->hide();
|
|
|
|
connect( d->list, SIGNAL(customContextMenuRequested(QPoint)),
|
|
this, SLOT(listContextMenu(QPoint)) );
|
|
connect( d->splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(splitterMoved(int,int)) );
|
|
|
|
setFocusProxy( d->list );
|
|
}
|
|
|
|
Sidebar::~Sidebar()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
int Sidebar::addItem( QWidget *widget, const QIcon &icon, const QString &text )
|
|
{
|
|
if ( !widget )
|
|
return -1;
|
|
|
|
SidebarItem *newitem = new SidebarItem( widget, icon, text );
|
|
d->list->addItem( newitem );
|
|
d->pages.append( newitem );
|
|
widget->setParent( d->stack );
|
|
d->stack->addWidget( widget );
|
|
// updating the minimum height of the icon view, so all are visible with no scrolling
|
|
d->adjustListSize( false, true );
|
|
return d->pages.count() - 1;
|
|
}
|
|
|
|
void Sidebar::setMainWidget( QWidget *widget )
|
|
{
|
|
delete d->sideWidget;
|
|
d->sideWidget = widget;
|
|
if ( d->sideWidget )
|
|
{
|
|
// setting the splitter as parent for the widget automatically plugs it
|
|
// into the splitter, neat!
|
|
d->sideWidget->setParent( d->splitter );
|
|
|
|
if ( !d->splitterSizesSet )
|
|
{
|
|
QList<int> splitterSizes = Okular::Settings::splitterSizes();
|
|
if ( !splitterSizes.count() )
|
|
{
|
|
// the first time use 1/10 for the panel and 9/10 for the pageView
|
|
splitterSizes.push_back( 50 );
|
|
splitterSizes.push_back( 500 );
|
|
}
|
|
d->splitter->setSizes( splitterSizes );
|
|
d->splitterSizesSet = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Sidebar::setBottomWidget( QWidget *widget )
|
|
{
|
|
delete d->bottomWidget;
|
|
d->bottomWidget = widget;
|
|
if ( d->bottomWidget )
|
|
{
|
|
d->bottomWidget->setParent( this );
|
|
d->vlay->addWidget( d->bottomWidget );
|
|
}
|
|
}
|
|
|
|
void Sidebar::setItemEnabled( int index, bool enabled )
|
|
{
|
|
if ( index < 0 || index >= d->pages.count() )
|
|
return;
|
|
|
|
Qt::ItemFlags f = d->pages.at( index )->flags();
|
|
if ( enabled )
|
|
{
|
|
f |= Qt::ItemIsEnabled;
|
|
f |= Qt::ItemIsSelectable;
|
|
}
|
|
else
|
|
{
|
|
f &= ~Qt::ItemIsEnabled;
|
|
f &= ~Qt::ItemIsSelectable;
|
|
}
|
|
d->pages.at( index )->setFlags( f );
|
|
|
|
if ( !enabled && index == currentIndex() && isSidebarVisible() )
|
|
// find an enabled item, and select that one
|
|
for ( int i = 0; i < d->pages.count(); ++i )
|
|
if ( d->pages.at(i)->flags() & Qt::ItemIsEnabled )
|
|
{
|
|
setCurrentIndex( i );
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool Sidebar::isItemEnabled( int index ) const
|
|
{
|
|
if ( index < 0 || index >= d->pages.count() )
|
|
return false;
|
|
|
|
Qt::ItemFlags f = d->pages.at( index )->flags();
|
|
return ( f & Qt::ItemIsEnabled ) == Qt::ItemIsEnabled;
|
|
}
|
|
|
|
void Sidebar::setCurrentIndex( int index )
|
|
{
|
|
if ( index < 0 || index >= d->pages.count() || !isItemEnabled( index ) )
|
|
return;
|
|
|
|
itemClicked( d->pages.at( index ) );
|
|
QModelIndex modelindex = d->list->model()->index( index, 0 );
|
|
d->list->setCurrentIndex( modelindex );
|
|
d->list->selectionModel()->select( modelindex, QItemSelectionModel::ClearAndSelect );
|
|
}
|
|
|
|
int Sidebar::currentIndex() const
|
|
{
|
|
return d->list->currentRow();
|
|
}
|
|
|
|
void Sidebar::setSidebarVisibility( bool visible )
|
|
{
|
|
if ( visible != d->list->isHidden() )
|
|
return;
|
|
|
|
static bool sideWasVisible = !d->sideContainer->isHidden();
|
|
|
|
d->list->setHidden( !visible );
|
|
if ( visible )
|
|
{
|
|
d->sideContainer->setHidden( !sideWasVisible );
|
|
sideWasVisible = true;
|
|
}
|
|
else
|
|
{
|
|
sideWasVisible = !d->sideContainer->isHidden();
|
|
d->sideContainer->setHidden( true );
|
|
}
|
|
}
|
|
|
|
bool Sidebar::isSidebarVisible() const
|
|
{
|
|
return !d->list->isHidden();
|
|
}
|
|
|
|
void Sidebar::itemClicked( QListWidgetItem *item )
|
|
{
|
|
if ( !item )
|
|
return;
|
|
|
|
SidebarItem* sbItem = dynamic_cast< SidebarItem* >( item );
|
|
if ( !sbItem )
|
|
return;
|
|
|
|
if ( sbItem->widget() == d->stack->currentWidget() )
|
|
{
|
|
if ( d->sideContainer->isVisible() )
|
|
{
|
|
d->list->selectionModel()->clear();
|
|
d->sideContainer->hide();
|
|
}
|
|
else
|
|
{
|
|
d->sideContainer->show();
|
|
d->list->show();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( d->sideContainer->isHidden() )
|
|
{
|
|
d->sideContainer->show();
|
|
d->list->show();
|
|
}
|
|
d->stack->setCurrentWidget( sbItem->widget() );
|
|
d->sideTitle->setText( sbItem->toolTip() );
|
|
}
|
|
}
|
|
|
|
void Sidebar::splitterMoved( int /*pos*/, int index )
|
|
{
|
|
// if the side panel has been resized, save splitter sizes
|
|
if ( index == 1 )
|
|
saveSplitterSize();
|
|
}
|
|
|
|
void Sidebar::saveSplitterSize() const
|
|
{
|
|
Okular::Settings::setSplitterSizes( d->splitter->sizes() );
|
|
Okular::Settings::self()->writeConfig();
|
|
}
|
|
|
|
void Sidebar::listContextMenu( const QPoint &pos )
|
|
{
|
|
KMenu menu( this );
|
|
menu.addTitle( i18n( "Okular" ) );
|
|
QAction *showTextAct = menu.addAction( i18n( "Show Text" ) );
|
|
showTextAct->setCheckable( true );
|
|
showTextAct->setChecked( d->sideDelegate->isTextShown() );
|
|
connect( showTextAct, SIGNAL(toggled(bool)), this, SLOT(showTextToggled(bool)) );
|
|
menu.addSeparator();
|
|
QActionGroup *sizeGroup = new QActionGroup( &menu );
|
|
int curSize = d->list->iconSize().width();
|
|
#define ADD_SIZE_ACTION( text, _itssize ) \
|
|
{ \
|
|
const int itssize = static_cast< int >( _itssize ); \
|
|
QAction *sizeAct = menu.addAction( text ); \
|
|
sizeAct->setCheckable( true ); \
|
|
sizeAct->setData( qVariantFromValue( itssize ) ); \
|
|
sizeAct->setChecked( itssize == curSize ); \
|
|
sizeGroup->addAction( sizeAct ); \
|
|
}
|
|
ADD_SIZE_ACTION( i18n( "Small Icons" ), KIconLoader::SizeSmallMedium )
|
|
ADD_SIZE_ACTION( i18n( "Normal Icons" ), KIconLoader::SizeMedium )
|
|
ADD_SIZE_ACTION( i18n( "Large Icons" ), KIconLoader::SizeLarge )
|
|
#undef ADD_SIZE_ACTION
|
|
connect( sizeGroup, SIGNAL(triggered(QAction*)), this, SLOT(iconSizeChanged(QAction*)) );
|
|
menu.exec( mapToGlobal( pos ) );
|
|
}
|
|
|
|
void Sidebar::showTextToggled( bool on )
|
|
{
|
|
d->sideDelegate->setShowText( on );
|
|
d->adjustListSize( true, on );
|
|
d->list->reset();
|
|
d->list->update();
|
|
Okular::Settings::setSidebarShowText( on );
|
|
Okular::Settings::self()->writeConfig();
|
|
}
|
|
|
|
void Sidebar::iconSizeChanged( QAction *action )
|
|
{
|
|
int size = action->data().toInt();
|
|
int oldSize = d->list->iconSize().width();
|
|
d->list->setIconSize( QSize( size, size ) );
|
|
d->adjustListSize( true, size > oldSize );
|
|
d->list->reset();
|
|
d->list->update();
|
|
Okular::Settings::setSidebarIconSize( size );
|
|
Okular::Settings::self()->writeConfig();
|
|
}
|
|
|
|
#include "sidebar.moc"
|