diff -Naur kaffeine-0.8.6-original/kaffeine/src/kaffeine.cpp kaffeine-0.8.6/kaffeine/src/kaffeine.cpp
--- kaffeine-0.8.6-original/kaffeine/src/kaffeine.cpp	2008-03-04 21:27:30.000000000 +0100
+++ kaffeine-0.8.6/kaffeine/src/kaffeine.cpp	2008-03-04 21:12:04.000000000 +0100
@@ -98,6 +98,584 @@
 #include <X11/extensions/XTest.h>
 #endif
 
+// yo6 beginning of modifications
+Yo6Button::Yo6Button( QWidget *parent, 
+		      const QString& iconName,
+		      const QString& labelName ) : QToolButton( parent ) {
+  KIconLoader *loader = KGlobal::iconLoader();
+  setIconSet( loader->loadIconSet( iconName, 
+				   KIcon::Panel, 
+				   KIcon::SizeMedium ) );
+  setTextLabel( labelName );
+  setTextPosition( QToolButton::BelowIcon );
+  setUsesBigPixmap( true );
+  setUsesTextLabel( true );
+}
+
+/* ************************************************************************* */
+Yo6CheckBox::Yo6CheckBox( QWidget *parent, DBWidget *dbWidget, 
+			  const QString& description, uint id_tag ) : 
+  QCheckBox( description, parent ) {
+  this->dbWidget = dbWidget;
+  this->id_tag = id_tag;
+}
+
+/* ************************************************************************* */
+void Yo6CheckBox::slotCheckBoxStateChanged( int state ) { 
+  /* Debug stuff */
+  const char *state_str;
+  switch ( state ) {
+  case QButton::Off:
+    state_str = "OFF";
+    break;
+  case QButton::NoChange:
+    state_str = "No change\n";
+    break;
+  case QButton::On:
+    state_str = "ON";
+    break;
+  default:
+    state_str = "unknown";
+  };
+  kdDebug() << "state    : " << state_str << endl
+	    << "tag ID   : " << id_tag << endl;
+
+  /* Get media ID */
+  if ( !dbWidget->isMediaExist() ) {
+    KMessageBox::information( 0, "You must choose a media before" );
+    return;
+  }
+  unsigned id_media = dbWidget->getMediaDbId();
+  kdDebug() << "media ID : " << id_media << endl;
+
+  /* Update tag */
+  QSqlQuery query( dbWidget->db );
+  switch ( state ) {
+  case QButton::Off:
+    query.prepare( "delete from media_tag "
+		   "where id_media = ? and id_tag = ?" );
+    break;
+  case QButton::On:
+    query.prepare( "insert ignore into media_tag values ( ?, ? )" );
+    break;
+  default:
+    return;
+  };
+  query.bindValue( 0, id_media );
+  query.bindValue( 1, id_tag );
+  if ( !query.exec() ) {
+    KMessageBox::sorry( 0, "SQL Error:" + query.lastError().text() );
+    return;
+  }
+}
+
+/* ************************************************************************* */
+ThumbsWidget::ThumbsWidget( QWidget *parent, 
+			    DBWidget *dbWidget, Kaffeine *kaffeine ) : 
+  QVBox( parent ), dbWidget( dbWidget ), kaffeine( kaffeine ) {
+  QHBox *hbox = new QHBox( this );
+  
+  QPushButton *button_add = new QPushButton( "add", hbox );
+  QPushButton *button_del = new QPushButton( "delete", hbox );
+  
+  listBox = new QListBox( this );
+  
+  QObject::connect( button_add, SIGNAL(clicked()), this, SLOT(add_thumbs()));
+  QObject::connect( button_del, SIGNAL(clicked()), this, SLOT(del_thumbs()));
+
+  /* Refresh listBox */
+  refresh_from_db();
+}
+
+/* *********************************************************************** */
+void ThumbsWidget::add_thumbs( void ) {
+  if ( !dbWidget->isMediaExist() ) {
+    KMessageBox::information( 0, "You must choose a media before" );
+    return;
+  }
+  KaffeinePart *p = kaffeine->m_mediaPart;
+  if ( !listBox || !p || !p->isPlaying() )
+    return;
+
+  /* Do a screen capture */
+  QPixmap thumbnail =  
+    QPixmap( p->yo6ScreenShot().smoothScale( 160, 120, 
+					     QImage::ScaleMin ) );
+  QByteArray ba;
+  QBuffer buffer( ba );
+  buffer.open( IO_WriteOnly );
+  if ( !thumbnail.save( &buffer, "PNG" ) ) {
+    KMessageBox::information( 0, "Cannot serialize pixmap" );
+    return;
+  }
+
+  /* Do a time capture */
+  QString timetext = 
+    QTime().addSecs( p->position() ).toString( "hh:mm:ss" );
+  
+  /* Save these precious informations to database */
+  QSqlQuery query( dbWidget->db );
+  query.prepare( "replace into media_thumbnail values ( ?, ?, ? )" );
+  query.bindValue( 0, dbWidget->getMediaDbId() );
+  query.bindValue( 1, timetext );
+  query.bindValue( 2, ba );
+  if ( !query.exec() ) {
+    KMessageBox::sorry( 0, "SQL Error:" + query.lastError().text() );
+    return;
+  }
+
+  /* Refresh listBox */
+  refresh_from_db();
+}
+
+/* ************************************************************************* */
+void ThumbsWidget::del_thumbs( void ) {
+  if ( !dbWidget->isMediaExist() ) {
+    KMessageBox::information( 0, "You must choose a media before" );
+    return;
+  }
+  if ( !listBox )
+    return;
+
+  /* Pick selected item if any */
+  QListBoxItem *item = listBox->selectedItem();
+  if ( item ) {
+    /* Remove it from database */
+    QSqlQuery query( dbWidget->db );
+    query.prepare( "delete from media_thumbnail "
+		   "where id_media = ? and stream_position = ?" );
+    query.bindValue( 0, dbWidget->getMediaDbId() );
+    query.bindValue( 1, item->text() );
+    if ( !query.exec() ) {
+      KMessageBox::sorry( 0, "SQL Error:" + query.lastError().text() );
+      return;
+    }
+
+    /* Refresh listBox */
+    refresh_from_db();
+  }
+}
+
+/* ************************************************************************* */
+void ThumbsWidget::refresh_from_db( void ) {
+  unsigned id_media;
+
+  listBox->clear();
+  if ( !dbWidget->isMediaExist() || !listBox || 
+       ((id_media = dbWidget->getMediaDbIdNoInsert()) == 0) )
+    return;
+
+  QSqlQuery query( dbWidget->db );
+  query.prepare( "select stream_position, thumbnail "
+		 "from media_thumbnail where id_media = ?" );
+  query.bindValue( 0, id_media );
+  if ( !query.exec() ) {
+    kdDebug() << "SQL Error:" << query.lastError().text() << endl;
+    return;
+  }
+  while ( query.next() ) {
+    QString stream_position = query.value( 0 ).toString();
+    QByteArray ba = query.value( 1 ).toByteArray();
+    QPixmap thumbnail;
+    thumbnail.loadFromData( ba );
+    listBox->insertItem( thumbnail, stream_position );
+  }
+}
+
+/* ************************************************************************* */
+Yo6TextEdit::Yo6TextEdit( QWidget *parent, DBWidget *dbWidget ) : 
+  QTextEdit( parent ) {
+  this->dbWidget = dbWidget;
+  QObject::connect( this, SIGNAL(textChanged()), 
+		    this, SLOT(slotTextEditTextChanged()));
+  refresh_from_db();
+}
+
+/* ************************************************************************* */
+void Yo6TextEdit::refresh_from_db( void ) {
+  QObject::disconnect( this, SIGNAL(textChanged()), 
+		       this, SLOT(slotTextEditTextChanged()));
+
+  /* Clear text area */
+  selectAll();
+  del();
+
+  /* Grab description */
+  unsigned id_media = 0;
+  if ( dbWidget->isMediaExist() &&
+       ((id_media = dbWidget->getMediaDbIdNoInsert()) > 0) ) {
+    QSqlQuery query( dbWidget->db );
+    query.prepare( "select description "
+		   "from media_description where id_media = ?" );
+    query.bindValue( 0, id_media );
+    if ( query.exec() ) {
+      if ( query.next() ) {
+	setText( query.value( 0 ).toString() );
+	moveCursor( QTextEdit::MoveEnd, false );
+      }
+    } else
+      KMessageBox::sorry( 0, "SQL Error:" + query.lastError().text() );
+  }
+
+  QObject::connect( this, SIGNAL(textChanged()), 
+		    this, SLOT(slotTextEditTextChanged()));
+}
+
+/* ************************************************************************* */
+void Yo6TextEdit::slotTextEditTextChanged() {
+  if ( !dbWidget->isMediaExist() ) {
+    KMessageBox::information( 0, "You must choose a media before" );
+    return;
+  }
+
+  /* Update description */
+  QSqlQuery query( dbWidget->db );
+  query.prepare( "replace into media_description values ( ?, ? )" );
+  query.bindValue( 0, dbWidget->getMediaDbId() );
+  query.bindValue( 1, text() );
+  if ( !query.exec() ) {
+    KMessageBox::sorry( 0, "SQL Error:" + query.lastError().text() );
+    return;
+  }
+}
+
+
+/* ************************************************************************* */
+TagsWidget::TagsWidget( QWidget *parent, DBWidget *dbWidget ) : 
+  QWidget( parent ) {
+  this->dbWidget = dbWidget;
+  QSqlDatabase *db = dbWidget->db;
+  QVBoxLayout *vbox = new QVBoxLayout( this );
+
+  /* Grab nbCheckBoxes */
+  QSqlQuery query_nbCheckBoxes( db );
+  if ( !query_nbCheckBoxes.exec( "select count( * ) from tag" ) ) {
+    kdDebug() << "SQL Error:" << query_nbCheckBoxes.lastError().text() << endl;
+    return;
+  }
+  if ( !query_nbCheckBoxes.next() )
+    return;
+  nbCheckBoxes = query_nbCheckBoxes.value( 0 ).toUInt();
+  checkBox = new Yo6CheckBox*[ nbCheckBoxes ];
+  memset( checkBox, 0, nbCheckBoxes * sizeof( Yo6CheckBox* ) );
+
+  /* Grab tags from database */
+  QSqlQuery query( db );
+  if ( !query.exec( "select id, description from tag order by description") ) {
+    kdDebug() << "SQL Error:" << query.lastError().text() << endl;
+    return;
+  }
+  uint slot = 0;
+  nbCheckBoxesInv = 0;
+  while ( query.next() ) {
+    uint id_tag = query.value( 0 ).toUInt();
+    QString description = query.value( 1 ).toString();
+    checkBox[ slot ] = new Yo6CheckBox( this, dbWidget, description, id_tag );
+    if ( nbCheckBoxesInv < (id_tag + 1))
+      nbCheckBoxesInv = id_tag + 1;
+    vbox->addWidget( checkBox[ slot ] );
+    connect( checkBox[ slot ], SIGNAL(stateChanged(int)), 
+	     checkBox[ slot ], SLOT(slotCheckBoxStateChanged(int)));
+    slot++;
+  }
+
+  /* Compute checkBox_inv */
+  if ( nbCheckBoxesInv ) {
+    uint i;
+    checkBoxInv = new Yo6CheckBox*[ nbCheckBoxesInv ];
+    memset( checkBoxInv, 0, nbCheckBoxesInv * sizeof( Yo6CheckBox* ) );
+    for ( i = 0; i < nbCheckBoxes; i++ )
+      checkBoxInv[ checkBox[ i ]->id_tag ] = checkBox[ i ];
+  } else
+    checkBoxInv = 0L;
+
+  /* Add flowers */
+  vbox->addStretch( 1 );
+
+  refresh_from_db();
+}
+
+/* ************************************************************************* */
+TagsWidget::~TagsWidget() {
+  delete [] checkBox;
+}
+
+/* ************************************************************************* */
+void TagsWidget::refresh_from_db( void ) {
+  uint i;
+
+  /* Clear and disconnect checkboxes */
+  for ( i = 0; i < nbCheckBoxes; i++ ) {
+    disconnect( checkBox[ i ], SIGNAL(stateChanged(int)), 
+		checkBox[ i ], SLOT(slotCheckBoxStateChanged(int)));
+    checkBox[ i ]->setChecked( false );
+  }
+  
+  /* Grab description */
+  unsigned id_media = 0;
+  if ( dbWidget->isMediaExist() &&
+       ((id_media = dbWidget->getMediaDbIdNoInsert()) > 0) ) {
+    QSqlQuery query( dbWidget->db );
+    query.prepare( "select id_tag "
+		   "from media_tag where id_media = ?" );
+    query.bindValue( 0, id_media );
+    if ( query.exec() ) {
+      while ( query.next() ) {
+	uint id_tag = query.value( 0 ).toUInt();
+	if ( id_tag >= nbCheckBoxesInv || !checkBoxInv[ id_tag ] )
+	  KMessageBox::information( 0, "Media tag unknown : " + 
+				    QString::number( id_tag ) );
+	else
+	  checkBoxInv[ id_tag ]->setChecked( true );
+      }
+    } else
+      KMessageBox::sorry( 0, "SQL Error:" + query.lastError().text() );
+  }
+
+  /* Reconnect checkboxes */
+  for ( i = 0; i < nbCheckBoxes; i++ )
+    connect( checkBox[ i ], SIGNAL(stateChanged(int)), 
+	     checkBox[ i ], SLOT(slotCheckBoxStateChanged(int)));
+}
+
+/* ************************************************************************* */
+QLineEdit *DBConfWidget::createEntry( QWidget *parent, 
+				      QGridLayout *gridLayout,
+				      int row, int col,
+				      const QString& name,
+				      const QString& contents ) {
+  QLabel *label = new QLabel( name, parent );
+  QLineEdit *lineEdit = new QLineEdit( contents, parent );
+  gridLayout->addWidget( label, row, col );
+  gridLayout->addWidget( lineEdit, row, col + 1 );
+  return lineEdit;
+}
+
+/* ************************************************************************* */
+DBConfWidget::DBConfWidget( QWidget *parent ) : QWidget( parent ) {
+  int row = 0;
+  QGridLayout *gridLayout = new QGridLayout( this );
+  QHBoxLayout *hboxLayout = new QHBoxLayout( this );
+  hostname = createEntry( this, gridLayout, row++, 0, "Host name", "" );
+  portnumber = createEntry( this, gridLayout, row++, 0, "Port number", "" );
+  username = createEntry( this, gridLayout, row++, 0, "Username", "" );
+  password = createEntry( this, gridLayout, row++, 0, "Password", "" );
+  database = createEntry( this, gridLayout, row++, 0, "Database", "" );
+  password->setEchoMode( QLineEdit::Password );
+  portnumber->setMaxLength( 5 );
+  portnumber->setValidator( new QIntValidator( 0, 0xFFFF, this ) );
+  
+  button_disconnect = new Yo6Button( this, "connect_established", 
+				     "Disconnect" );
+  button_connect = new Yo6Button( this, "connect_no", 
+				  "Connect" );
+
+  gridLayout->addMultiCellLayout( hboxLayout, row, row, 0, 1 );
+  row++;
+
+  hboxLayout->addWidget( button_connect );
+  hboxLayout->addWidget( button_disconnect );
+
+  gridLayout->setRowStretch( row++, 1 );
+  gridLayout->setSpacing( 2 );
+  gridLayout->setMargin( 2 );
+
+  setEnableWidgets( true );
+}
+
+/* ************************************************************************* */
+void DBConfWidget::setEnableWidgets( bool enabled ) {
+  hostname->setEnabled( enabled );
+  portnumber->setEnabled( enabled );
+  username->setEnabled( enabled );
+  password->setEnabled( enabled );
+  database->setEnabled( enabled );
+  button_connect->setEnabled( enabled );
+  button_disconnect->setEnabled( !enabled );
+}
+
+/* ************************************************************************* */
+QSqlDatabase *DBConfWidget::getdb( void ) const {
+  QSqlDatabase *db = QSqlDatabase::addDatabase( "QMYSQL3" );
+  if ( !db )
+    return db;
+  db->setHostName( hostname->text() );
+  db->setPort( portnumber->text().toInt() );
+  db->setUserName( username->text() );
+  db->setPassword( password->text() );
+  db->setDatabaseName( database->text() );
+  if ( !db->open() ) {
+    kdDebug() << "database error:" << db->lastError().text() << endl;
+    QSqlDatabase::removeDatabase( db );
+    db = 0L;
+  }
+  return db;
+}
+
+/* ************************************************************************* */
+void DBConfWidget::releasedb( QSqlDatabase *db ) {
+  if ( db ) {
+    db->close();
+    QSqlDatabase::removeDatabase( db );
+  }
+}
+
+/* ************************************************************************* */
+DBWidget::DBWidget( QWidget *parent, Kaffeine *kaffeine ) : QWidget( parent ) {
+  this->kaffeine = kaffeine;
+  db = 0L;
+  QVBoxLayout *vboxLayout = new QVBoxLayout( this );
+  
+  /* Media URL Placeholder */
+  lineEdit = new QLineEdit( "", this );
+  lineEdit->setReadOnly( true );
+  lineEdit->setAlignment( Qt::AlignHCenter );
+  vboxLayout->addWidget( lineEdit );
+
+  /* Create tab widget */
+  tabWidget = new QTabWidget( this );
+  vboxLayout->addWidget( tabWidget );
+
+  /* Create conf widget */
+  dbConfWidget = new DBConfWidget( tabWidget );
+  tabWidget->addTab( dbConfWidget, "database connection" );
+
+  QObject::connect( dbConfWidget->button_connect, SIGNAL(clicked()), 
+		    this, SLOT(databaseConnect(void)));
+  QObject::connect( dbConfWidget->button_disconnect, SIGNAL(clicked()), 
+		    this, SLOT(databaseDisconnect(void)));
+}
+
+/* ************************************************************************* */
+void DBWidget::setMediaUrl( const QString& url ) {
+  const char *file_protocol = "file://";
+  QString normalized_url;
+
+  /* Normalize URL*/
+  normalized_url = 
+    url.startsWith( file_protocol ) ? url : (file_protocol + url);
+  
+  /* Put it on URL Widget */
+  lineEdit->setText( normalized_url );
+
+  /* Get database information */
+  refresh_from_db();
+}
+
+/* ************************************************************************* */
+QString DBWidget::getMediaUrl( void ) {
+  return lineEdit->text();
+}
+
+/* ************************************************************************* */
+bool DBWidget::isMediaExist( void ) {
+  return !lineEdit->text().isEmpty();
+}
+
+/* ************************************************************************* */
+unsigned DBWidget::getMediaDbId( void ) {
+  /* Robustness */
+  if ( !isMediaExist() ) {
+    KMessageBox::sorry( 0, "Internal error: Invalid call to getMediaDbId" );
+    return 0;
+  }
+  QString mediaUrl = getMediaUrl();
+
+  /* Insert media into database */
+  QSqlQuery query( db );
+  query.prepare( "insert ignore into media ( url ) values( ? )" );
+  query.bindValue( 0, mediaUrl );
+  if ( !query.exec() ) {
+    KMessageBox::sorry( 0, "SQL Error:" + query.lastError().text() );
+    return 0;
+  }
+
+  /* Get media ID from db */
+  unsigned id_media = getMediaDbIdNoInsert();
+  if ( id_media == 0 ) {
+    KMessageBox::sorry( 0, "Database Error: cannot retreive ID of media " +
+			mediaUrl );
+    return 0;
+  }
+  return id_media;
+}
+
+/* ************************************************************************* */
+unsigned DBWidget::getMediaDbIdNoInsert( void ) {
+  /* Robustness */
+  if ( !isMediaExist() ) {
+    KMessageBox::sorry( 0, "Internal error: Invalid call to getMediaDbId" );
+    return 0;
+  }
+  QString mediaUrl = getMediaUrl();
+
+  /* Get media ID from db */
+  QSqlQuery query( db );
+  query.prepare( "select id from media where url = ?" );
+  query.bindValue( 0, mediaUrl );
+  if ( !query.exec() ) {
+    KMessageBox::sorry( 0, "SQL Error:" + query.lastError().text() );
+    return 0;
+  }
+  if ( !query.next() )
+     return 0;
+
+  /* Returns media ID */
+  return query.value( 0 ).toUInt();
+}
+
+/* ************************************************************************* */
+bool DBWidget::isConnected( void ) {
+  return db;
+}
+
+/* ************************************************************************* */
+void DBWidget::refresh_from_db( void ) {
+  if ( !isConnected() )
+    return;
+  tagsWidget->refresh_from_db();
+  textEdit->refresh_from_db();
+  thumbsWidget->refresh_from_db();
+}
+
+/* ************************************************************************* */
+void DBWidget::databaseConnect( void ) {
+  db = dbConfWidget->getdb();
+  if ( db ) {
+    kdDebug() << "Connection Succeed" << endl;
+    
+    /* Disable database conf. */
+    dbConfWidget->setEnableWidgets( false );
+
+    /* Create tabs */
+    tagsWidget = new TagsWidget( tabWidget, this );
+    textEdit = new Yo6TextEdit( tabWidget, this );
+    thumbsWidget = new ThumbsWidget( tabWidget, this, kaffeine );
+
+    tabWidget->addTab( tagsWidget, "tags" );
+    tabWidget->addTab( textEdit, "comments" );
+    tabWidget->addTab( thumbsWidget, "thumbnails" );
+  } else {
+    KMessageBox::sorry( 0, "Connection failed" );
+  }
+}
+
+/* ************************************************************************* */
+void DBWidget::databaseDisconnect( void ) {
+  if ( !db ) {
+    KMessageBox::error( 0, "Internal error" );
+    return;
+  }
+  dbConfWidget->releasedb( db );
+  db = 0L;
+  delete tagsWidget;
+  delete textEdit;
+  delete thumbsWidget;
+  dbConfWidget->setEnableWidgets( true );
+}
+// yo6 ending of modifications
+
+
 const KCmdLineOptions cmdLineOptions[] = {
 	{ "p", 0, 0 },
 	{ "play", I18N_NOOP("Start playing immediately"), 0 },
@@ -169,7 +747,10 @@
 		process.clearArguments();
 	}
 
