Commit 0f995e47192a30e30134e0e46b5454d1be3b2e20

  • avatar
  • nobody <nobody @loca…ost.>
  • Mon Jun 28 06:45:00 CEST 2004
This commit was manufactured by cvs2svn to create tag 'amarok_1_0_1'.

svn path=/tags/amarok_1_0_1/kdeextragear-1/amarok/; revision=324184
ChangeLog
(2 / 6)
  
33(c) 2002-2004 the amaroK authors.
44
55
6VERSION 1.1:
7 FIX: GStreamer engine must not allow non-audio filetypes in playlist.
8 ADD: Icon for "Menu" button in toolbar. Improves Usability.
9
106VERSION 1.0.1:
117 FIX: Short dropouts after starting a stream with GStreamer.
128 FIX: amaroK starting invisible when systray icon is disabled.
13 FIX: Playlist analyzer looks freaky on some systems (BR 83671).
14 FIX: Display filename in title column for wav files (BR 83650).
9 FIX: Playlist analyzer looks freaky on some systems. (BR 83671)
10 FIX: Display filename in title column for wav files. (BR 83650)
1511 FIX: Don't show crash dialog when no engine plugins are found.
1612 FIX: Compile issue for KDE < 3.2.1 users. Sorry :(
1713
README
(2 / 2)
  
9292 "Run with highest possible priority", and increase the size of the sound
9393 buffer (warning, see the next FAQ!) You should also enusre that your
9494 artswrapper is suid:
95
95
9696 $ su
9797 $ chmod a+rsx /path/to/kde/bin/artswrapper
98
98
9999 Finally you will benefit from installing kdemultimedia in its entirety to get
100100 the faster aRts codecs (eg. libarts_mpeglib.so, etc.)
101101
amarok.lsm
(1 / 1)
  
11Begin3
22Title: amarok
3Version: 1.1
3Version: 1.0.1
44Entered-date:
55Description: Audio player for KDE
66Keywords: player multimedia kde mp3 ogg audio music arts
  
11// Maintainer: Max Howell <max.howell@methylblue.com>, (C) 2004
22// Copyright: See COPYING file that comes with this distribution
33
4#ifdef HAVE_CONFIG_H
5 #include <config.h> //HAVE_XMMS definition
6#endif
7
48#include "actionclasses.h"
59#include "amarokconfig.h"
610#include "app.h" //actionCollection() and a SLOT
7#include "config.h" //HAVE_XMMS definition
811#include "enginecontroller.h"
912#include "playlistwindow.h" //need amaroK::ToolBar
10#include "scriptmanager.h"
11#include "socketserver.h" //Vis::Selector::showInstance(
13#include "socketserver.h" //Vis::Selector::showInstance()
1214
1315#include <kaction.h>
1416#include <khelpmenu.h>
6969 button->setPopup( amaroK::Menu::instance() );
7070 button->setName( "toolbutton_amarok_menu" );
7171 button->setIcon( "configure" );
72
72
7373 return containerCount() - 1;
7474 }
7575 else return -1;
9090 insertItem( i18n( "&Visualizations..." ), ID_SHOW_VIS_SELECTOR );
9191
9292 insertSeparator();
93
94 insertItem( i18n( "&Scripts..." ), ID_SHOW_SCRIPT_SELECTOR );
95 insertItem( i18n( "&JavaScript Console" ), ID_SHOW_SCRIPT_CONSOLE );
96
97 #ifndef HAVE_KJSEMBED
98 setItemEnabled( ID_SHOW_SCRIPT_SELECTOR, false );
99 setItemEnabled( ID_SHOW_SCRIPT_CONSOLE, false );
100 #endif
101
102 insertSeparator();
103
93
10494 insertItem( i18n( "Configure &Effects..." ), pApp, SLOT( slotConfigEffects() ) );
10595 insertItem( i18n( "Configure &Decoder..." ), ID_CONF_DECODER );
10696
152152 case ID_SHOW_VIS_SELECTOR:
153153 Vis::Selector::instance()->show(); //doing it here means we delay creation of the widget
154154 break;
155 #ifdef HAVE_KJSEMBED
156 case ID_SHOW_SCRIPT_SELECTOR:
157 ScriptManager::Manager::instance()->showSelector();
158 break;
159 case ID_SHOW_SCRIPT_CONSOLE:
160 ScriptManager::Manager::instance()->showConsole();
161 break;
162 #endif
163155 }
164156}
165157
265265 m_slider->setFixedHeight( 35 );
266266 m_slider->setMaxValue( amaroK::VOLUME_MAX );
267267 m_slider->setValue( amaroK::VOLUME_MAX - AmarokConfig::masterVolume() );
268 QToolTip::add( m_slider, i18n( "Volume control" ) );
268 QToolTip::add( m_slider, i18n( "Volume Control" ) );
269269 connect( m_slider, SIGNAL(valueChanged( int )), SLOT(sliderMoved( int )) );
270270 connect( bar, SIGNAL(wheelMoved( int )), SLOT(wheelMoved( int )) );
271271
  
