summaryrefslogtreecommitdiffstats
path: root/koshell/iconsidepane.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'koshell/iconsidepane.cpp')
-rw-r--r--koshell/iconsidepane.cpp595
1 files changed, 595 insertions, 0 deletions
diff --git a/koshell/iconsidepane.cpp b/koshell/iconsidepane.cpp
new file mode 100644
index 00000000..8698f9a0
--- /dev/null
+++ b/koshell/iconsidepane.cpp
@@ -0,0 +1,595 @@
+/*
+ This file is part of KDE KOffice project.
+
+ Copyright (C) 2003 Cornelius Schumacher <[email protected]>
+ Copyright (C) 2005 Fredrik Edemar <[email protected]>
+
+ 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.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qbitmap.h>
+#include <qcursor.h>
+#include <qdrawutil.h>
+#include <qfontmetrics.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qobjectlist.h>
+#include <qpainter.h>
+#include <qptrlist.h>
+#include <qstyle.h>
+#include <qtooltip.h>
+#include <qwidgetstack.h>
+
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kdialog.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kpushbutton.h>
+
+#include "iconsidepane.h"
+
+EntryItem::EntryItem( Navigator *parent, int _id, const QString &_text, const QString & _pix )
+ : QListBoxItem( parent ),
+ mPixmapName(_pix),
+ mId(_id),
+ mHasHover( false ),
+ mPaintActive( false )
+{
+ reloadPixmap();
+ setCustomHighlighting( true );
+ setText( _text );
+}
+
+EntryItem::~EntryItem()
+{
+}
+
+void EntryItem::setNewText(const QString &_text)
+{
+ setText( _text );
+}
+
+void EntryItem::reloadPixmap()
+{
+ int size = (int)navigator()->viewMode();
+ if ( size != 0 )
+ mPixmap = KGlobal::iconLoader()->loadIcon( mPixmapName, KIcon::Desktop, size );
+ else
+ mPixmap = QPixmap();
+}
+
+Navigator* EntryItem::navigator() const
+{
+ return static_cast<Navigator*>( listBox() );
+}
+
+int EntryItem::width( const QListBox *listbox ) const
+{
+ int w = 0;
+ if( navigator()->showIcons() ) {
+ w = navigator()->viewMode();
+ if ( navigator()->viewMode() == SmallIcons )
+ w += 4;
+ }
+ if( navigator()->showText() ) {
+ if ( navigator()->viewMode() == SmallIcons )
+ w += listbox->fontMetrics().width( text() );
+ else
+ w = QMAX( w, listbox->fontMetrics().width( text() ) );
+ }
+ return w + ( KDialog::marginHint() * 2 );
+}
+
+int EntryItem::height( const QListBox *listbox ) const
+{
+ int h = 0;
+ if ( navigator()->showIcons() )
+ h = (int)navigator()->viewMode() + 4;
+ if ( navigator()->showText() ) {
+ if ( navigator()->viewMode() == SmallIcons || !navigator()->showIcons() )
+ h = QMAX( h, listbox->fontMetrics().lineSpacing() ) + KDialog::spacingHint() * 2;
+ else
+ h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing() + 4;
+ }
+ return h;
+}
+
+void EntryItem::paint( QPainter *p )
+{
+ reloadPixmap();
+
+ QListBox *box = listBox();
+ bool iconAboveText = ( navigator()->viewMode() > SmallIcons )
+ && navigator()->showIcons();
+ int w = box->viewport()->width();
+ int y = 2;
+
+ // draw selected
+ if ( isCurrent() || isSelected() || mHasHover || mPaintActive ) {
+ int h = height( box );
+
+ QBrush brush;
+ if ( isCurrent() || isSelected() || mPaintActive )
+ brush = box->colorGroup().brush( QColorGroup::Highlight );
+ else
+ brush = box->colorGroup().highlight().light( 115 );
+ p->fillRect( 1, 0, w - 2, h - 1, brush );
+ QPen pen = p->pen();
+ QPen oldPen = pen;
+ pen.setColor( box->colorGroup().mid() );
+ p->setPen( pen );
+
+ p->drawPoint( 1, 0 );
+ p->drawPoint( 1, h - 2 );
+ p->drawPoint( w - 2, 0 );
+ p->drawPoint( w - 2, h - 2 );
+
+ p->setPen( oldPen );
+ }
+
+ if ( !mPixmap.isNull() && navigator()->showIcons() ) {
+ int x = iconAboveText ? ( ( w - mPixmap.width() ) / 2 ) :
+ KDialog::marginHint();
+ p->drawPixmap( x, y, mPixmap );
+ }
+
+ QColor shadowColor = listBox()->colorGroup().background().dark(115);
+ if ( isCurrent() || isSelected() ) {
+ p->setPen( box->colorGroup().highlightedText() );
+ }
+
+ if ( !text().isEmpty() && navigator()->showText() ) {
+ QFontMetrics fm = p->fontMetrics();
+
+ int x = 0;
+ if ( iconAboveText ) {
+ x = ( w - fm.width( text() ) ) / 2;
+ y += fm.height() - fm.descent();
+ if ( navigator()->showIcons() )
+ y += mPixmap.height();
+ } else {
+ x = KDialog::marginHint() + 4;
+ if( navigator()->showIcons() ) {
+ x += mPixmap.width();
+ }
+
+ if ( !navigator()->showIcons() || mPixmap.height() < fm.height() )
+ y += fm.ascent() + fm.leading()/2;
+ else
+ y += mPixmap.height()/2 - fm.height()/2 + fm.ascent();
+ }
+
+ if ( isCurrent() || isSelected() || mHasHover ) {
+ p->setPen( box->colorGroup().highlight().dark(115) );
+ p->drawText( x + ( QApplication::reverseLayout() ? -1 : 1),
+ y + 1, text() );
+ p->setPen( box->colorGroup().highlightedText() );
+ }
+ else
+ p->setPen( box->colorGroup().text() );
+
+ p->drawText( x, y, text() );
+ }
+
+ // ensure that we don't have a stale flag around
+ if ( isCurrent() || isSelected() ) mHasHover = false;
+}
+
+void EntryItem::setHover( bool hasHover )
+{
+ mHasHover = hasHover;
+}
+
+void EntryItem::setPaintActive( bool paintActive )
+{
+ mPaintActive = paintActive;
+}
+
+// ************************************************
+
+Navigator::Navigator(bool _selectable, KPopupMenu * menu, IconSidePane *_iconsidepane, QWidget *parent, const char *name )
+ : KListBox( parent, name ), mSidePane( _iconsidepane ), mPopupMenu( menu )
+{
+ setSelectionMode( KListBox::Single );
+ viewport()->setBackgroundMode( PaletteBackground );
+ setFrameStyle( QFrame::NoFrame );
+ setHScrollBarMode( QScrollView::AlwaysOff );
+ //setAcceptDrops( true );
+ mMinWidth = 0;
+ mSelectable = _selectable;
+ executedItem = 0;
+ mMouseOn = 0;
+
+ setFocusPolicy( NoFocus );
+
+ connect( this, SIGNAL( clicked( QListBoxItem* ) ),
+ SLOT( slotExecuted( QListBoxItem* ) ) );
+ connect( this, SIGNAL( onItem( QListBoxItem * ) ),
+ SLOT( slotMouseOn( QListBoxItem * ) ) );
+ connect( this, SIGNAL( onViewport() ), SLOT( slotMouseOff() ) );
+
+ QToolTip::remove( this );
+ if ( !mSidePane->showText() )
+ new EntryItemToolTip( this );
+}
+
+IconViewMode Navigator::viewMode()
+{
+ return mSidePane->viewMode();
+}
+
+bool Navigator::showText()
+{
+ return mSidePane->showText();
+}
+
+bool Navigator::showIcons()
+{
+ return mSidePane->showIcons();
+}
+
+void Navigator::mouseReleaseEvent(QMouseEvent *e)
+{
+ KListBox::mouseReleaseEvent(e);
+ if ( e->button() != LeftButton || !mLeftMouseButtonPressed )
+ return;
+ if ( itemAt( e->pos() ) && executedItem == selectedItem() )
+ emit itemSelected( currentItem() );
+ if ( !mSelectable )
+ clearSelection();
+}
+
+void Navigator::mousePressEvent(QMouseEvent *e)
+{
+ if ( e->button() != LeftButton || itemAt( e->pos() ) == 0 )
+ {
+ mLeftMouseButtonPressed = false;
+ if (e->button() == RightButton)
+ slotShowRMBMenu( 0,mapToGlobal( e->pos() ) );
+ return;
+ }
+ else
+ mLeftMouseButtonPressed = true;
+ KListBox::mousePressEvent(e);
+}
+
+void Navigator::enterEvent( QEvent *event )
+{
+ // work around Qt behaviour: onItem is not emmitted in enterEvent()
+ KListBox::enterEvent( event );
+ emit onItem( itemAt( mapFromGlobal( QCursor::pos() ) ) );
+}
+
+void Navigator::slotExecuted( QListBoxItem *item )
+{
+ if ( !item )
+ return;
+ executedItem = item;
+}
+
+QSize Navigator::sizeHint() const
+{
+ return QSize( mMinWidth, 100 );
+}
+
+void Navigator::calculateMinWidth()
+{
+ mMinWidth = mSidePane->minWidth();
+
+ for (EntryItem *item = static_cast<EntryItem *>(firstItem()) ; item; item = static_cast<EntryItem *>(item->next()))
+ {
+ if (item->width( this ) > mMinWidth)
+ mMinWidth = item->width( this );
+ }
+ //kdDebug() << "minWidth:" << mMinWidth << endl;
+ parentWidget()->setFixedWidth( mMinWidth );
+ triggerUpdate(true);
+}
+
+int Navigator::insertItem(const QString &_text, const QString & _pix)
+{
+ EntryItem *item = new EntryItem( this, count(), _text, _pix );
+ if (item->width( this ) > mSidePane->minWidth() )
+ {
+ mMinWidth = item->width( this );
+ parentWidget()->setMinimumWidth( mMinWidth );
+ //kdDebug() << "minWidth:" << mMinWidth << endl;
+ }
+ return item->id();
+}
+
+void Navigator::setHoverItem( QListBoxItem* item, bool hover )
+{
+ static_cast<EntryItem*>( item )->setHover( hover );
+ updateItem( item );
+}
+
+void Navigator::setPaintActiveItem( QListBoxItem* item, bool paintActive )
+{
+ static_cast<EntryItem*>( item )->setPaintActive( paintActive );
+ updateItem( item );
+}
+
+void Navigator::slotMouseOn( QListBoxItem* newItem )
+{
+ QListBoxItem* oldItem = mMouseOn;
+ if ( oldItem == newItem )
+ return;
+
+ if ( oldItem && !oldItem->isCurrent() && !oldItem->isSelected() )
+ setHoverItem( oldItem, false );
+
+ if ( newItem && !newItem->isCurrent() && !newItem->isSelected() )
+ setHoverItem( newItem, true );
+ mMouseOn = newItem;
+}
+
+void Navigator::slotMouseOff()
+{
+ slotMouseOn( 0 );
+}
+
+void Navigator::resizeEvent( QResizeEvent *event )
+{
+ QListBox::resizeEvent( event );
+ triggerUpdate( true );
+}
+
+void Navigator::slotShowRMBMenu( QListBoxItem *, const QPoint &pos )
+{
+ int choice = mPopupMenu->exec( pos );
+
+ if ( choice == -1 )
+ return;
+
+ mSidePane->resetWidth();
+ if ( choice >= SmallIcons ) {
+ mSidePane->setViewMode( mSidePane->sizeIntToEnum( choice ) );
+ mPopupMenu->setItemChecked( (int)SmallIcons, false);
+ mPopupMenu->setItemChecked( (int)NormalIcons, false);
+ mPopupMenu->setItemChecked( (int)LargeIcons, false);
+ mPopupMenu->setItemChecked( mSidePane->viewMode(), true);
+ KoShellSettings::setSidePaneIconSize( choice );
+ }
+ else
+ {
+ // either icons or text were toggled
+ if ( choice == ShowIcons ) {
+ mSidePane->toogleIcons();
+ mPopupMenu->setItemChecked( (int)ShowIcons, mSidePane->showIcons() );
+ mPopupMenu->setItemEnabled( (int)ShowText, mSidePane->showIcons() );
+ mPopupMenu->setItemEnabled( (int)SmallIcons, mSidePane->showIcons());
+ mPopupMenu->setItemEnabled( (int)NormalIcons, mSidePane->showIcons());
+ mPopupMenu->setItemEnabled( (int)LargeIcons, mSidePane->showIcons());
+ KoShellSettings::setSidePaneShowIcons( mSidePane->showIcons() );
+
+ QToolTip::remove( this );
+ } else {
+ mSidePane->toogleText();
+ mSidePane->resetWidth();
+ mPopupMenu->setItemChecked( (int)ShowText, mSidePane->showText() );
+ mPopupMenu->setItemEnabled( (int)ShowIcons, mSidePane->showText() );
+ mPopupMenu->setItemEnabled( (int)SmallIcons, true);
+ mPopupMenu->setItemEnabled( (int)NormalIcons, true);
+ mPopupMenu->setItemEnabled( (int)LargeIcons, true);
+ KoShellSettings::setSidePaneShowText( mSidePane->showText() );
+ new EntryItemToolTip( this );
+// if ( !mSidePane->showText() )
+// mSidePane->buttonGroup()->hide();
+// else
+// mSidePane->buttonGroup()->show();
+ }
+ }
+ calculateMinWidth();
+ emit updateAllWidgets();
+}
+
+// ************************************************
+
+IconSidePane::IconSidePane(QWidget *parent, const char *name )
+ : QVBox( parent, name )
+{
+ m_buttongroup = new QButtonGroup(1, QGroupBox::Horizontal, this);
+ m_buttongroup->setExclusive(true);
+ m_buttongroup->hide();
+ mWidgetstack = new QWidgetStack(this);
+ mWidgetstack->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+
+ // setup the popup menu
+ mShowIcons = KoShellSettings::sidePaneShowIcons();
+ mShowText = KoShellSettings::sidePaneShowText();
+ mViewMode = sizeIntToEnum( KoShellSettings::sidePaneIconSize() );
+ mPopupMenu = new KPopupMenu(0);
+ mPopupMenu->insertTitle( i18n( "Icon Size" ) );
+ mPopupMenu->insertItem( i18n( "Large" ), (int)LargeIcons );
+ mPopupMenu->setItemEnabled( (int)LargeIcons, mShowIcons );
+ mPopupMenu->insertItem( i18n( "Normal" ), (int)NormalIcons );
+ mPopupMenu->setItemEnabled( (int)NormalIcons, mShowIcons );
+ mPopupMenu->insertItem( i18n( "Small" ), (int)SmallIcons );
+ mPopupMenu->setItemEnabled( (int)SmallIcons, mShowIcons );
+ mPopupMenu->setItemChecked( (int)mViewMode, true );
+ mPopupMenu->insertSeparator();
+ mPopupMenu->insertItem( i18n( "Show Icons" ), (int)ShowIcons );
+ mPopupMenu->setItemChecked( (int)ShowIcons, mShowIcons );
+ mPopupMenu->setItemEnabled( (int)ShowIcons, mShowText );
+ mPopupMenu->insertItem( i18n( "Show Text" ), (int)ShowText );
+ mPopupMenu->setItemChecked( (int)ShowText, mShowText );
+ mPopupMenu->setItemEnabled( (int)ShowText, mShowIcons );
+ if ( !mShowText )
+ m_buttongroup->hide();
+}
+
+IconSidePane::~IconSidePane()
+{
+}
+
+int IconSidePane::insertItem(int _grp, const QString & _pix, const QString &_text)
+{
+ return static_cast<Navigator*>( mWidgetstack->widget(_grp))->insertItem( _text, _pix );
+}
+
+int IconSidePane::insertItem(const QString & _pix, const QString &_text)
+{
+ return mCurrentNavigator->insertItem(_text, _pix);
+}
+
+void IconSidePane::renameItem( int _grp, int _id, const QString & _text )
+{
+ Navigator *navigator = static_cast<Navigator*>(mWidgetstack->widget(_grp));
+ if (!navigator)
+ return;
+ EntryItem *item = 0;
+ for (uint i=0; i< navigator->count(); i++)
+ {
+ item = static_cast<EntryItem *>(navigator->item(i));
+ if (_id == item->id())
+ {
+ item->setNewText(_text);
+ navigator->triggerUpdate(false);
+ break;
+ }
+ }
+}
+
+void IconSidePane::removeItem( int _grp, int _id )
+{
+ Navigator *navigator = static_cast<Navigator*>(mWidgetstack->widget(_grp));
+ if (!navigator)
+ return;
+ for (uint i=0; i< navigator->count(); i++)
+ {
+ if (_id == static_cast<EntryItem *>(navigator->item(i))->id())
+ {
+ navigator->removeItem(i);
+ break;
+ }
+ }
+}
+
+int IconSidePane::insertGroup(const QString &_text, bool _selectable, QObject *_obj, const char *_slot)
+{
+ mCurrentNavigator = new Navigator(_selectable, mPopupMenu, this, mWidgetstack );
+ //connect( mCurrentNavigator, SIGNAL( itemSelected( int ) ), this, SLOT( itemSelected( int ) ) );
+ if ( _obj != 0L && _slot != 0L )
+ connect( mCurrentNavigator, SIGNAL( itemSelected(int ) ), _obj, _slot );
+ connect( mCurrentNavigator, SIGNAL( updateAllWidgets() ), this, SLOT(updateAllWidgets()) );
+ int const id = mWidgetstack->addWidget(mCurrentNavigator);
+ mWidgetStackIds.append( id );
+ KPushButton *b = new KPushButton( _text, m_buttongroup );
+ m_buttongroup->insert( b, id );
+ connect( b, SIGNAL( clicked() ), this, SLOT( buttonClicked() ) );
+ b->setToggleButton( true );
+ b->setFocusPolicy( NoFocus );
+ if (m_buttongroup->count()==1)
+ {
+ mCurrentNavigator->calculateMinWidth();
+ m_buttongroup->setButton(m_buttongroup->id(b));
+ mWidgetstack->raiseWidget(id);
+ }
+ if ( b->width() > minimumWidth() )
+ setMinimumWidth( b->width() );
+ return id;
+}
+
+void IconSidePane::buttonClicked()
+{
+ mWidgetstack->raiseWidget( m_buttongroup->selectedId() );
+}
+
+void IconSidePane::selectGroup(int group_id)
+{
+ mWidgetstack->raiseWidget(group_id);
+}
+
+void IconSidePane::itemSelected(int item)
+{
+ kdDebug() << "Item selected:" << item << endl;
+}
+
+Navigator * IconSidePane::group(int _grp)
+{
+ return static_cast<Navigator*>(mWidgetstack->widget(_grp));
+}
+
+void IconSidePane::updateAllWidgets()
+{
+ QValueList<int>::iterator it;
+ for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
+ static_cast<Navigator*>(mWidgetstack->widget(*it))->triggerUpdate( true );
+}
+
+int IconSidePane::minWidth()
+{
+ int width = 0;
+ QValueList<int>::iterator it;
+ Navigator *n;
+ for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
+ {
+ n = static_cast<Navigator*>(mWidgetstack->widget(*it));
+ if ( n->minWidth() > width )
+ width = n->minWidth();
+ }
+ return width;
+}
+
+void IconSidePane::resetWidth()
+{
+ QValueList<int>::iterator it;
+ Navigator *n;
+ for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
+ {
+ n = static_cast<Navigator*>(mWidgetstack->widget(*it));
+ n->resetWidth();
+ n->triggerUpdate(true);
+ }
+}
+
+IconViewMode IconSidePane::sizeIntToEnum(int size) const
+{
+ switch ( size ) {
+ case int(LargeIcons):
+ return LargeIcons;
+ break;
+ case int(NormalIcons):
+ return NormalIcons;
+ break;
+ case int(SmallIcons):
+ return SmallIcons;
+ break;
+ default:
+ // Stick with sane values
+ return NormalIcons;
+ kdDebug() << "View mode not implemented!" << endl;
+ break;
+ }
+}
+
+void IconSidePane::setActionCollection( KActionCollection *actionCollection )
+{
+ mActionCollection = actionCollection;
+}
+
+KActionCollection *IconSidePane::actionCollection() const
+{
+ return mActionCollection;
+}
+
+#include "iconsidepane.moc"
+
+// vim: sw=2 sts=2 et tw=80