-	mainbox = new QHBox( this );
+	// yo6 beginning of modifications
+	//mainbox = new QHBox( this );
+	mainbox = new QSplitter( this );
+	// yo6 ending of modifications
 	mainbox->setMouseTracking( true );
 	setCentralWidget(mainbox);
 	KMultiTabBar *mtBar = new KMultiTabBar( KMultiTabBar::Vertical, mainbox );
@@ -179,6 +760,11 @@
 	stack->setMouseTracking( true );
 	inplug = new InputManager( this, stack, mtBar );
 
+	// yo6 beginning of modifications
+	m_dbwidget = new DBWidget( mainbox, this );
+	m_dbwidget->hide();
+	// yo6 ending of modifications
+
 	m_startWindow = new StartWindow( stack );
 	inplug->addStartWindow( m_startWindow, KGlobal::iconLoader()->loadIcon("kmenu", KIcon::Small), i18n("Start") );
 
@@ -503,6 +1089,10 @@
 		m_mediaPart->openURL(mrl);
 		if ( !mrl.mime().contains("audio") )
 			QTimer::singleShot(300, this, SLOT(slotSwitchToPlayerWindow()));
+		// yo6 beginning of modifications
+		if ( m_dbwidget )
+		  m_dbwidget->setMediaUrl( mrl.url() );
+		// yo6 ending of modifications
 	}
 }
 