11INCLUDES = \
2 -I$(top_builddir)/amarok/src \
32 -I$(top_srcdir)/amarok/src \
43 -I$(top_srcdir)/amarok/src/engine \
54 -I$(top_srcdir)/amarok/src/plugin \
  
185185 <default>true</default>
186186 <whatsthis>Enable/Disable shoutcast metadata fetching. If set, amaroK displays metadata also for shoutcast streams.</whatsthis>
187187 </entry>
188 <entry key="Thread Priority" type="Int">
189 <label>Priority of GStreamer pipeline thread</label>
190 <default>2</default>
191 <min>0</min>
192 <max>3</max>
193 <whatsthis>The priority of the thread for GStreamer, a value between 0 (low) and 3 (high).</whatsthis>
194 </entry>
195188</group>
196189
197190<group name="OSD">
  
6767 m_rows = limit( uint(double(height()+1) / (HEIGHT+1)), MAX_ROWS, MIN_ROWS );
6868
6969 const uint PRE = 1, PRO = 1; //PRE and PRO allow us to restrict the range somewhat
70 for( uint z = 0; z < m_rows; ++z )
70 for( uint z = 0; z < m_rows; ++z )\
7171 {
7272 lvlMapper[z] = 1-(log10(PRE+z) / log10(PRE+m_rows+PRO));
7373 }
src/app.cpp
(60 / 27)
  
