|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2004, 2005 Max Howell <max.howell@methylblue.com> *
|
|
|
|
* *
|
|
|
|
* 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 "amarok.h"
|
|
|
|
#include "amarokconfig.h"
|
|
|
|
#include "browserbar.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "enginecontroller.h"
|
|
|
|
#include "multitabbar.h" //m_tabBar
|
|
|
|
|
|
|
|
#include <kapplication.h> //kapp
|
|
|
|
#include <kconfig.h>
|
|
|
|
#include <kiconloader.h> //multiTabBar icons
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
#include <tqcursor.h> //for resize cursor
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqsignalmapper.h> //m_mapper
|
|
|
|
#include <tqstyle.h> //Amarok::Splitter
|
|
|
|
#include <tqtooltip.h>
|
|
|
|
|
|
|
|
|
|
|
|
// we emulate a qsplitter, mostly for historic reasons, but there are still a few advantages
|
|
|
|
// mostly we can stop the browserbar getting resized too small so that switching browser looks wrong
|
|
|
|
|
|
|
|
|
|
|
|
namespace Amarok
|
|
|
|
{
|
|
|
|
class Splitter : public TQWidget {
|
|
|
|
public:
|
|
|
|
Splitter( BrowserBar *w ) : TQWidget( w, "divider" )
|
|
|
|
{
|
|
|
|
setCursor( TQCursor(SplitHCursor) );
|
|
|
|
styleChange( tqstyle() );
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void paintEvent( TQPaintEvent* )
|
|
|
|
{
|
|
|
|
TQPainter p( this );
|
|
|
|
parentWidget()->tqstyle().tqdrawPrimitive( TQStyle::PE_Splitter, &p, rect(), colorGroup(), TQStyle::Style_Horizontal );
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void styleChange( TQStyle& )
|
|
|
|
{
|
|
|
|
setFixedWidth( tqstyle().pixelMetric( TQStyle::PM_SplitterWidth, this ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void mouseMoveEvent( TQMouseEvent *e )
|
|
|
|
{
|
|
|
|
static_cast<BrowserBar*>(TQT_TQWIDGET(parent()))->mouseMovedOverSplitter( e );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
BrowserBar* BrowserBar::s_instance = 0;
|
|
|
|
|
|
|
|
BrowserBar::BrowserBar( TQWidget *parent )
|
|
|
|
: TQWidget( parent, "BrowserBar" )
|
|
|
|
, EngineObserver( EngineController::instance() )
|
|
|
|
, m_playlistBox( new TQVBox( this ) )
|
|
|
|
, m_divider( new Amarok::Splitter( this ) )
|
|
|
|
, m_browserBox( new TQVBox( this ) )
|
|
|
|
, m_currentIndex( -1 )
|
|
|
|
, m_lastIndex( -1 )
|
|
|
|
, m_mapper( new TQSignalMapper( TQT_TQOBJECT(this) ) )
|
|
|
|
{
|
|
|
|
m_tabManagementButton = new TQPushButton( SmallIconSet(Amarok::icon( "configure" )), 0, this, "tab_managment_button" );
|
|
|
|
connect (m_tabManagementButton, TQT_SIGNAL(clicked()), TQT_SLOT(showBrowserSelectionMenu()));
|
|
|
|
m_tabManagementButton->setIsMenuButton ( true ); //deprecated, but since I cannot add menu directly to button it is needed.
|
|
|
|
|
|
|
|
TQToolTip::add (m_tabManagementButton, i18n("Manage tabs"));
|
|
|
|
|
|
|
|
|
|
|
|
m_tabBar = new MultiTabBar( MultiTabBar::Vertical, this );
|
|
|
|
|
|
|
|
|
|
|
|
m_tabManagementButton->setFixedWidth(m_tabBar->sizeHint().width());
|
|
|
|
m_tabManagementButton->setFixedHeight(m_tabBar->sizeHint().width());
|
|
|
|
|
|
|
|
|
|
|
|
s_instance = this;
|
|
|
|
m_pos = m_tabBar->sizeHint().width() + 5; //5 = esthetic spacing
|
|
|
|
|
|
|
|
m_tabBar->setStyle( MultiTabBar::AMAROK );
|
|
|
|
m_tabBar->setPosition( MultiTabBar::Left );
|
|
|
|
m_tabBar->showActiveTabTexts( true );
|
|
|
|
m_tabBar->setFixedWidth( m_pos );
|
|
|
|
m_tabBar->move( 0, 25 );
|
|
|
|
|
|
|
|
TQVBoxLayout *layout = new TQVBoxLayout( m_browserBox );
|
|
|
|
layout->addSpacing( 3 ); // aesthetics
|
|
|
|
layout->setAutoAdd( true );
|
|
|
|
|
|
|
|
m_browserBox->move( m_pos, 0 );
|
|
|
|
m_browserBox->hide();
|
|
|
|
m_divider->hide();
|
|
|
|
m_playlistBox->setSpacing( 1 );
|
|
|
|
|
|
|
|
connect( m_mapper, TQT_SIGNAL(mapped( int )), TQT_SLOT(showHideBrowser( int )) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//m_tabBar->appendButton( Amarok::icon( "configure" ), 1, 0, TQString() );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
BrowserBar::~BrowserBar()
|
|
|
|
{
|
|
|
|
KConfig* const config = Amarok::config( "BrowserBar" );
|
|
|
|
config->writeEntry( "CurrentPane", m_currentIndex != -1 ? TQString(currentBrowser()->name()) : TQString() );
|
|
|
|
config->writeEntry( "Width", m_browserBox->width() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::makeDropProxy( const TQString &name, DropProxyTarget *finalTarget )
|
|
|
|
{
|
|
|
|
int id = m_browserIds[name];
|
|
|
|
MultiTabBarButton *button = m_tabBar->tab( id );
|
|
|
|
if( button )
|
|
|
|
button->proxyDrops( finalTarget );
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
BrowserBar::restoreWidth()
|
|
|
|
{
|
|
|
|
const int index = indexForName( Amarok::config( "BrowserBar" )->readEntry( "CurrentPane" ) );
|
|
|
|
const int width = Amarok::config( "BrowserBar" )->readNumEntry( "Width", browser( index )->sizeHint().width() );
|
|
|
|
|
|
|
|
m_browserBox->resize( width, height() );
|
|
|
|
m_pos = m_browserBox->width() + m_tabBar->width();
|
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::polish()
|
|
|
|
{
|
|
|
|
DEBUG_FUNC_INFO
|
|
|
|
|
|
|
|
TQWidget::polish();
|
|
|
|
|
|
|
|
uint M = 0;
|
|
|
|
foreachType( BrowserList, m_browsers ) {
|
|
|
|
const uint m = (*it)->minimumWidth();
|
|
|
|
if (m > M)
|
|
|
|
M = m;
|
|
|
|
if (m > 250) {
|
|
|
|
warning() << "Browser is too large, mxcl says castrate the developer: " << (*it)->name() << ", " << M << endl;
|
|
|
|
M = 250;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_browserBox->setMinimumWidth( M );
|
|
|
|
const int index = restoreWidth();
|
|
|
|
|
|
|
|
if (index != -1)
|
|
|
|
// if we did it for -1 it ruins the browserBox size
|
|
|
|
showHideBrowser( index );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::adjustWidgetSizes()
|
|
|
|
{
|
|
|
|
//TODO set the geometry of the PlaylistWindow before
|
|
|
|
// the browsers are loaded so this isn't called twice
|
|
|
|
|
|
|
|
const uint w = width();
|
|
|
|
const uint h = height();
|
|
|
|
const uint maxW = maxBrowserWidth();
|
|
|
|
const uint p = (m_pos < maxW) ? m_pos : maxW;
|
|
|
|
const uint ppw = p + m_divider->width();
|
|
|
|
const uint tbw = m_tabBar->width();
|
|
|
|
|
|
|
|
m_divider->move( p, 0 );
|
|
|
|
|
|
|
|
const uint offset = !m_divider->isHidden() ? ppw : tbw;
|
|
|
|
|
|
|
|
m_browserBox->resize( p - tbw, h );
|
|
|
|
m_playlistBox->setGeometry( offset, 0, w - offset, h );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::mouseMovedOverSplitter( TQMouseEvent *e )
|
|
|
|
{
|
|
|
|
const uint oldPos = m_pos;
|
|
|
|
const uint newPos = mapFromGlobal( e->globalPos() ).x();
|
|
|
|
const uint minWidth = m_tabBar->width() + m_browserBox->minimumWidth();
|
|
|
|
const uint maxWidth = maxBrowserWidth();
|
|
|
|
|
|
|
|
if( newPos < minWidth )
|
|
|
|
m_pos = minWidth;
|
|
|
|
|
|
|
|
else if( newPos > maxWidth )
|
|
|
|
m_pos = maxWidth;
|
|
|
|
|
|
|
|
else
|
|
|
|
m_pos = newPos;
|
|
|
|
|
|
|
|
if( m_pos != oldPos )
|
|
|
|
adjustWidgetSizes();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
BrowserBar::event( TQEvent *e )
|
|
|
|
{
|
|
|
|
switch( e->type() )
|
|
|
|
{
|
|
|
|
case TQEvent::LayoutHint:
|
|
|
|
//FIXME include browserholder width
|
|
|
|
setMinimumWidth(
|
|
|
|
m_tabBar->minimumWidth() +
|
|
|
|
m_divider->minimumWidth() +
|
|
|
|
m_browserBox->width() +
|
|
|
|
m_playlistBox->minimumWidth() );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TQEvent::Resize:
|
|
|
|
// DEBUG_LINE_INFO
|
|
|
|
|
|
|
|
m_divider->resize( 0, height() ); //TQt will set width
|
|
|
|
m_tabBar->resize( 0, height() ); //TQt will set width
|
|
|
|
|
|
|
|
adjustWidgetSizes();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TQWidget::event( e );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::addBrowser( const TQString &identifier, TQWidget *widget, const TQString &title, const TQString& icon )
|
|
|
|
{
|
|
|
|
const int id = m_tabBar->tabs()->count(); // the next available id
|
|
|
|
const TQString name( widget->name() );
|
|
|
|
m_browserIds[name] = id;
|
|
|
|
TQWidget *tab;
|
|
|
|
|
|
|
|
widget->reparent( m_browserBox, TQPoint() );
|
|
|
|
widget->hide();
|
|
|
|
|
|
|
|
m_tabBar->appendTab( SmallIcon( icon ), id, title, identifier );
|
|
|
|
tab = m_tabBar->tab( id );
|
|
|
|
tab->setFocusPolicy( TQ_NoFocus ); //FIXME you can focus on the tab, but they respond to no input!
|
|
|
|
|
|
|
|
//we use a SignalMapper to show/hide the corresponding browser when tabs are clicked
|
|
|
|
connect( tab, TQT_SIGNAL(clicked()), m_mapper, TQT_SLOT(map()) );
|
|
|
|
m_mapper->setMapping( TQT_TQOBJECT(tab), id );
|
|
|
|
connect( tab, TQT_SIGNAL(initiateDrag ( int ) ), this, TQT_SLOT( showBrowser( int )) );
|
|
|
|
|
|
|
|
m_browsers.push_back( widget );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::removeMediaBrowser( TQWidget *widget )
|
|
|
|
{
|
|
|
|
BrowserList::iterator it = tqFind( m_browsers.begin(), m_browsers.end(), widget );
|
|
|
|
if( it != m_browsers.end() )
|
|
|
|
m_browsers.erase( it );
|
|
|
|
TQWidget *tab;
|
|
|
|
tab = m_tabBar->tab( m_browserIds["MediaBrowser"] );
|
|
|
|
m_mapper->removeMappings( TQT_TQOBJECT(tab) );
|
|
|
|
m_tabBar->removeTab( m_browserIds["MediaBrowser"] );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::showHideBrowser( int index )
|
|
|
|
{
|
|
|
|
const int prevIndex = m_currentIndex;
|
|
|
|
|
|
|
|
if( m_currentIndex != -1 ) {
|
|
|
|
///first we need to hide the currentBrowser
|
|
|
|
|
|
|
|
m_currentIndex = -1; //to prevent race condition, see CVS history
|
|
|
|
|
|
|
|
m_browsers[prevIndex]->hide();
|
|
|
|
m_tabBar->setTab( prevIndex, false );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( index == prevIndex ) {
|
|
|
|
///close the BrowserBar
|
|
|
|
|
|
|
|
m_browserBox->hide();
|
|
|
|
m_divider->hide();
|
|
|
|
|
|
|
|
adjustWidgetSizes();
|
|
|
|
}
|
|
|
|
|
|
|
|
else if( (uint)index < m_browsers.count() ) {
|
|
|
|
///open up target
|
|
|
|
|
|
|
|
TQWidget* const target = m_browsers[index];
|
|
|
|
m_currentIndex = index;
|
|
|
|
|
|
|
|
m_divider->show();
|
|
|
|
target->show();
|
|
|
|
target->setFocus();
|
|
|
|
m_browserBox->show();
|
|
|
|
m_tabBar->setTab( index, true );
|
|
|
|
|
|
|
|
if( prevIndex == -1 ) {
|
|
|
|
// we need to show the browserBox
|
|
|
|
// m_pos dictates how everything will be sized in adjustWidgetSizes()
|
|
|
|
m_pos = m_browserBox->width() + m_tabBar->width();
|
|
|
|
adjustWidgetSizes();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
emit browserActivated( index );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::showHideVisibleBrowser( int index )
|
|
|
|
{
|
|
|
|
int realindex = -1;
|
|
|
|
TQPtrList<MultiTabBarTab> tabs = *m_tabBar->tabs();
|
|
|
|
for( int i = 0, n = tabs.count(); i < n; ++i )
|
|
|
|
{
|
|
|
|
if( tabs.at( i )->visible() )
|
|
|
|
index--;
|
|
|
|
if( index < 0 )
|
|
|
|
{
|
|
|
|
realindex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( realindex >= 0 )
|
|
|
|
showHideBrowser( realindex );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQWidget*
|
|
|
|
BrowserBar::browser( const TQString &name ) const
|
|
|
|
{
|
|
|
|
foreachType( BrowserList, m_browsers )
|
|
|
|
if( name == (*it)->name() )
|
|
|
|
return *it;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
BrowserBar::visibleCount() const
|
|
|
|
{
|
|
|
|
int num = 0;
|
|
|
|
TQPtrList<MultiTabBarTab> tabs = *m_tabBar->tabs();
|
|
|
|
for( int i = 0, n = tabs.count(); i < n; ++i )
|
|
|
|
{
|
|
|
|
if( tabs.at( i )->visible() )
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
BrowserBar::indexForName( const TQString &name ) const
|
|
|
|
{
|
|
|
|
for( uint x = 0; x < m_browsers.count(); ++x )
|
|
|
|
if( name == m_browsers[x]->name() )
|
|
|
|
return x;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::showBrowserSelectionMenu()
|
|
|
|
{
|
|
|
|
m_tabBar->showTabSelectionMenu(mapToGlobal(TQPoint(m_tabManagementButton->pos().x(), m_tabManagementButton->pos().y() +m_tabManagementButton->height() )));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BrowserBar::engineStateChanged( Engine::State state, Engine::State oldState )
|
|
|
|
{
|
|
|
|
if( !AmarokConfig::autoShowContextBrowser() || m_currentIndex == -1 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch( state ) {
|
|
|
|
case Engine::Playing:
|
|
|
|
|
|
|
|
if( oldState != Engine::Paused && m_currentIndex != -1 ) {
|
|
|
|
m_lastIndex = m_currentIndex;
|
|
|
|
showBrowser( "ContextBrowser" );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Engine::Empty:
|
|
|
|
|
|
|
|
if( m_lastIndex >= 0 )
|
|
|
|
showBrowser( m_lastIndex );
|
|
|
|
|
|
|
|
default:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "browserbar.moc"
|