@@ -674,6 +1264,9 @@
 	m_fullscreen = KStdAction::fullScreen(this, SLOT(slotToggleFullscreen()), actionCollection(), this, "view_fullscreen");
 	m_minimal = new KToggleAction(i18n("&Minimal Mode"), 0, Key_M, this, SLOT(slotToggleMinimalMode()), actionCollection(), "view_minimal");
 	new KAction(i18n("Toggle &Playlist/Player"), 0, Key_P, this, SLOT(slotTogglePlaylist()), actionCollection(), "view_toggle_tab");
+	// yo6 beginning of modifications
+	new KAction(i18n("Toggle &Database Indexation"), 0, this, SLOT(slotToggleDatabase()), actionCollection(), "view_toggle_database");
+	// yo6 ending of modifications
 	m_originalAspect = new KToggleAction(i18n("Keep &Original Aspect"), 0, 0, this, SLOT(slotOriginalAspect()), actionCollection(), "view_original_aspect");
 	m_autoResizeOff = new KToggleAction(i18n("Off"), 0, ALT|Key_0, this, SLOT(slotAutoresizeOff()), actionCollection(), "view_auto_resize_off");
 	m_autoResizeOriginal = new KToggleAction(i18n("Original Size"), 0, ALT|Key_1, this, SLOT(slotAutoresizeOriginal()), actionCollection(), "view_auto_resize_original");