1818#include "amarokconfig.h"
1919#include "amarokdcophandler.h"
2020#include "app.h"
21#include "config.h"
2221#include "configdialog.h"
2322#include "effectwidget.h"
2423#include "enginebase.h"
2929#include "playlistwindow.h"
3030#include "plugin.h"
3131#include "pluginmanager.h"
32#include "scriptmanager.h"
3332#include "socketserver.h"
3433#include "systray.h"
3534#include "tracktooltip.h" //engineNewMetaData()
6767 m_pTray = new amaroK::TrayIcon( m_pPlaylistWindow );
6868 (void) new Vis::SocketServer( this );
6969
70 #ifdef HAVE_KJSEMBED
71 (void) new ScriptManager::Manager( this );
72 // Export symbols to KJSEmbed
73 ScriptManager::Manager::instance()->addObject( this );
74 ScriptManager::Manager::instance()->addObject( m_pDcopHandler );
75 #endif
76
7770 m_pPlaylistWindow->init(); //creates the playlist, browsers, etc.
7871 initGlobalShortcuts();
7972
201201}
202202
203203
204void App::initEngine()
205{
206 kdDebug() << "BEGIN " << k_funcinfo << endl;
207
208 const QString query = "[X-KDE-amaroK-plugintype] == 'engine' and Name == '%1'";
209 amaroK::Plugin* plugin = PluginManager::createFromQuery( query.arg( AmarokConfig::soundSystem() ) );
210
211 if ( !plugin )
212 {
213 kdWarning() << "Cannot load the: " << AmarokConfig::soundSystem() << " plugin. Trying another engine..\n";
214
215 //try to invoke _any_ engine plugin
216 plugin = PluginManager::createFromQuery( "[X-KDE-amaroK-plugintype] == 'engine'" );
217
218 if ( !plugin )
219 {
220 KMessageBox::error( m_pPlaylistWindow, i18n(
221 "<p>amaroK could not find any sound-engine plugins. "
222 "It is likely that amaroK is installed under the wrong prefix, please fix your installation using:"
223 "<pre>cd /path/to/amarok/source-code/<br>"
224 "su -c \"make uninstall\"<br>"
225 "./configure --prefix=`kde-config --prefix` && su -c \"make install\"</pre>"
226 "More information can be found in the README file. For further assistance join us at #amarok on irc.freenode.net." ) );
227
228 ::exit( EXIT_SUCCESS );
229 }
230
231 AmarokConfig::setSoundSystem( PluginManager::getService( plugin )->name() );
232 kdDebug() << "Setting soundSystem to: " << AmarokConfig::soundSystem() << endl;
233 }
234
235 // feed engine to controller
236 EngineBase* const engine = (EngineBase*)plugin;
237 bool restartArts = AmarokConfig::version() != APP_VERSION;
238
239 engine->init( restartArts, amaroK::SCOPE_SIZE, AmarokConfig::rememberEffects() );
240 EngineController::setEngine( engine ); //will set engine's volume
241
242 //NOTE applySettings() must be called now to ensure mixer settings are set
243
244 kdDebug() << "END " << k_funcinfo << endl;
245}
246
247
204248#include <kaction.h>
205249#include <kshortcutlist.h>
206250void App::initGlobalShortcuts()
260260 ec, SLOT( playPause() ), true, true );
261261 m_pGlobalAccel->insert( "stop", i18n( "Stop" ), 0, KKey("WIN+v"), 0,
262262 ec, SLOT( stop() ), true, true );
263 m_pGlobalAccel->insert( "next", i18n( "Next Track" ), 0, KKey("WIN+b"), 0,
263 m_pGlobalAccel->insert( "next", i18n( "Next track" ), 0, KKey("WIN+b"), 0,
264264 ec, SLOT( next() ), true, true );
265 m_pGlobalAccel->insert( "prev", i18n( "Previous Track" ), 0, KKey("WIN+z"), 0,
265 m_pGlobalAccel->insert( "prev", i18n( "Previous track" ), 0, KKey("WIN+z"), 0,
266266 ec, SLOT( previous() ), true, true );
267 m_pGlobalAccel->insert( "volup", i18n( "Increase Volume" ), 0, KKey("WIN+KP_Add"), 0,
267 m_pGlobalAccel->insert( "volup", i18n( "Increase volume" ), 0, KKey("WIN+KP_Add"), 0,
268268 ec, SLOT( increaseVolume() ), true, true );
269 m_pGlobalAccel->insert( "voldn", i18n( "Decrease Volume" ), 0, KKey("WIN+KP_Subtract"), 0,
269 m_pGlobalAccel->insert( "voldn", i18n( "Decrease volume" ), 0, KKey("WIN+KP_Subtract"), 0,
270270 ec, SLOT( decreaseVolume() ), true, true );
271 m_pGlobalAccel->insert( "playlist_add", i18n( "Add Media" ), 0, KKey("WIN+a"), 0,
271 m_pGlobalAccel->insert( "playlist_add", i18n( "Add media" ), 0, KKey("WIN+a"), 0,
272272 m_pPlaylistWindow, SLOT( slotAddLocation() ), true, true );
273 m_pGlobalAccel->insert( "show", i18n( "Toggle Playlist Window" ), 0, KKey("WIN+p"), 0,
273 m_pGlobalAccel->insert( "show", i18n( "Toggle the Playlist Window" ), 0, KKey("WIN+p"), 0,
274274 m_pPlaylistWindow, SLOT( showHide() ), true, true );
275 m_pGlobalAccel->insert( "osd", i18n( "Show OSD" ), 0, KKey("WIN+o"), 0,
275 m_pGlobalAccel->insert( "osd", i18n( "Show the OSD" ), 0, KKey("WIN+o"), 0,
276276 m_pOSD, SLOT( forceShowTrack() ), true, true );
277277
278278 m_pGlobalAccel->setConfigGroup( "Shortcuts" );
396396 setupColors();
397397
398398
399 //on startup we need to show the window, but only if it wasn't hidden on exit
400 //and always if the trayicon isn't showing
401 if( firstTime && (!amaroK::config()->readBoolEntry( "HiddenOnExit", false ) || !AmarokConfig::showTrayIcon()) )
399 if( firstTime && !amaroK::config()->readBoolEntry( "HiddenOnExit", false ) )
402400 {
403401 mainWindow()->show();
404402
404404 kapp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
405405 }
406406
407
407
408408 { //<Engine>
409 //TODO move loading of engine and initEngine() to engineController; it can handle things better
410
409411 EngineBase *engine = EngineController::engine();
410412 const bool b = QCString( engine->name() ) == "Dummy";
411413
412414 if( b || AmarokConfig::soundSystem() != PluginManager::getService( engine )->name() )
413415 {
414416 if( !b ) PluginManager::unload( engine );
415 EngineController::instance()->loadEngine();
417
418 initEngine();
416419 engine = EngineController::engine();
417 // Invalidate extension cache
418 Playlist::s_extensionCache.clear();
419420
420421 AmarokConfig::setHardwareMixer( engine->initMixer( AmarokConfig::hardwareMixer() ) );
421422 }
428428 engine->setDefaultSoundDevice( !AmarokConfig::customSoundDevice() );
429429 engine->setRestoreEffects( AmarokConfig::rememberEffects() );
430430 engine->setVolume( AmarokConfig::masterVolume() );
431 engine->setThreadPriority( AmarokConfig::threadPriority() );
432431 //TODO deprecate/improve
433432 engine->setXfadeLength( AmarokConfig::crossfade() ? AmarokConfig::crossfadeLength() : 0 );
434433 } //</Engine>
553553 //FIXME this isn't a good way to determine if there is a currentTrack, need playlist() function
554554 const bool b = EngineController::engine()->loaded();
555555
556 popup.insertItem( i18n( "&Append to Playlist" ), 101 );
557 popup.insertItem( i18n( "Append && &play" ), 102 );
558 if( b ) popup.insertItem( i18n( "&Queue After Current Track" ), 103 );
556 popup.insertItem( i18n( "&Append to playlist" ), 101 );
557 popup.insertItem( i18n( "Append and &play" ), 102 );
558 if( b ) popup.insertItem( i18n( "&Queue after current track" ), 103 );
559559 popup.insertSeparator();
560560 popup.insertItem( i18n( "&Cancel" ), 0 );
561561
  
1717
1818#include "enginebase.h"
1919#include "gstengine.h"
20#include "gstuade.h"
2120#include "streamsrc.h"
2221
2322#include <math.h> //interpolate()
5050GstEngine::error_msg;
5151
5252GstEngine*
53GstEngine::s_instance;
53GstEngine::self;
5454
5555
5656void
6060
6161 //this is the Qt equivalent to an idle function: delay the call until all events are finished,
6262 //otherwise gst will crash horribly
63 QTimer::singleShot( 0, instance(), SLOT( stopAtEnd() ) );
63 QTimer::singleShot( 0, self, SLOT( stopAtEnd() ) );
6464}
6565
6666
6868GstEngine::handoff_cb( GstElement*, GstBuffer* buf, gpointer )
6969{
7070 int channels = 2; //2 == default, if we cannot determine the value from gst
71 GstCaps* caps = gst_pad_get_caps( gst_element_get_pad( instance()->m_spider, "src_0" ) );
71 GstCaps* caps = gst_pad_get_caps( gst_element_get_pad( self->m_spider, "src_0" ) );
7272
7373 for ( int i = 0; i < gst_caps_get_size( caps ); i++ ) {
7474 GstStructure* structure = gst_caps_get_structure( caps, i );
8787
8888 //divide length by 2 for casting from 8bit to 16bit, and divide by number of channels
8989 for ( ulong i = 0; i < GST_BUFFER_SIZE( buf ) / 2 / channels; i += channels ) {
90 if ( instance()->m_scopeBufIndex == instance()->m_scopeBuf.size() ) {
91 instance()->m_scopeBufIndex = 0;
90 if ( self->m_scopeBufIndex == self->m_scopeBuf.size() ) {
91 self->m_scopeBufIndex = 0;
9292 // kdDebug() << k_funcinfo << "m_scopeBuf overflow!\n";
9393 }
9494
9898 //convert uint-16 to float and write into buf
9999 temp += ( float ) ( data[ i + j ] - 32768 ) / 32768.0;
100100 }
101 instance()->m_scopeBuf[ instance()->m_scopeBufIndex++ ] = temp;
101 self->m_scopeBuf[ self->m_scopeBufIndex++ ] = temp;
102102 }
103103 }
104104}
105105
106106
107107void
108GstEngine::typefindFound_cb( GstElement* /*typefind*/, GstCaps* /*caps*/, GstElement* /*pipeline*/ )
109{
110// kdDebug() << "GstEngine::typefindFound" << endl;
111
112 self->m_typefindResult = true;
113}
114
115// const GList *elements = gst_registry_pool_feature_list( GST_TYPE_ELEMENT_FACTORY );
116//
117// while ( elements != NULL )
118// {
119// factory = (GstElementFactory *) elements->data;
120// const gchar *klass = gst_element_factory_get_klass( factory );
121// elements = elements->next;
122// }
123
124
125void
108126GstEngine::error_cb( GstElement* /*element*/, GstElement* /*source*/, GError* error, gchar* /*debug*/, gpointer /*data*/ )
109127{
110128 kdDebug() << k_funcinfo << endl;
111129
112 QTimer::singleShot( 0, instance(), SLOT( handleError() ) );
130 QTimer::singleShot( 0, self, SLOT( handleError() ) );
113131}
114132
115133
167167{
168168 kdDebug() << "BEGIN " << k_funcinfo << endl;
169169
170 s_instance = this;
170 self = this;
171171 m_mixerHW = -1; //initialize
172172
173173 m_scopeBuf.resize( SCOPEBUF_SIZE );
194194bool
195195GstEngine::canDecode( const KURL &url, mode_t, mode_t )
196196{
197 bool success = false;
198 GstElement *pipeline, *filesrc, *spider, *audioconvert, *audioscale, *audiosink;
197 GstElement* pipeline;
198 GstElement* filesrc;
199 GstElement* typefind;
200 m_typefindResult = false;
199201
200202 /* create a new pipeline to hold the elements */
201203 pipeline = gst_pipeline_new( "pipeline" );
204
202205 /* create a disk reader */
203 if ( !( filesrc = gst_element_factory_make( "filesrc", "filesrc" ) ) ) goto error;
206 if ( !( filesrc = gst_element_factory_make( "filesrc", "disk_source" ) ) ) goto error;
204207 gst_bin_add ( GST_BIN ( pipeline ), filesrc );
205 if ( !( spider = gst_element_factory_make( "spider", "spider" ) ) ) goto error;
206 gst_bin_add ( GST_BIN ( pipeline ), spider );
207 if ( !( audioconvert = gst_element_factory_make( "audioconvert", "audioconvert" ) ) ) goto error;
208 gst_bin_add ( GST_BIN ( pipeline ), audioconvert );
209 if ( !( audioscale = gst_element_factory_make( "audioscale", "audioscale" ) ) ) goto error;
210 gst_bin_add ( GST_BIN ( pipeline ), audioscale );
211 if ( !( audiosink = gst_element_factory_make( m_soundOutput.latin1(), "audiosink" ) ) ) goto error;
212 gst_bin_add ( GST_BIN ( pipeline ), audiosink );
213
214 /* setting device property for AudioSink*/
215 if ( !m_defaultSoundDevice && !m_soundDevice.isEmpty() )
216 g_object_set( G_OBJECT ( audiosink ), "device", m_soundDevice.latin1(), NULL );
217
208
209 if ( !( typefind = gst_element_factory_make( "typefind", "typefind" ) ) ) goto error;
210 gst_bin_add ( GST_BIN ( pipeline ), typefind );
211
218212 g_object_set( G_OBJECT( filesrc ), "location", (const char*) QFile::encodeName( url.path() ), NULL );
213 gst_element_link_many( filesrc, typefind, NULL );
219214
220 gst_element_link_many( filesrc, spider, audioconvert, audioscale, audiosink, NULL );
215 g_signal_connect ( G_OBJECT( typefind ), "have-type", G_CALLBACK( typefindFound_cb ), pipeline );
221216 gst_element_set_state( pipeline, GST_STATE_PLAYING );
222217
223 // Try to iterate over the bin, if it works gst can decode our file
224 if ( gst_bin_iterate ( GST_BIN ( pipeline ) ) )
225 success = true;
226
218 // Iterate over the pipeline until operation is finished
219 while ( gst_bin_iterate ( GST_BIN ( pipeline ) ) );
220
227221 gst_element_set_state( pipeline, GST_STATE_NULL );
228222 gst_object_unref( GST_OBJECT( pipeline ) );
229223
230 return success;
224 return m_typefindResult;
231225
232226error:
233227 kdWarning() << "GStreamer element factory does not work. " << endl
301301
302302 /* create a new pipeline (thread) to hold the elements */
303303 m_thread = gst_thread_new ( "thread" );
304 g_object_set( G_OBJECT( m_thread ), "priority", m_threadPriority, NULL );
305
306 kdDebug() << "Thread scheduling priority: " << m_threadPriority << endl;
304 g_object_set( G_OBJECT( m_thread ), "priority", 2, NULL );
305
307306 kdDebug() << "Sound output method: " << m_soundOutput << endl;
308307
309308 if ( !( m_audiosink = createElement( m_soundOutput.latin1(), "play_audio" ) ) ) return;
325325 m_filesrc = GST_ELEMENT( gst_streamsrc_new( m_streamBuf, &m_streamBufIndex ) );
326326 gst_bin_add ( GST_BIN ( m_thread ), m_filesrc );
327327 }
328
329 //TODO HACK
330 if ( url.path().contains( "_uade" ) ) {
331 m_spider = GST_ELEMENT( gst_uade_new() );
332 g_object_set( G_OBJECT( m_spider ), "location", (const char*) ( QFile::encodeName( url.path() ) ), NULL );
333 }
334 else
335 if ( !( m_spider = createElement( "spider", "spider" ) ) ) return;
336
328
329 if ( !( m_spider = createElement( "spider", "spider" ) ) ) return;
337330 if ( !( m_identity = createElement( "identity", "rawscope" ) ) ) return;
338331 if ( !( m_volumeElement = createElement( "volume", "volume" ) ) ) return;
339332 if ( !( m_audioconvert = createElement( "audioconvert", "audioconvert" ) ) ) return;
429429{
430430 if ( m_streamBufIndex + size > STREAMBUF_SIZE ) {
431431 size = STREAMBUF_SIZE - m_streamBufIndex;
432 kdDebug() << "Stream buffer overflow!" << endl;
432 // kdDebug() << "Stream buffer overflow!" << endl;
433433 }
434434
435435 // Copy data into stream buffer
465465 /* stop the thread */
466466 gst_element_set_state ( m_thread, GST_STATE_READY );
467467
468 emit endOfTrack();
468 emit stopped();
469469}
470470
471471
  
126126 m_lineEdit = new KLineEdit( hbox );
127127
128128 hbox->setMargin( 4 );
129 button->setIconSet( SmallIconSet( QApplication::reverseLayout() ? "clear_left" : "locationbar_erase" ) );
129 button->setIconSet( SmallIconSet( "locationbar_erase.png" ) );
130130 m_lineEdit->setFrame( QFrame::Sunken );
131131 m_lineEdit->installEventFilter( this ); //we intercept keyEvents
132132
166166 m_browsers->addBrowser( new ContextBrowser( "ContextBrowser" ), i18n( "Context" ), "info" );
167167 m_browsers->addBrowser( new SearchBrowser( "SearchBrowser" ), i18n( "Search" ), "find" );
168168
169 #define PLAYLIST_BROWSER 1
170169 #ifdef PLAYLIST_BROWSER
171 m_browsers->addBrowser( new PlaylistBrowser( "PlaylistBrowser" ), i18n( "Playlist" ), "midi" );
170 m_browsers->addBrowser( m_playlist->browser(), i18n( "Playlist" ), "midi" );
172171 #endif
173172
174173 { //<StreamBrowser>
463463 const KWin::WindowInfo info = KWin::windowInfo( winId() );
464464 const uint desktop = KWin::currentDesktop();
465465 const bool isOnThisDesktop = info.isOnDesktop( desktop );
466
466467 #if KDE_IS_VERSION(3,2,1)
467468 const bool isShaded = info.hasState( NET::Shaded );
468469 #else
469470 const bool isShaded = false;
470471 #endif
471472
472
473473 if( isShaded )
474474 {
475475 KWin::clearState( winId(), NET::Shaded );
520520 pApp->applySettings();
521521
522522 amaroK::config()->writeEntry( "XMLFile", xml );
523}
524
525
526void amaroK::ToolBar::mousePressEvent( QMouseEvent *e )
527{
528 if( e->button() == RightButton ) amaroK::Menu::instance()->popup( e->globalPos() );
529523}
530524
531525#include "playlistwindow.moc"