KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

596 lines
17KB

  1. /*
  2. This file is part of KDE KOffice project.
  3. Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>
  4. Copyright (C) 2005 Fredrik Edemar <f_edemar@linux.se>
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; see the file COPYING. If not, write to
  15. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. * Boston, MA 02110-1301, USA.
  17. */
  18. #include <tqbitmap.h>
  19. #include <tqcursor.h>
  20. #include <tqdrawutil.h>
  21. #include <tqfontmetrics.h>
  22. #include <tqframe.h>
  23. #include <tqlabel.h>
  24. #include <tqobjectlist.h>
  25. #include <tqpainter.h>
  26. #include <tqptrlist.h>
  27. #include <tqstyle.h>
  28. #include <tqtooltip.h>
  29. #include <tqwidgetstack.h>
  30. #include <tdeapplication.h>
  31. #include <kdebug.h>
  32. #include <kdialog.h>
  33. #include <kiconloader.h>
  34. #include <tdelocale.h>
  35. #include <tdepopupmenu.h>
  36. #include <kpushbutton.h>
  37. #include "iconsidepane.h"
  38. EntryItem::EntryItem( Navigator *parent, int _id, const TQString &_text, const TQString & _pix )
  39. : TQListBoxItem( parent ),
  40. mPixmapName(_pix),
  41. mId(_id),
  42. mHasHover( false ),
  43. mPaintActive( false )
  44. {
  45. reloadPixmap();
  46. setCustomHighlighting( true );
  47. setText( _text );
  48. }
  49. EntryItem::~EntryItem()
  50. {
  51. }
  52. void EntryItem::setNewText(const TQString &_text)
  53. {
  54. setText( _text );
  55. }
  56. void EntryItem::reloadPixmap()
  57. {
  58. int size = (int)navigator()->viewMode();
  59. if ( size != 0 )
  60. mPixmap = TDEGlobal::iconLoader()->loadIcon( mPixmapName, TDEIcon::Desktop, size );
  61. else
  62. mPixmap = TQPixmap();
  63. }
  64. Navigator* EntryItem::navigator() const
  65. {
  66. return static_cast<Navigator*>( listBox() );
  67. }
  68. int EntryItem::width( const TQListBox *listbox ) const
  69. {
  70. int w = 0;
  71. if( navigator()->showIcons() ) {
  72. w = navigator()->viewMode();
  73. if ( navigator()->viewMode() == SmallIcons )
  74. w += 4;
  75. }
  76. if( navigator()->showText() ) {
  77. if ( navigator()->viewMode() == SmallIcons )
  78. w += listbox->fontMetrics().width( text() );
  79. else
  80. w = TQMAX( w, listbox->fontMetrics().width( text() ) );
  81. }
  82. return w + ( KDialog::marginHint() * 2 );
  83. }
  84. int EntryItem::height( const TQListBox *listbox ) const
  85. {
  86. int h = 0;
  87. if ( navigator()->showIcons() )
  88. h = (int)navigator()->viewMode() + 4;
  89. if ( navigator()->showText() ) {
  90. if ( navigator()->viewMode() == SmallIcons || !navigator()->showIcons() )
  91. h = TQMAX( h, listbox->fontMetrics().lineSpacing() ) + KDialog::spacingHint() * 2;
  92. else
  93. h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing() + 4;
  94. }
  95. return h;
  96. }
  97. void EntryItem::paint( TQPainter *p )
  98. {
  99. reloadPixmap();
  100. TQListBox *box = listBox();
  101. bool iconAboveText = ( navigator()->viewMode() > SmallIcons )
  102. && navigator()->showIcons();
  103. int w = box->viewport()->width();
  104. int y = 2;
  105. // draw selected
  106. if ( isCurrent() || isSelected() || mHasHover || mPaintActive ) {
  107. int h = height( box );
  108. TQBrush brush;
  109. if ( isCurrent() || isSelected() || mPaintActive )
  110. brush = box->colorGroup().brush( TQColorGroup::Highlight );
  111. else
  112. brush = TQBrush(box->colorGroup().highlight().light( 115 ));
  113. p->fillRect( 1, 0, w - 2, h - 1, brush );
  114. TQPen pen = p->pen();
  115. TQPen oldPen = pen;
  116. pen.setColor( box->colorGroup().mid() );
  117. p->setPen( pen );
  118. p->drawPoint( 1, 0 );
  119. p->drawPoint( 1, h - 2 );
  120. p->drawPoint( w - 2, 0 );
  121. p->drawPoint( w - 2, h - 2 );
  122. p->setPen( oldPen );
  123. }
  124. if ( !mPixmap.isNull() && navigator()->showIcons() ) {
  125. int x = iconAboveText ? ( ( w - mPixmap.width() ) / 2 ) :
  126. KDialog::marginHint();
  127. p->drawPixmap( x, y, mPixmap );
  128. }
  129. TQColor shadowColor = listBox()->colorGroup().background().dark(115);
  130. if ( isCurrent() || isSelected() ) {
  131. p->setPen( box->colorGroup().highlightedText() );
  132. }
  133. if ( !text().isEmpty() && navigator()->showText() ) {
  134. TQFontMetrics fm = p->fontMetrics();
  135. int x = 0;
  136. if ( iconAboveText ) {
  137. x = ( w - fm.width( text() ) ) / 2;
  138. y += fm.height() - fm.descent();
  139. if ( navigator()->showIcons() )
  140. y += mPixmap.height();
  141. } else {
  142. x = KDialog::marginHint() + 4;
  143. if( navigator()->showIcons() ) {
  144. x += mPixmap.width();
  145. }
  146. if ( !navigator()->showIcons() || mPixmap.height() < fm.height() )
  147. y += fm.ascent() + fm.leading()/2;
  148. else
  149. y += mPixmap.height()/2 - fm.height()/2 + fm.ascent();
  150. }
  151. if ( isCurrent() || isSelected() || mHasHover ) {
  152. p->setPen( box->colorGroup().highlight().dark(115) );
  153. p->drawText( x + ( TQApplication::reverseLayout() ? -1 : 1),
  154. y + 1, text() );
  155. p->setPen( box->colorGroup().highlightedText() );
  156. }
  157. else
  158. p->setPen( box->colorGroup().text() );
  159. p->drawText( x, y, text() );
  160. }
  161. // ensure that we don't have a stale flag around
  162. if ( isCurrent() || isSelected() ) mHasHover = false;
  163. }
  164. void EntryItem::setHover( bool hasHover )
  165. {
  166. mHasHover = hasHover;
  167. }
  168. void EntryItem::setPaintActive( bool paintActive )
  169. {
  170. mPaintActive = paintActive;
  171. }
  172. // ************************************************
  173. Navigator::Navigator(bool _selectable, TDEPopupMenu * menu, IconSidePane *_iconsidepane, TQWidget *parent, const char *name )
  174. : TDEListBox( parent, name ), mSidePane( _iconsidepane ), mPopupMenu( menu )
  175. {
  176. setSelectionMode( TDEListBox::Single );
  177. viewport()->setBackgroundMode( PaletteBackground );
  178. setFrameStyle( TQFrame::NoFrame );
  179. setHScrollBarMode( TQScrollView::AlwaysOff );
  180. //setAcceptDrops( true );
  181. mMinWidth = 0;
  182. mSelectable = _selectable;
  183. executedItem = 0;
  184. mMouseOn = 0;
  185. setFocusPolicy( TQ_NoFocus );
  186. connect( this, TQT_SIGNAL( clicked( TQListBoxItem* ) ),
  187. TQT_SLOT( slotExecuted( TQListBoxItem* ) ) );
  188. connect( this, TQT_SIGNAL( onItem( TQListBoxItem * ) ),
  189. TQT_SLOT( slotMouseOn( TQListBoxItem * ) ) );
  190. connect( this, TQT_SIGNAL( onViewport() ), TQT_SLOT( slotMouseOff() ) );
  191. TQToolTip::remove( this );
  192. if ( !mSidePane->showText() )
  193. new EntryItemToolTip( this );
  194. }
  195. IconViewMode Navigator::viewMode()
  196. {
  197. return mSidePane->viewMode();
  198. }
  199. bool Navigator::showText()
  200. {
  201. return mSidePane->showText();
  202. }
  203. bool Navigator::showIcons()
  204. {
  205. return mSidePane->showIcons();
  206. }
  207. void Navigator::mouseReleaseEvent(TQMouseEvent *e)
  208. {
  209. TDEListBox::mouseReleaseEvent(e);
  210. if ( e->button() != Qt::LeftButton || !mLeftMouseButtonPressed )
  211. return;
  212. if ( itemAt( e->pos() ) && executedItem == selectedItem() )
  213. emit itemSelected( currentItem() );
  214. if ( !mSelectable )
  215. clearSelection();
  216. }
  217. void Navigator::mousePressEvent(TQMouseEvent *e)
  218. {
  219. if ( e->button() != Qt::LeftButton || itemAt( e->pos() ) == 0 )
  220. {
  221. mLeftMouseButtonPressed = false;
  222. if (e->button() == Qt::RightButton)
  223. slotShowRMBMenu( 0,mapToGlobal( e->pos() ) );
  224. return;
  225. }
  226. else
  227. mLeftMouseButtonPressed = true;
  228. TDEListBox::mousePressEvent(e);
  229. }
  230. void Navigator::enterEvent( TQEvent *event )
  231. {
  232. // work around TQt behaviour: onItem is not emmitted in enterEvent()
  233. TDEListBox::enterEvent( event );
  234. emit onItem( itemAt( mapFromGlobal( TQCursor::pos() ) ) );
  235. }
  236. void Navigator::slotExecuted( TQListBoxItem *item )
  237. {
  238. if ( !item )
  239. return;
  240. executedItem = item;
  241. }
  242. TQSize Navigator::sizeHint() const
  243. {
  244. return TQSize( mMinWidth, 100 );
  245. }
  246. void Navigator::calculateMinWidth()
  247. {
  248. mMinWidth = mSidePane->minWidth();
  249. for (EntryItem *item = static_cast<EntryItem *>(firstItem()) ; item; item = static_cast<EntryItem *>(item->next()))
  250. {
  251. if (item->width( this ) > mMinWidth)
  252. mMinWidth = item->width( this );
  253. }
  254. //kdDebug() << "minWidth:" << mMinWidth << endl;
  255. parentWidget()->setFixedWidth( mMinWidth );
  256. triggerUpdate(true);
  257. }
  258. int Navigator::insertItem(const TQString &_text, const TQString & _pix)
  259. {
  260. EntryItem *item = new EntryItem( this, count(), _text, _pix );
  261. if (item->width( this ) > mSidePane->minWidth() )
  262. {
  263. mMinWidth = item->width( this );
  264. parentWidget()->setMinimumWidth( mMinWidth );
  265. //kdDebug() << "minWidth:" << mMinWidth << endl;
  266. }
  267. return item->id();
  268. }
  269. void Navigator::setHoverItem( TQListBoxItem* item, bool hover )
  270. {
  271. static_cast<EntryItem*>( item )->setHover( hover );
  272. updateItem( item );
  273. }
  274. void Navigator::setPaintActiveItem( TQListBoxItem* item, bool paintActive )
  275. {
  276. static_cast<EntryItem*>( item )->setPaintActive( paintActive );
  277. updateItem( item );
  278. }
  279. void Navigator::slotMouseOn( TQListBoxItem* newItem )
  280. {
  281. TQListBoxItem* oldItem = mMouseOn;
  282. if ( oldItem == newItem )
  283. return;
  284. if ( oldItem && !oldItem->isCurrent() && !oldItem->isSelected() )
  285. setHoverItem( oldItem, false );
  286. if ( newItem && !newItem->isCurrent() && !newItem->isSelected() )
  287. setHoverItem( newItem, true );
  288. mMouseOn = newItem;
  289. }
  290. void Navigator::slotMouseOff()
  291. {
  292. slotMouseOn( 0 );
  293. }
  294. void Navigator::resizeEvent( TQResizeEvent *event )
  295. {
  296. TQListBox::resizeEvent( event );
  297. triggerUpdate( true );
  298. }
  299. void Navigator::slotShowRMBMenu( TQListBoxItem *, const TQPoint &pos )
  300. {
  301. int choice = mPopupMenu->exec( pos );
  302. if ( choice == -1 )
  303. return;
  304. mSidePane->resetWidth();
  305. if ( choice >= SmallIcons ) {
  306. mSidePane->setViewMode( mSidePane->sizeIntToEnum( choice ) );
  307. mPopupMenu->setItemChecked( (int)SmallIcons, false);
  308. mPopupMenu->setItemChecked( (int)NormalIcons, false);
  309. mPopupMenu->setItemChecked( (int)LargeIcons, false);
  310. mPopupMenu->setItemChecked( mSidePane->viewMode(), true);
  311. KoShellSettings::setSidePaneIconSize( choice );
  312. }
  313. else
  314. {
  315. // either icons or text were toggled
  316. if ( choice == ShowIcons ) {
  317. mSidePane->toogleIcons();
  318. mPopupMenu->setItemChecked( (int)ShowIcons, mSidePane->showIcons() );
  319. mPopupMenu->setItemEnabled( (int)ShowText, mSidePane->showIcons() );
  320. mPopupMenu->setItemEnabled( (int)SmallIcons, mSidePane->showIcons());
  321. mPopupMenu->setItemEnabled( (int)NormalIcons, mSidePane->showIcons());
  322. mPopupMenu->setItemEnabled( (int)LargeIcons, mSidePane->showIcons());
  323. KoShellSettings::setSidePaneShowIcons( mSidePane->showIcons() );
  324. TQToolTip::remove( this );
  325. } else {
  326. mSidePane->toogleText();
  327. mSidePane->resetWidth();
  328. mPopupMenu->setItemChecked( (int)ShowText, mSidePane->showText() );
  329. mPopupMenu->setItemEnabled( (int)ShowIcons, mSidePane->showText() );
  330. mPopupMenu->setItemEnabled( (int)SmallIcons, true);
  331. mPopupMenu->setItemEnabled( (int)NormalIcons, true);
  332. mPopupMenu->setItemEnabled( (int)LargeIcons, true);
  333. KoShellSettings::setSidePaneShowText( mSidePane->showText() );
  334. new EntryItemToolTip( this );
  335. // if ( !mSidePane->showText() )
  336. // mSidePane->buttonGroup()->hide();
  337. // else
  338. // mSidePane->buttonGroup()->show();
  339. }
  340. }
  341. calculateMinWidth();
  342. emit updateAllWidgets();
  343. }
  344. // ************************************************
  345. IconSidePane::IconSidePane(TQWidget *parent, const char *name )
  346. : TQVBox( parent, name )
  347. {
  348. m_buttongroup = new TQButtonGroup(1, Qt::Horizontal, this);
  349. m_buttongroup->setExclusive(true);
  350. m_buttongroup->hide();
  351. mWidgetstack = new TQWidgetStack(this);
  352. mWidgetstack->setSizePolicy(TQSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding));
  353. // setup the popup menu
  354. mShowIcons = KoShellSettings::sidePaneShowIcons();
  355. mShowText = KoShellSettings::sidePaneShowText();
  356. mViewMode = sizeIntToEnum( KoShellSettings::sidePaneIconSize() );
  357. mPopupMenu = new TDEPopupMenu(0);
  358. mPopupMenu->insertTitle( i18n( "Icon Size" ) );
  359. mPopupMenu->insertItem( i18n( "Large" ), (int)LargeIcons );
  360. mPopupMenu->setItemEnabled( (int)LargeIcons, mShowIcons );
  361. mPopupMenu->insertItem( i18n( "Normal" ), (int)NormalIcons );
  362. mPopupMenu->setItemEnabled( (int)NormalIcons, mShowIcons );
  363. mPopupMenu->insertItem( i18n( "Small" ), (int)SmallIcons );
  364. mPopupMenu->setItemEnabled( (int)SmallIcons, mShowIcons );
  365. mPopupMenu->setItemChecked( (int)mViewMode, true );
  366. mPopupMenu->insertSeparator();
  367. mPopupMenu->insertItem( i18n( "Show Icons" ), (int)ShowIcons );
  368. mPopupMenu->setItemChecked( (int)ShowIcons, mShowIcons );
  369. mPopupMenu->setItemEnabled( (int)ShowIcons, mShowText );
  370. mPopupMenu->insertItem( i18n( "Show Text" ), (int)ShowText );
  371. mPopupMenu->setItemChecked( (int)ShowText, mShowText );
  372. mPopupMenu->setItemEnabled( (int)ShowText, mShowIcons );
  373. if ( !mShowText )
  374. m_buttongroup->hide();
  375. }
  376. IconSidePane::~IconSidePane()
  377. {
  378. }
  379. int IconSidePane::insertItem(int _grp, const TQString & _pix, const TQString &_text)
  380. {
  381. return static_cast<Navigator*>( mWidgetstack->widget(_grp))->insertItem( _text, _pix );
  382. }
  383. int IconSidePane::insertItem(const TQString & _pix, const TQString &_text)
  384. {
  385. return mCurrentNavigator->insertItem(_text, _pix);
  386. }
  387. void IconSidePane::renameItem( int _grp, int _id, const TQString & _text )
  388. {
  389. Navigator *navigator = static_cast<Navigator*>(mWidgetstack->widget(_grp));
  390. if (!navigator)
  391. return;
  392. EntryItem *item = 0;
  393. for (uint i=0; i< navigator->count(); i++)
  394. {
  395. item = static_cast<EntryItem *>(navigator->item(i));
  396. if (_id == item->id())
  397. {
  398. item->setNewText(_text);
  399. navigator->triggerUpdate(false);
  400. break;
  401. }
  402. }
  403. }
  404. void IconSidePane::removeItem( int _grp, int _id )
  405. {
  406. Navigator *navigator = static_cast<Navigator*>(mWidgetstack->widget(_grp));
  407. if (!navigator)
  408. return;
  409. for (uint i=0; i< navigator->count(); i++)
  410. {
  411. if (_id == static_cast<EntryItem *>(navigator->item(i))->id())
  412. {
  413. navigator->removeItem(i);
  414. break;
  415. }
  416. }
  417. }
  418. int IconSidePane::insertGroup(const TQString &_text, bool _selectable, TQObject *_obj, const char *_slot)
  419. {
  420. mCurrentNavigator = new Navigator(_selectable, mPopupMenu, this, mWidgetstack );
  421. //connect( mCurrentNavigator, TQT_SIGNAL( itemSelected( int ) ), this, TQT_SLOT( itemSelected( int ) ) );
  422. if ( _obj != 0L && _slot != 0L )
  423. connect( mCurrentNavigator, TQT_SIGNAL( itemSelected(int ) ), _obj, _slot );
  424. connect( mCurrentNavigator, TQT_SIGNAL( updateAllWidgets() ), this, TQT_SLOT(updateAllWidgets()) );
  425. int const id = mWidgetstack->addWidget(mCurrentNavigator);
  426. mWidgetStackIds.append( id );
  427. KPushButton *b = new KPushButton( _text, m_buttongroup );
  428. m_buttongroup->insert( b, id );
  429. connect( b, TQT_SIGNAL( clicked() ), this, TQT_SLOT( buttonClicked() ) );
  430. b->setToggleButton( true );
  431. b->setFocusPolicy( TQ_NoFocus );
  432. if (m_buttongroup->count()==1)
  433. {
  434. mCurrentNavigator->calculateMinWidth();
  435. m_buttongroup->setButton(m_buttongroup->id(b));
  436. mWidgetstack->raiseWidget(id);
  437. }
  438. if ( b->width() > minimumWidth() )
  439. setMinimumWidth( b->width() );
  440. return id;
  441. }
  442. void IconSidePane::buttonClicked()
  443. {
  444. mWidgetstack->raiseWidget( m_buttongroup->selectedId() );
  445. }
  446. void IconSidePane::selectGroup(int group_id)
  447. {
  448. mWidgetstack->raiseWidget(group_id);
  449. }
  450. void IconSidePane::itemSelected(int item)
  451. {
  452. kdDebug() << "Item selected:" << item << endl;
  453. }
  454. Navigator * IconSidePane::group(int _grp)
  455. {
  456. return static_cast<Navigator*>(mWidgetstack->widget(_grp));
  457. }
  458. void IconSidePane::updateAllWidgets()
  459. {
  460. TQValueList<int>::iterator it;
  461. for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
  462. static_cast<Navigator*>(mWidgetstack->widget(*it))->triggerUpdate( true );
  463. }
  464. int IconSidePane::minWidth()
  465. {
  466. int width = 0;
  467. TQValueList<int>::iterator it;
  468. Navigator *n;
  469. for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
  470. {
  471. n = static_cast<Navigator*>(mWidgetstack->widget(*it));
  472. if ( n->minWidth() > width )
  473. width = n->minWidth();
  474. }
  475. return width;
  476. }
  477. void IconSidePane::resetWidth()
  478. {
  479. TQValueList<int>::iterator it;
  480. Navigator *n;
  481. for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
  482. {
  483. n = static_cast<Navigator*>(mWidgetstack->widget(*it));
  484. n->resetWidth();
  485. n->triggerUpdate(true);
  486. }
  487. }
  488. IconViewMode IconSidePane::sizeIntToEnum(int size) const
  489. {
  490. switch ( size ) {
  491. case int(LargeIcons):
  492. return LargeIcons;
  493. break;
  494. case int(NormalIcons):
  495. return NormalIcons;
  496. break;
  497. case int(SmallIcons):
  498. return SmallIcons;
  499. break;
  500. default:
  501. // Stick with sane values
  502. return NormalIcons;
  503. kdDebug() << "View mode not implemented!" << endl;
  504. break;
  505. }
  506. }
  507. void IconSidePane::setActionCollection( TDEActionCollection *actionCollection )
  508. {
  509. mActionCollection = actionCollection;
  510. }
  511. TDEActionCollection *IconSidePane::actionCollection() const
  512. {
  513. return mActionCollection;
  514. }
  515. #include "iconsidepane.moc"
  516. // vim: sw=2 sts=2 et tw=80