@@ -752,6 +1345,17 @@
 	KConfig* config = kapp->config();
 	bool b;
 
+	// yo6 beginning of modifications
+	config->setGroup("Database Connection");
+
+	DBConfWidget *dbcw = m_dbwidget->dbConfWidget;
+	dbcw->hostname->setText( config->readEntry( "Hostname", "localhost" ) );
+	dbcw->portnumber->setText( QString::number( config->readNumEntry( "Port Number", 3306 ) ) );
+	dbcw->username->setText( config->readEntry( "User Name", "root" ) );
+	dbcw->password->setText( config->readEntry( "Password", "" ) );
+	dbcw->database->setText( config->readEntry( "Database", "kaffeine" ) );
+	// yo6 ending of modifications
+
 	config->setGroup("General Options");
 
 	m_autoResizeFactor = config->readNumEntry("Autoresize Factor", 0);
@@ -825,6 +1429,17 @@
 		saveMainWindowSettings(config, "Main Window");
 	}
 
+	// yo6 beginning of modifications
+	DBConfWidget *dbcw = m_dbwidget->dbConfWidget;
+
+	config->setGroup("Database Connection");
+	config->writeEntry( "Hostname", dbcw->hostname->text() );
+	config->writeEntry( "Port Number", dbcw->portnumber->text() );
+	config->writeEntry( "User Name", dbcw->username->text() );
+	config->writeEntry( "Password", dbcw->password->text() );
+	config->writeEntry( "Database", dbcw->database->text() );
+	// yo6 ending of modifications
+
 	config->setGroup("General Options");
 	config->writeEntry("Autoresize Factor", m_autoResizeFactor);
 	config->writeEntry("Original Aspect", m_originalAspect->isChecked());
