Bug 79436

Summary: current.xml title parsing problem
Product: [Applications] amarok Reporter: Cariad Ilmara <cariad>
Component: generalAssignee: Amarok Bugs <amarok-bugs-null>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Gentoo Packages   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description Cariad Ilmara 2004-04-11 19:01:12 UTC
Version:           1.0 beta1 (using KDE KDE 3.2.1)
Installed from:    Gentoo Packages
Compiler:          GCC 3.3.2 QT 3.3.1
OS:          Linux

The XML infos storage doesn't work with some files. Some files with 'é' (&eacute;) in the title get written as such in current.xml.

On next load, amaroK cannot load the XML, thus creating an empty playlist.
A sample MP3 is available here : http://www.adnx.net/misc_data/amarok/PAG1.MP3

Also the encoding in current.xml for 'à' is also wrong. Although amaroK can load the playlist, the corresponding character will appear as a square in the playlist editor.
Sample playlist :
"<Title>La pince ?linge</Title>"
Comment 1 Stanislav Karchebny 2004-04-11 23:24:16 UTC
CVS commit by karchebny: 


* Proper saving of current.xml
* Formatting cleanup.

CCMAIL: 79436-done@bugs.kde.org


  M +23 -24    playlistwidget.cpp   1.166
  M +1 -1      playlistwidget.h   1.69


--- kdeextragear-1/amarok/amarok/playlistwidget.cpp  #1.165:1.166
@@ -277,5 +277,4 @@ void PlaylistWidget::handleOrder( Reques
                 {
                      item = (PlaylistItem *)itemAtIndex( KApplication::random() % count );
-                    kdDebug() << "[DBG] pick[2] item " << item << endl;
                 }
             }
@@ -323,9 +322,6 @@ void PlaylistWidget::saveXML( const QStr
 {
     //TODO save nextTrack queue
-    //TODO do the write in one go rather than gradually?
-    //  <berkus>: you can generate dom tree and then let it write down
-    //            (also saves you from making stupid mistakes with raw xml =)
-
     QFile file( path );
+    QDomDocument newdoc;
 
     if( !file.open( IO_WriteOnly ) ) return;
@@ -330,29 +326,34 @@ void PlaylistWidget::saveXML( const QStr
 
     if( !file.open( IO_WriteOnly ) ) return;
-
     QTextStream stream( &file );
-    const QString body  = "<%1>%2</%1>\n";
-    const QString open1 = "<item url=\"", open2 = "\">\n";
-    const QString close = "</item>\n";
+    stream.setEncoding(QTextStream::UnicodeUTF8);
 
     stream << "<?xml version=\"1.0\" encoding=\"utf8\"?>\n";
-    stream << "<playlist product=\"amaroK\" version=\"1\">\n";
+
+    QDomElement playlist = newdoc.createElement("playlist");
+    playlist.setAttribute("product", "amaroK");
+    playlist.setAttribute("version", "1");
+    newdoc.appendChild(playlist);
 
     for( const PlaylistItem *item = firstChild(); item; item = item->nextSibling() )
     {
-        stream << open1 << item->url().url() << open2;
-
-        //TODO speed up, cache columnNames (if would help), etc.
-        //NOTE we don't bother storing TrackName as this is based on the URL anyway
+        QDomElement i = newdoc.createElement("item");
+        i.setAttribute("url", item->url().url());
 
         for( int x = 1; x < columns(); ++x )
         {
             if( !item->exactText(x).isEmpty() )
-                stream << body.arg( columnText(x), item->exactText(x).replace( '&', "&amp;" ).replace( '<', "&lt;" ) );
+            {
+                QDomElement attr = newdoc.createElement( columnText(x) );
+                QDomText t = newdoc.createTextNode( item->exactText(x) );
+                attr.appendChild( t );
+                i.appendChild( attr );
         }
-        stream << close;
     }
 
-    stream << "</playlist>\n";
+        playlist.appendChild(i);
+    }
+
+    stream << newdoc.toString();
     file.close();
 }
@@ -610,6 +611,4 @@ void PlaylistWidget::activate( QListView
         m_cachedTrack = item;
 
-        kdDebug() << "[DBG] item=" << item << endl;
-
         //tell the engine to play the new track
         EngineController::instance()->play( item->metaBundle() );