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.
tdemultimedia/noatun/modules/kaiman/userinterface.cpp

563 lines
14 KiB

/*
Copyright (c) 2000 Stefan Schimanski <1Stein@gmx.de>
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, 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
aint with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <noatun/effects.h>
#include <noatun/app.h>
#include <noatun/player.h>
#include <noatun/pref.h>
#include "userinterface.h"
#include "pref.h"
#include <tqcursor.h>
#include <tqpixmap.h>
#include <tqbitmap.h>
#include <tqimage.h>
#include <tqdropsite.h>
#include <tqdragobject.h>
#include <tqtimer.h>
#include <kfiledialog.h>
#include <kdebug.h>
#include <kapplication.h>
#include <kwin.h>
#include <kglobal.h>
#include <klocale.h>
#include <kconfig.h>
#include <kpopupmenu.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>
#include <kio/netaccess.h>
#include <kurldrag.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <X11/X.h>
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
Kaiman* Kaiman::kaiman=0;
const char Kaiman::DEFAULT_SKIN[]="car-preset";
Kaiman::Kaiman()
: KMainWindow(0, "NoatunKaiman"), UserInterface()
{
NOATUNPLUGINC(Kaiman);
kaiman=this;
//setCaption( i18n("Kaiman") );
KWin::setType( this->winId(), NET::Override );
setBackgroundMode( NoBackground );
setAcceptDrops(true);
_style = 0;
_seeking = false;
_altSkin = false;
// init config
KConfig *config=KGlobal::config();
config->setGroup("Kaiman");
// load skin
TQString skinName = config->readEntry( "SkinResource", DEFAULT_SKIN );
if ( !changeStyle(skinName, "skindata") )
{
KMessageBox::sorry( this, i18n("Cannot load skin %1. Switching to default skin.").tqarg(skinName) );
if ( !changeStyle( DEFAULT_SKIN, "skindata" ) )
{
KMessageBox::error( this, i18n("Cannot load default skin %1.").tqarg(DEFAULT_SKIN) );
TQTimer::singleShot( 0, this, TQT_SLOT(close()) );
return;
}
}
// global connects
connect( napp, TQT_SIGNAL(hideYourself()), this, TQT_SLOT(hide()) );
connect( napp, TQT_SIGNAL(showYourself()), this, TQT_SLOT(show()) );
connect( napp->player(), TQT_SIGNAL(playing()), this, TQT_SLOT(updateMode()));
connect( napp->player(), TQT_SIGNAL(stopped()), this, TQT_SLOT(updateMode()));
connect( napp->player(), TQT_SIGNAL(paused()), this, TQT_SLOT(updateMode()));
connect( napp->player(), TQT_SIGNAL(timeout()), this, TQT_SLOT(timeout()));
connect( napp->player(), TQT_SIGNAL(loopTypeChange(int)), this, TQT_SLOT(loopTypeChange(int)));
connect( napp->player(), TQT_SIGNAL(newSongLen(int,int)), this, TQT_SLOT(newSongLen(int,int)));
connect( napp->player(), TQT_SIGNAL(newSong()), this, TQT_SLOT(newSong()));
if( napp->player()->isPlaying() )
newSong();
new KaimanPrefDlg(TQT_TQOBJECT(this));
show();
}
Kaiman::~Kaiman()
{
}
bool Kaiman::changeStyle( const TQString &style, const TQString &desc )
{
TQString ldesc = desc;
if ( ldesc.isEmpty() )
ldesc = _altSkin ? "alt_skindata" : "skindata";
bool vis = isVisible();
if ( vis )
hide();
bool ret = loadStyle( style, ldesc );
newSongLen(0,0);
timeout();
loopTypeChange(0);
updateMode();
if ( vis )
show();
return ret;
}
bool Kaiman::loadStyle( const TQString &style, const TQString &desc )
{
if ( _style ) delete _style;
_style = new KaimanStyle(this);
if ( !_style->loadStyle( style, desc ) )
{
delete _style;
_style = 0;
return false;
}
if ( _style->Mask() != 0 )
{
// Set the tqshaped window form
XShapeCombineMask( qt_xdisplay(), winId(), ShapeBounding, 0,0,
_style->Mask()->handle(), ShapeSet );
}
KaimanStyleElement* item = _style->find("Background");
setBackgroundMode(TQWidget::NoBackground);
if ( item!=0 )
{
_style->resize( item->width(), item->height());
resize( item->width(), item->height());
setFixedSize( item->width(), item->height());
}
item = _style->find("Playlist_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), napp->player(), TQT_SLOT(toggleListView()) );
item = _style->find("Play_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), napp->player(), TQT_SLOT(playpause()) );
item = _style->find("Pause_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), napp->player(), TQT_SLOT(playpause()) );
item = _style->find("Stop_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), napp->player(), TQT_SLOT(stop()) );
item = _style->find("Next_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), napp->player(), TQT_SLOT(forward()) );
item = _style->find("Prev_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), napp->player(), TQT_SLOT(back()) );
item = _style->find("Exit_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), this, TQT_SLOT(close()) );
item = _style->find("Mixer_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), this, TQT_SLOT(execMixer()) );
item = _style->find("Iconify_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), this, TQT_SLOT(showMinimized()) );
item = _style->find("Alt_Skin_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), this, TQT_SLOT(toggleSkin()) );
item = _style->find("Repeat_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), this, TQT_SLOT(toggleLoop()) );
item = _style->find("Shuffle_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), this, TQT_SLOT(toggleShuffle()) );
item = _style->find("Config_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), napp, TQT_SLOT(preferences()) );
item = _style->find("Volume_Up_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), this,TQT_SLOT(volumeUp()));
item = _style->find("Volume_Down_Button");
if( item!=0 ) connect( item, TQT_SIGNAL(clicked()), this,TQT_SLOT(volumeDown()));
KaimanStyleSlider* slider =
static_cast<KaimanStyleSlider*>(_style->find("Position_Slider"));
if( slider!=0 )
{
connect( slider, TQT_SIGNAL(newValueDrag(int)), this, TQT_SLOT(seekStart(int)) );
connect( slider, TQT_SIGNAL(newValue(int)), this, TQT_SLOT(seekDrag(int)) );
connect( slider, TQT_SIGNAL(newValueDrop(int)), this, TQT_SLOT(seekStop(int)) );
slider->setValue( 0, 0, 1000 );
}
slider = static_cast<KaimanStyleSlider*>(_style->find("Volume_Slider"));
if ( slider!=0 )
{
connect(slider, TQT_SIGNAL(newValue(int)), this, TQT_SLOT(setVolume(int)));
slider->setValue( napp->player()->volume(), 0, 100 );
}
KaimanStyleValue* volItem = static_cast<KaimanStyleValue*>(_style->find("Volume_Item"));
if ( volItem )
volItem->setValue( napp->player()->volume(), 0, 100 );
KaimanStyleText* titleItem = static_cast<KaimanStyleText*>(_style->find("Title"));
if ( titleItem )
titleItem->startAnimation( 300 );
return true;
}
void Kaiman::closeEvent(TQCloseEvent*)
{
unload();
}
void Kaiman::dragEnterEvent( TQDragEnterEvent *event )
{
event->accept( KURLDrag::canDecode(event) );
}
void Kaiman::dropEvent( TQDropEvent *event )
{
doDropEvent(event);
}
void Kaiman::doDropEvent(TQDropEvent *event)
{
KURL::List uri;
if (KURLDrag::decode(event, uri))
{
for (KURL::List::Iterator i = uri.begin(); i != uri.end(); ++i)
napp->player()->openFile(*i, false);
}
}
void Kaiman::seekStart( int )
{
_seeking = true;
}
void Kaiman::seekDrag( int value )
{
int length = napp->player()->getLength()/1000;
if ( length < 0)
length = 0;
if ( !_style ) return;
KaimanStyleValue* posItem =
static_cast<KaimanStyleValue*>(_style->find("Position_Item"));
if ( posItem )
posItem->setValue( value, 0, length );
KaimanStyleSlider* posSlider =
static_cast<KaimanStyleSlider*>(_style->find("Position_Slider"));
if ( posSlider )
posSlider->setValue( value, 0, length );
// update time
KaimanStyleNumber* numItem =
static_cast<KaimanStyleNumber*>(_style->find("Minute_Number"));
if ( numItem )
numItem->setValue( value/60%60 );
numItem = static_cast<KaimanStyleNumber*>(_style->find("Second_Number"));
if ( numItem )
numItem->setValue( value % 60 );
}
void Kaiman::seekStop( int value )
{
seek( value );
_seeking = false;
}
void Kaiman::seek( int value )
{
napp->player()->skipTo( value*1000 ); // skipTo() takes milliseconds
}
void Kaiman::toggleSkin()
{
_altSkin = !_altSkin;
TQString skinName = _style->skinName();
TQString oldDesc, newDesc;
if ( _altSkin )
{
oldDesc = TQString::tqfromLatin1("skindata");
newDesc = TQString::tqfromLatin1("alt_skindata");
}
else
{
newDesc = TQString::tqfromLatin1("skindata");
oldDesc = TQString::tqfromLatin1("alt_skindata");
}
if ( !changeStyle(skinName, newDesc) )
changeStyle(skinName, oldDesc);
}
void Kaiman::setVolume( int vol )
{
if ( vol<0 ) vol=0;
if ( vol>=100 ) vol=100;
napp->player()->setVolume( vol );
}
void Kaiman::volumeUp()
{
setVolume( napp->player()->volume()+10 );
}
void Kaiman::volumeDown()
{
setVolume( napp->player()->volume()-10 );
}
void Kaiman::execMixer()
{
kapp->startServiceByDesktopName ( TQString::tqfromLatin1("kmix"), TQString() );
}
void Kaiman::timeout()
{
if ( !_style ) return;
if (!napp->player()->current())
return;
// update volume
KaimanStyleSlider* l_elem_volslider = static_cast<KaimanStyleSlider*>(_style->find("Volume_Slider"));
KaimanStyleValue* l_elem_volitem = static_cast<KaimanStyleValue*>(_style->find("Volume_Item"));
if ( l_elem_volslider!=0 )
l_elem_volslider->setValue( napp->player()->volume(), 0, 100 );
if ( l_elem_volitem!=0 )
l_elem_volitem->setValue( napp->player()->volume(), 0, 100 );
// update position
if ( !_seeking )
{
int sec = napp->player()->getTime()/1000;
if ( sec < 0 )
sec = 0;
KaimanStyleValue* posItem =
static_cast<KaimanStyleValue*>(_style->find("Position_Item"));
if ( posItem ) posItem->setValue( sec, 0, napp->player()->getLength()/1000 );
KaimanStyleSlider* posSlider =
static_cast<KaimanStyleSlider*>(_style->find("Position_Slider"));
if ( posSlider ) posSlider->setValue( sec, 0, napp->player()->getLength()/1000 );
// update time
KaimanStyleNumber* numItem =
static_cast<KaimanStyleNumber*>(_style->find("Minute_Number"));
if ( numItem )
numItem->setValue( sec/60%60 );
numItem = static_cast<KaimanStyleNumber*>(_style->find("Second_Number"));
if ( numItem )
numItem->setValue( sec%60 );
}
const PlaylistItem &item = napp->playlist()->current();
KaimanStyleNumber* numItem = 0;
numItem = static_cast<KaimanStyleNumber*>(_style->find("In_Rate_Number"));
if ( numItem )
numItem->setValue(item.property("bitrate").toInt());
TQString hzString = item.property("samplerate");
hzString.truncate(2);
numItem = static_cast<KaimanStyleNumber*>(_style->find("In_Hz_Number"));
if ( numItem )
numItem->setValue(hzString.toInt());
}
void Kaiman::updateMode()
{
if ( !_style ) return;
KaimanStyleButton* pause =
static_cast<KaimanStyleButton*>(_style->find("Pause_Button"));
KaimanStyleButton* play =
static_cast<KaimanStyleButton*>(_style->find("Play_Button"));
KaimanStyleState* status =
static_cast<KaimanStyleState*>(_style->find("Status_Item"));
if (napp->player()->isStopped() )
{
if ( pause ) pause->setLit( false );
if ( play ) play->setLit( false );
if ( status ) status->setValue( 0 );
}
else if ( napp->player()->isPlaying() )
{
if ( pause ) pause->setLit( false );
if ( play ) play->setLit( true );
if ( status ) status->setValue( 2 );
}
else if ( napp->player()->isPaused() )
{
if ( pause ) pause->setLit( true );
if ( play ) play->setLit( false );
if ( status ) status->setValue( 1 );
}
}
void Kaiman::loopTypeChange( int )
{
if ( !_style ) return;
KaimanStyleState* rep = static_cast<KaimanStyleState*>(_style->find("Repeat_Item"));
if ( rep )
rep->setValue( napp->player()->loopStyle() );
}
void Kaiman::newSongLen( int, int )
{
if ( !_style )
return;
int len = napp->player()->getLength()/1000; // convert milliseconds -> seconds
if ( len < 0 ) // getLength returns -1 if there's no Playobject
len = 0;
// update time
KaimanStyleNumber* numItem =
static_cast<KaimanStyleNumber*>(_style->find("Minute_Total_Number"));
if ( numItem )
numItem->setValue( len/60%60 );
numItem = static_cast<KaimanStyleNumber*>(_style->find("Second_Total_Number"));
if ( numItem )
numItem->setValue( len%60 );
numItem = static_cast<KaimanStyleNumber*>(_style->find("Song_Minute_Number"));
if ( numItem )
numItem->setValue( len/60%60 );
numItem = static_cast<KaimanStyleNumber*>(_style->find("Second_Minute_Number"));
if ( numItem )
numItem->setValue( len%60 );
newSong();
}
void Kaiman::newSong()
{
if ( !_style ) return;
KaimanStyleText* titleItem = static_cast<KaimanStyleText*>(_style->find("Title"));
if ( titleItem )
{
TQString title = i18n("Noatun");
if ( napp->player()->current() )
{
title = napp->player()->current().title();
if ( title.isEmpty() )
title = napp->player()->current().file();
title = i18n("TITLE (LENGTH)", "%1 (%2)").tqarg(title,
napp->player()->current().lengthString());
}
titleItem->setValue( title );
}
}
#undef None
void Kaiman::toggleLoop()
{
KPopupMenu *loopMenu = new KPopupMenu(this, "loopMenu");
int selectedItem = 0;
loopMenu->setCheckable(true);
loopMenu->insertTitle(i18n("Loop Style"));
loopMenu->insertItem(i18n("&None"),
(int)Player::None);
loopMenu->insertItem(i18n("&Song"),
(int)Player::Song);
loopMenu->insertItem(i18n("&Playlist"),
(int)(Player::Playlist));
loopMenu->insertItem(i18n("&Random"),
(int)(Player::Random));
loopMenu->setItemChecked((int)napp->player()->loopStyle(), true); // select current loopstyle in menu
selectedItem = loopMenu->exec(TQCursor::pos());
if (selectedItem != -1)
napp->player()->loop(selectedItem); // set new loopstyle
delete loopMenu;
}
void Kaiman::toggleShuffle()
{
napp->player()->loop(Player::Random); // set loopstyle to be random
}
#include "userinterface.moc"