@@ -1103,6 +1718,17 @@
 		inplug->togglePlaylist();
 }
 
+// yo6 beginning of modifications
+void Kaffeine::slotToggleDatabase() {
+  if ( m_dbwidget ) {
+    if ( m_dbwidget->isHidden() )
+      m_dbwidget->show();
+    else
+      m_dbwidget->hide();
+  }
+}
+// yo6 ending of modifications
+
 void Kaffeine::slotSwitchToPlayerWindow()
 {
 	if ( !m_playerContainer )
diff -Naur kaffeine-0.8.6-original/kaffeine/src/kaffeine.h kaffeine-0.8.6/kaffeine/src/kaffeine.h
--- kaffeine-0.8.6-original/kaffeine/src/kaffeine.h	2008-03-04 21:27:30.000000000 +0100
+++ kaffeine-0.8.6/kaffeine/src/kaffeine.h	2008-03-04 21:12:05.000000000 +0100
@@ -34,6 +34,137 @@
 
 #include "kaffeineiface.h"
 
+// yo6 beginning of modifications
+#include <qwidget.h>
+#include <qtabwidget.h>
+#include <qlineedit.h>
+#include <qlistbox.h>
+#include <qgrid.h>
+#include <qsplitter.h>
+#include <qsqldatabase.h>
+#include <qsqlquery.h>
+#include <qvalidator.h>
+#include <kicontheme.h>
+#include <qobjectlist.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qlabel.h>
+#include <qtextedit.h>
+#include <qimage.h>
+#include <qcheckbox.h>
+
+class Kaffeine;
+class TagsWidget;
+class DBConfWidget;
+class ThumbsWidget;
+class DBWidget;
+
+/* ************************************************************************* */
+class Yo6Button : public QToolButton {
+  Q_OBJECT
+public:
+  Yo6Button( QWidget *parent, 
+	     const QString& iconName,
+	     const QString& labelName );
+};
+/* ************************************************************************* */
+class Yo6CheckBox : public QCheckBox {
+  Q_OBJECT
+public:
+  uint id_tag;
+  DBWidget *dbWidget;
+  Yo6CheckBox( QWidget *parent, DBWidget *dbWidget,
+	       const QString& description, uint id_tag );
+public slots:
+  void slotCheckBoxStateChanged( int state );
+};
+/* ************************************************************************* */
+class ThumbsWidget : public QVBox {
+  Q_OBJECT
+  QListBox *listBox;
+  DBWidget *dbWidget;
+  Kaffeine *kaffeine;
+public:
+  ThumbsWidget( QWidget *parent, DBWidget *dbWidget, Kaffeine *kaffeine );
+public slots:
+  void add_thumbs( void );
+  void del_thumbs( void );
+  void refresh_from_db( void );
+};
+/* ************************************************************************* */
+class Yo6TextEdit : public QTextEdit {
+  Q_OBJECT
+public:
+  DBWidget *dbWidget;
+  Yo6TextEdit( QWidget *parent, DBWidget *dbWidget );
+  void refresh_from_db( void );
+public slots:
+  void slotTextEditTextChanged();
+};
+/* ************************************************************************* */
+class TagsWidget : public QWidget {
+  Q_OBJECT
+  DBWidget *dbWidget;
+
+  uint nbCheckBoxes, nbCheckBoxesInv;
+  Yo6CheckBox **checkBox;
+  Yo6CheckBox **checkBoxInv;
+  
+public:
+  TagsWidget( QWidget *parent, DBWidget *dbWidget );
+  ~TagsWidget();
+
+  void refresh_from_db( void );
+};
+/* ************************************************************************* */
+class DBConfWidget : public QWidget {
+  Q_OBJECT
+private:
+  QLineEdit *createEntry( QWidget *parent, 
+			  QGridLayout *gridLayout,
+                          int row, int col,
+                          const QString& name, 
+			  const QString& contents );
+public:
+  QLineEdit *hostname, *portnumber, *username, *password, *database;
+  Yo6Button *button_connect, *button_disconnect;
+
+  DBConfWidget( QWidget *parent );
+  QSqlDatabase *getdb( void ) const;
+  static void releasedb( QSqlDatabase *db );
+  void setEnableWidgets( bool enabled );
+};
+/* ************************************************************************* */
+class DBWidget : public QWidget {
+  Q_OBJECT
+public:
+  Kaffeine *kaffeine;
+  QSqlDatabase *db;
+
+  QLineEdit *lineEdit;
+  QTabWidget *tabWidget;
+  DBConfWidget *dbConfWidget;
+  TagsWidget *tagsWidget;
+  Yo6TextEdit *textEdit;
+  ThumbsWidget *thumbsWidget;
+
+  DBWidget( QWidget *parent, Kaffeine *kaffeine );
+
+  void setMediaUrl( const QString& url );
+  QString getMediaUrl( void );
+  bool isMediaExist( void );
+  unsigned getMediaDbId( void );
+  unsigned getMediaDbIdNoInsert( void );
+
+  bool isConnected( void );
+  void refresh_from_db( void );
+
+public slots:
+  void databaseConnect( void );
+  void databaseDisconnect( void );
+};
+// yo6 ending of modifications
+
 class KActionMenu;
 class KCmdLineOptions;
 class KRecentFilesAction;
@@ -154,6 +285,9 @@
 	void slotOpenURL();
 	void slotOpenDirectory();
 	void slotPlaylistPlay();
+	// yo6 beginning of modifications
+	void slotToggleDatabase();
+	// yo6 ending of modifications
 	void slotNext();
 	void slotRequestForCurrentTrack();
 	void slotRequestForNextTrack();
@@ -203,14 +337,23 @@
 	QString askForOtherDevice(const QString&);
 	void unloadCurrentPart();
 
+// yo6 beginning of modifications
+public:
 	KaffeinePart* m_mediaPart;
-
+private:
 	InputManager *inplug;
 
-	QHBox *mainbox;
+	//QHBox *mainbox;
+	QSplitter *mainbox;
+	DBWidget *m_dbwidget;
+
 	QVBox *playerWidget;
 	PlayerContainer* m_playerContainer;
+public:
 	PlayList* m_playlist;
+private:
+// yo6 ending of modifications
+
 	Disc *cddisc;
 #ifdef HAVE_DVB
 	DvbPanel *dvbPanel;
diff -Naur kaffeine-0.8.6-original/kaffeine/src/kaffeineui.rc kaffeine-0.8.6/kaffeine/src/kaffeineui.rc
--- kaffeine-0.8.6-original/kaffeine/src/kaffeineui.rc	2008-03-04 21:27:30.000000000 +0100
+++ kaffeine-0.8.6/kaffeine/src/kaffeineui.rc	2008-03-04 21:12:05.000000000 +0100
@@ -22,6 +22,7 @@
   <Action name="view_fullscreen"/>
   <Action name="view_minimal"/>
   <Action name="view_toggle_tab"/>
+  <Action name="view_toggle_database"/>
   <Separator/>
   <Menu><text>Enable Auto &amp;Resize</text>
     <Action name="view_auto_resize_off"/>
diff -Naur kaffeine-0.8.6-original/kaffeine/src/main.cpp kaffeine-0.8.6/kaffeine/src/main.cpp
--- kaffeine-0.8.6-original/kaffeine/src/main.cpp	2008-03-04 21:27:30.000000000 +0100
+++ kaffeine-0.8.6/kaffeine/src/main.cpp	2008-03-04 21:12:05.000000000 +0100
@@ -71,6 +71,7 @@
 		KAboutData::License_GPL_V2, I18N_NOOP("Copyright (C) 2003-2007, The Kaffeine Authors"), 0,
 		"http://kaffeine.sourceforge.net");
 
