Bug 142897

Summary: More intuitive vector selection for complex data sources
Product: [Applications] kst Reporter: Andrew Walker <arwalker>
Component: generalAssignee: kst
Status: RESOLVED FIXED    
Severity: wishlist    
Priority: NOR    
Version: 1.x   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Andrew Walker 2007-03-13 01:56:47 UTC
Version:           HEAD (using KDE KDE 3.5.1)
OS:                Linux

For more complex data sources (e.g. fits files) it is often the case that the available vectors are naturally hierarchical in nature. 

Thus, it would be useful to allow the user to select from the available data source via a tree rather than a simple list. This would allow the tree to reflect the naturual order of the data source.

For simpler data sources the existing linear display of vector names could be retained.
Comment 1 Andrew Walker 2007-06-19 00:39:58 UTC
SVN commit 677340 by arwalker:

CCBUG:142897 Start support for hierarchical data sources

 M  +10 -4     datasources/planckIDEF/planckIDEF.cpp  
 M  +1 -1      datasources/planckIDEF/planckIDEF.h  
 M  +10 -0     libkst/kstdatacollection.cpp  
 M  +14 -4     libkst/kstdatasource.cpp  
 M  +2 -1      libkst/kstdatasource.h  
 M  +2 -1      libkstapp/Makefile.am  
 M  +0 -247    libkstapp/datawizard.ui  
 M  +3 -3      libkstapp/kst.cpp  
 A             libkstapp/kstdatawizard_i.cpp   [License: GPL (v2+)]
 A             libkstapp/kstdatawizard_i.h   [License: GPL (v2+)]
 M  +39 -35    libkstapp/kstviewobject.cpp  
Comment 2 Andrew Walker 2007-07-20 03:42:25 UTC
SVN commit 690077 by arwalker:

CCBUG:142897 continue work for hierarchical data sources

 M  +10 -5     datasources/planckIDEF/planckIDEF.cpp  
 M  +11 -0     libkst/kstdataplugin.h  
 M  +18 -1     libkst/kstdatasource.cpp  
 M  +3 -0      libkst/kstdatasource.h  
 M  +5 -1      libkstapp/kstdatawizard_i.cpp  


--- branches/work/kst/1.5/kst/src/datasources/planckIDEF/planckIDEF.cpp #690076:690077
@@ -501,7 +501,7 @@
                         iResult = fits_read_keyword( ffits, "EXTNAME", value, comment, &iStatus );
                         if( iResult == 0 )
                         {
-                          prefixNew = prefix + QDir::separator() + QString( value ).remove( QChar( '\'' ) );
+                          prefixNew = prefix + separator() + QString( value ).remove( QChar( '\'' ) );
                         }
 
                         iResult = 0;
@@ -554,7 +554,7 @@
         fileList*   folderFields;
         folderField folderField;
         QString     baseName = baseFilename(*it);
-        QString     pathname = folder.path() + QDir::separator() + *it;
+        QString     pathname = folder.path() + separator() + *it;
         int         numFrames;
 
         folderFields = _basefiles.find( baseName );
@@ -574,7 +574,7 @@
             fld->table = 0;
             fld->column = 0;
 
-            strIndex = baseName + QDir::separator() + "INDEX";
+            strIndex = baseName + separator() + "INDEX";
             _fields.insert( strIndex, fld );
             _fieldList.append( strIndex );
 
