Switch to side-by-side view

--- a/dirbrowser/cdbrowser.cpp
+++ b/dirbrowser/cdbrowser.cpp
@@ -72,6 +72,9 @@
 
 static const string minimFoldersViewPrefix("0$folders");
 
+const std::string
+CDBrowser::plContainerClass{"object.container.playlistContainer"};
+
 void CDWebPage::javaScriptConsoleMessage(
 #ifdef USING_WEBENGINE
     JavaScriptConsoleMessageLevel,
@@ -343,14 +346,14 @@
         // Servers page server link click: browse clicked server root
 	unsigned int cdsidx = atoi(scurl.c_str()+1);
         m_curpath.clear();
-        m_curpath.push_back(CtPathElt("0", "(servers)"));
+        m_curpath.push_back(CtPathElt("0", "(servers)", false));
         if (!newCds(cdsidx)) {
             return;
         }
         m_cds->srv()->getSearchCapabilities(m_searchcaps);
         emit sig_searchcaps_changed();
 
-	browseContainer("0", m_msdescs[cdsidx].friendlyName);
+	browseContainer("0", m_msdescs[cdsidx].friendlyName, false);
     }
     break;
 
@@ -384,14 +387,16 @@
                    << " id count: " << m_entries.size() << endl);
 	    return;
 	}
+        UPnPClient::UPnPDirObject& e{m_entries[i]};
+        bool isPlaylist = !e.getprop("upnp:class").compare(plContainerClass);
         if (m_lastbutton == Qt::MidButton) {
             // Open in new tab
             vector<CtPathElt> npath(m_curpath);
-            npath.push_back(CtPathElt(m_entries[i].m_id, m_entries[i].m_title));
+            npath.push_back(CtPathElt(e.m_id, e.m_title, isPlaylist));
             emit sig_browse_in_new_tab(u8s2qs(m_cds->srv()->getDeviceId()),
                                        npath);
         } else {
-            browseContainer(m_entries[i].m_id, m_entries[i].m_title);
+            browseContainer(e.m_id, e.m_title, isPlaylist);
         }
         return;
     }
@@ -428,21 +433,18 @@
         m_cds.reset();
         initialPage();
     } else {
-        string objid = m_curpath[i].objid;
-        string title = m_curpath[i].title;
-        string ss = m_curpath[i].searchStr;
-        QPoint scrollpos = m_curpath[i].scrollpos;
+        CtPathElt e{m_curpath[i]};
         m_curpath.erase(m_curpath.begin() + i, m_curpath.end());
         if (m_lastbutton == Qt::MidButton) {
             vector<CtPathElt> npath(m_curpath);
-            npath.push_back(CtPathElt(objid, title, ss));
+            npath.push_back(e);
             emit sig_browse_in_new_tab(u8s2qs(m_cds->srv()->getDeviceId()),
                                        npath);
         } else {
-            if (ss.empty()) {
-                browseContainer(objid, title, scrollpos);
+            if (e.searchStr.empty()) {
+                browseContainer(e.objid, e.title, e.isPlaylist, e.scrollpos);
             } else {
-                search(objid, ss, scrollpos);
+                search(e.objid, e.searchStr, e.scrollpos);
             }
         }
     }
@@ -485,7 +487,8 @@
     }
 }
 
-void CDBrowser::browseContainer(string ctid, string cttitle, QPoint scrollpos)
+void CDBrowser::browseContainer(string ctid, string cttitle, bool ispl,
+                                QPoint scrollpos)
 {
     LOGDEB("CDBrowser::browseContainer: " << " ctid " << ctid << endl);
     deleteReaders();
@@ -499,7 +502,7 @@
     }
     m_entries.clear();
 
-    m_curpath.push_back(CtPathElt(ctid, cttitle));
+    m_curpath.push_back(CtPathElt(ctid, cttitle, ispl));
 
     initContainerHtml();
     
@@ -527,7 +530,7 @@
     }
     m_savedscrollpos = scrollpos;
     m_entries.clear();
-    m_curpath.push_back(CtPathElt(objid, "(search)", iss));
+    m_curpath.push_back(CtPathElt(objid, "(search)", false, iss));
     initContainerHtml(iss);
 
     m_reader = new CDBrowseQO(m_cds->srv(), m_curpath.back().objid, iss, this);
@@ -687,6 +690,8 @@
 void CDBrowser::onBrowseDone(int)
 {
     //qDebug() <<"CDBrowser::onBrowseDone: " << m_entries.size() << " entries";
+    bool inPlaylist = m_curpath.back().isPlaylist;
+
     if (!m_reader) {
         qDebug() << "CDBrowser::onBrowseDone(int) no reader: cancelled";
         return;
@@ -715,7 +720,7 @@
     int nct = 0;
     char curinitial = 0;
     m_alphamap.clear();
-    if (!sortcrits.empty()) {
+    if (!inPlaylist && !sortcrits.empty()) {
         DirObjCmp cmpo(sortcrits);
 
         sort(m_entries.begin(), m_entries.end(), cmpo);
@@ -848,6 +853,8 @@
                 m_popupidx = value.toInt();
             } else if (!nm.compare("otype")) {
                 m_popupotype = qs2utf8s(value);
+            } else if (!nm.compare("ispl")) {
+                m_popupispl = value.toInt();
             } else {
                 LOGERR("onPopupJsDone: unknown key: " << qs2utf8s(nm) << endl);
             }
@@ -894,6 +901,10 @@
             m_popupidx = el.attribute("objidx").toInt();
         else
             m_popupidx = -1;
+        if (el.hasAttribute("ispl"))
+            m_popupispl = el.attribute("ispl").toInt();
+        else
+            m_popupispl = false;
         m_popupotype = qs2utf8s(el.attribute("class"));
         LOGDEB("Popup: " << " class " << m_popupotype << " objid " << 
                m_popupobjid << endl);
@@ -904,6 +915,10 @@
 
 void CDBrowser::doCreatePopupMenu()
 {
+    LOGDEB1("CDBrowser::doCreatePopupMenu: objid " << m_popupobjid <<
+           " title " << m_popupobjtitle << " type " <<  m_popupotype <<
+           " IDX " << m_popupidx << " ISPL " << m_popupispl << endl);
+
     QMenu *popup = new QMenu(this);
     QAction *act;
     QVariant v;
@@ -1089,7 +1104,7 @@
 
     if (m_popupmode == PUP_OPEN_IN_NEW_TAB) {
         vector<CtPathElt> npath(m_curpath);
-        npath.push_back(CtPathElt(m_popupobjid, m_popupobjtitle));
+        npath.push_back(CtPathElt(m_popupobjid, m_popupobjtitle, m_popupispl));
         emit sig_browse_in_new_tab(u8s2qs(m_cds->srv()->getDeviceId()), npath);
         return;
     }