+	aboutData.addAuthor("Olivier Parra", I18N_NOOP("Guest developer"), "olivier.parra@laposte.net"); // yo6
 	aboutData.addAuthor("Christophe Thommeret", I18N_NOOP("Current maintainer"), "hftom@free.fr");
 	aboutData.addAuthor("Christoph Pfister", I18N_NOOP("Developer"), "christophpfister@gmail.com");
 	aboutData.addAuthor("Jürgen Kofler", I18N_NOOP("Original author"), "kaffeine@gmx.net");
diff -Naur kaffeine-0.8.6-original/kaffeine/src/player-parts/kaffeine-part/kaffeinepart.h kaffeine-0.8.6/kaffeine/src/player-parts/kaffeine-part/kaffeinepart.h
--- kaffeine-0.8.6-original/kaffeine/src/player-parts/kaffeine-part/kaffeinepart.h	2008-03-04 21:27:30.000000000 +0100
+++ kaffeine-0.8.6/kaffeine/src/player-parts/kaffeine-part/kaffeinepart.h	2008-03-04 21:12:06.000000000 +0100
@@ -24,6 +24,9 @@
 #include <kparts/part.h>
 
 #include "mrl.h"
+// yo6 beginning of modifications
+#include "qimage.h"
+// yo6 ending of modifications
 
 /*
  * Base-Class for Kaffeine-Parts. Derive from this class if you want to develop a player part for Kaffeine.
@@ -99,6 +102,14 @@
 		return false;
 	}
 
+	// yo6 beginning of modifications
+	virtual QImage yo6ScreenShot() 
+	{ 
+	        return QImage(); 
+	}
+	// yo6 ending of modifications
+
+
 signals:
 	/*
 	 * Frame size of video changed
diff -Naur kaffeine-0.8.6-original/kaffeine/src/player-parts/xine-part/xine_part.cpp kaffeine-0.8.6/kaffeine/src/player-parts/xine-part/xine_part.cpp
--- kaffeine-0.8.6-original/kaffeine/src/player-parts/xine-part/xine_part.cpp	2008-03-04 21:27:30.000000000 +0100
+++ kaffeine-0.8.6/kaffeine/src/player-parts/xine-part/xine_part.cpp	2008-03-04 21:12:07.000000000 +0100
@@ -803,6 +803,14 @@
 		return "";
 }
 
+// yo6 beginning of modifications
+QImage XinePart::yo6ScreenShot() 
+{
+        return m_xine->getScreenshot();
+}
+// ending of modifications
+
+
 void XinePart::slotScreenshot()
 {
 	QImage shot = m_xine->getScreenshot();
diff -Naur kaffeine-0.8.6-original/kaffeine/src/player-parts/xine-part/xine_part.h kaffeine-0.8.6/kaffeine/src/player-parts/xine-part/xine_part.h
--- kaffeine-0.8.6-original/kaffeine/src/player-parts/xine-part/xine_part.h	2008-03-04 21:27:30.000000000 +0100
+++ kaffeine-0.8.6/kaffeine/src/player-parts/xine-part/xine_part.h	2008-03-04 21:12:07.000000000 +0100
@@ -106,6 +106,10 @@
 	void zoomOut();
 	void zoomOff();
 	QString screenShot();
+	// yo6 beginning of modifications
+	QImage yo6ScreenShot();
+	// yo6 ending of modifications
+
 	void nextAudioChannel();
 	void nextSubtitleChannel();
 	void speedFaster();