@@ -833,7 +833,7 @@
     fld = _fields.find( fieldName );
     if( fld != 0L ) 
     {
-      if( fieldName == fld->basefile + QDir::separator() + QString("INDEX") )
+      if( fieldName == fld->basefile + separator() + QString("INDEX") )
       {
         for( i = 0; i < n; ++i )
         {
@@ -965,7 +965,7 @@
   {
     for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) 
     {
-      pathname = folder.path() + QDir::separator() + *it;
+      pathname = folder.path() + separator() + *it;
 
       if( checkValidPlanckIDEFFile( pathname ) )
       {
@@ -1190,6 +1190,11 @@
     return rc;
   }
 
+  bool supportsHierarchy_planckIDEF( )
+  {
+    return true;
+  }
+
   int understands_planckIDEF( KConfig*, const QString& filename )
   {
     QFileInfo fileinfo( filename );
--- branches/work/kst/1.5/kst/src/libkst/kstdataplugin.h #690076:690077
@@ -224,6 +224,17 @@
         return false;
       }
 
+      bool supportsHierarchy() const {
+        bool (*sym)() = (bool(*)())symbol("supportsHierarchy");
+        if (sym) {
+          //kstdDebug() << "Checking if " << service->property("Name").toString() << " provides " << type << endl;
+          bool rc = (sym)();
+          return rc;
+        }
+
+        return false;
+      }
+
       bool provides(const QString& type) const {
         return provides().contains(type);
       }
--- branches/work/kst/1.5/kst/src/libkst/kstdatasource.cpp #690076:690077
@@ -318,6 +318,24 @@
 }
 
 
+bool KstDataSource::supportsHierarchy(const QString& filename, const QString& type) {
+  if (filename.isEmpty() || filename == "stdin" || filename == "-") {
+    return false;
+  }
+
+  QString fn = obtainFile(filename);
+  if (fn.isEmpty()) {
+    return false;
+  }
+
+  QValueList<PluginSortContainer> bestPlugins = bestPluginsForSource(fn, type);
+  if (bestPlugins.isEmpty()) {
+    return false;
+  }
+  return (*bestPlugins.begin()).plugin->supportsHierarchy();
+}
+
+
 QStringList KstDataSource::fieldListForSource(const QString& filename, const QString& type, QString *outType, bool *complete) {
   if (filename == "stdin" || filename == "-") {
     return QStringList();
@@ -360,7 +378,6 @@
     }
   }
 
-
   return rc;
 }
 
--- branches/work/kst/1.5/kst/src/libkst/kstdatasource.h #690076:690077
@@ -19,6 +19,7 @@
 #define KSTDATASOURCE_H
 
 #include <qdict.h>
+#include <qdir.h>
 #include <qdom.h>
 #include <qguardedptr.h>
 #include <qstring.h>
@@ -74,6 +75,8 @@
     static bool pluginHasConfigWidget(const QString& plugin);
     // @since 1.1.0
     static bool supportsTime(const QString& plugin, const QString& type = QString::null);
+    static bool supportsHierarchy(const QString& filename, const QString& type = QString::null);
+    static char separator() { return QDir::separator(); }
 
     KstDataSourceConfigWidget *configWidget() const;
 
--- branches/work/kst/1.5/kst/src/libkstapp/kstdatawizard_i.cpp #690076:690077
@@ -299,6 +299,7 @@
       ds = 0L;
     } else {
       fl = KstDataSource::fieldListForSource(file, QString::null, &fileType, &complete);
+      hierarchy = KstDataSource::supportsHierarchy(file, QString::null);
     }
 
     if (!fl.isEmpty() && !fileType.isEmpty()) {
@@ -337,12 +338,14 @@
 
     for (QStringList::ConstIterator it = fl.begin(); it != fl.end(); ++it) {
       QListViewItem *item = new QListViewItem(_vectors, *it);
+      QString str;
+
       item->setDragEnabled(true);
-      QString str;
       str.sprintf("%0*d", count, index++);
       item->setText(1, str);
       _countMap[*it] = str;
     }
+
     _vectors->sort();
 
     KST::vectorDefaults.sync();
@@ -548,6 +551,7 @@
   _vectors->setSorting(3, true); // Qt 3.1 compat
   QRegExp re(filter, true /* case insensitive */, true /* wildcard */);
   QListViewItemIterator it(_vectors);
+
   while (it.current()) {
     QListViewItem *i = it.current();
     ++it;
Comment 3 Andrew Walker 2007-07-24 20:47:17 UTC
SVN commit 691970 by arwalker:

CCBUG:142897 SVN_SILENT first draft of support for hierarchical data sources in the data wizard

 M  +117 -13   kstdatawizard_i.cpp  
 M  +2 -0      kstdatawizard_i.h  


--- branches/work/kst/1.5/kst/src/libkstapp/kstdatawizard_i.cpp #691969:691970
@@ -59,6 +59,7 @@
 {
   _configWidget = 0L;
   _inTest = false;
+  _hierarchy = false;
   KST::vectorDefaults.sync();
   QString default_source = KST::vectorDefaults.dataSource();
   _url->setMode(KFile::File | KFile::Directory | KFile::ExistingOnly);
@@ -284,22 +285,23 @@
     KstDataSourcePtr ds = *KST::dataSourceList.findReusableFileName(file);
     QStringList fl;
     bool complete = false;
-    bool hierarchy = false;
     QString fileType;
     int index = 0;
     int count;
 
+    _hierarchy = false;
+
     if (ds) {
       ds->readLock();
       fl = ds->fieldList();
       fileType = ds->fileType();
       complete = ds->fieldListIsComplete();
-      hierarchy = ds->supportsHierarchy();
+      _hierarchy = ds->supportsHierarchy();
       ds->unlock();
       ds = 0L;
     } else {
       fl = KstDataSource::fieldListForSource(file, QString::null, &fileType, &complete);
-      hierarchy = KstDataSource::supportsHierarchy(file, QString::null);
+      _hierarchy = KstDataSource::supportsHierarchy(file, QString::null);
     }
 
     if (!fl.isEmpty() && !fileType.isEmpty()) {
@@ -336,14 +338,60 @@
       count = 1;
     }
 
-    for (QStringList::ConstIterator it = fl.begin(); it != fl.end(); ++it) {
-      QListViewItem *item = new QListViewItem(_vectors, *it);
-      QString str;
+    _fields.clear();
 
-      item->setDragEnabled(true);
-      str.sprintf("%0*d", count, index++);
-      item->setText(1, str);
-      _countMap[*it] = str;
+    if (_hierarchy) {
+      for (QStringList::ConstIterator it = fl.begin(); it != fl.end(); ++it) {
+        QStringList     entries = QStringList::split(QDir::separator(), (*it), FALSE);
+        QString         item;
+        QListViewItem*  parent = 0L;
+        QListViewItem*  parentOld = 0L;
+
+        for (QStringList::ConstIterator itEntry = entries.begin(); itEntry != entries.end(); ++itEntry) {
+          item += (*itEntry);
+
+          if (item.compare(*it) != 0) {
+            parent = _fields.find(item);
+            if (parent == 0L) {
+              if (parentOld) {
+                QListViewItem *listItem = new QListViewItem(parentOld, *itEntry);
+
+                parentOld->setOpen(true);
+                _fields.insert(item, listItem);
+                parentOld = listItem;
+              } else {
+                QListViewItem *listItem = new QListViewItem(_vectors, *itEntry);
+
+                _fields.insert(item, listItem);
+                parentOld = listItem;
+              }
+            } else {
+              parentOld = parent;
+            }
+
+            item += QDir::separator();
+          } else if (parentOld) {
+            QListViewItem *listItem = new QListViewItem(parentOld, *itEntry);
+
+            parentOld->setOpen(true);
+            _fields.insert(item, listItem);
+          } else {
+            QListViewItem *listItem = new QListViewItem(_vectors, *itEntry);
+
+            _fields.insert(item, listItem);
+          }
+        }
+      }
+    } else {
+      for (QStringList::ConstIterator it = fl.begin(); it != fl.end(); ++it) {
+        QListViewItem *item = new QListViewItem(_vectors, *it);
+        QString str;
+
+        item->setDragEnabled(true);
+        str.sprintf("%0*d", count, index++);
+        item->setText(1, str);
+        _countMap[*it] = str;
+      }
     }
 
     _vectors->sort();
@@ -1375,7 +1423,9 @@
   QListViewItemIterator it(_vectors);
   while (it.current()) {
     if (it.current()->isSelected()) {
-      lst.append(it.current());
+      if (it.current()->childCount() == 0) {
+        lst.append(it.current());
+      }
     }
     ++it;
   }
@@ -1383,9 +1433,36 @@
   QListViewItem *last = _vectorsToPlot->lastItem();
   QPtrListIterator<QListViewItem> iter(lst);
   while (iter.current()) {
+    QListViewItem* parent;
     QListViewItem *item = iter.current();
-    _vectors->takeItem(item);
+    parent = item->parent();
+
+    while (parent) {
+      item->setText(0, parent->text(0) + QDir::separator() + item->text(0));
+      parent = parent->parent();
+    }
+
+    parent = item->parent();
+    if (parent) {
+      QListViewItem* parentNew;
+
+      parent->takeItem(item);
+      parentNew = parent;
+      while (parentNew) {
+        parent = parentNew;
+        if (parent->childCount() == 0) {
+          parentNew = parent->parent();
+          parent->setSelected(false);
+          parent->setVisible(false);
+        } else {
+          parentNew = 0L;
+        }
+      }
+    } else {
+      _vectors->takeItem(item);
+    }
     _vectorsToPlot->insertItem(item);
+
     item->moveItem(last);
     item->setSelected(false);
     last = item;
@@ -1415,7 +1492,34 @@
   QPtrListIterator<QListViewItem> iter(lst);
   while (iter.current()) {
     _vectorsToPlot->takeItem(iter.current());
-    _vectors->insertItem(iter.current());
+    if (_hierarchy) {
+      QListViewItem* parent = 0L;
+      QStringList entries;
+      QString text = iter.current()->text(0);
+      QString item;
+
+      entries = QStringList::split(QDir::separator(), text, FALSE);
+      for (QStringList::ConstIterator itEntry = entries.begin(); itEntry != entries.end(); ++itEntry) {
+        item += (*itEntry);
+        if (text.compare(item) != 0) {
+          parent = _fields.find(item);
+          if (parent) {
+            parent->setVisible(true);
+          }
+          item += QDir::separator();
+        } else {
+          iter.current()->setText(0, entries.back());
+
+          if (parent) {
+            parent->insertItem(iter.current());
+          } else {
+            _vectors->insertItem(iter.current());
+          }
+        }
+      }
+    } else {
+      _vectors->insertItem(iter.current());
+    }
     iter.current()->setSelected(false);
     ++iter;
   }
--- branches/work/kst/1.5/kst/src/libkstapp/kstdatawizard_i.h #691969:691970
@@ -75,6 +75,8 @@
   private:
     static const QString &defaultTag;
     QString _file;
+    QDict<QListViewItem> _fields;
+    bool _hierarchy;
     bool _inTest;
     QGuardedPtr<QWidget> _configWidget;
     KstDataSourceList _sourceCache;
Comment 4 Andrew Walker 2008-04-30 01:52:21 UTC
SVN commit 802611 by arwalker:

BUG:142897 add hierarchical field selection to the new vector dialog

 M  +3 -0      Makefile.am  
 A             fieldselect.ui  
 M  +8 -6      kstdatawizard_i.cpp  
 A             kstfieldselect_i.cpp   [License: GPL (v2+)]
 A             kstfieldselect_i.h   [License: GPL (v2+)]
 M  +31 -6     kstvectordialog_i.cpp  
 M  +27 -29    kstvectordialog_i.h  
 M  +105 -43   vectordialogwidget.ui  


WebSVN link: http://websvn.kde.org/?view=rev&revision=802611