changeset 1349:615eb28768ca zoom

Merge from default branch
author Chris Cannam
date Mon, 01 Oct 2018 15:48:20 +0100
parents 4c28e3302045 (current diff) 01778052e663 (diff)
children 4949061fcb8c
files
diffstat 3 files changed, 117 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/widgets/PluginParameterBox.cpp	Fri Sep 28 18:28:44 2018 +0100
+++ b/widgets/PluginParameterBox.cpp	Mon Oct 01 15:48:20 2018 +0100
@@ -121,6 +121,10 @@
         if (!(hint & PortHint::Logarithmic)) {
             if (qtz > 0.0) {
                 imax = int(lrintf((max - min) / qtz));
+                if (imax <= imin) {
+                    imax = 100;
+                    qtz = (max - min) / 100.f;
+                }
             } else {
                 qtz = (max - min) / 100.f;
             }
@@ -181,15 +185,22 @@
 //            dial->setValue(lrintf((value - min) / qtz));
             dial->setFixedWidth(32);
             dial->setFixedHeight(32);
-            RangeMapper *rm = 0;
-            if (hint & PortHint::Logarithmic) {
-                rm = new LogRangeMapper(imin, imax, min, max, unit);
+            if (max == min || imax == imin) {
+                SVCERR << "WARNING: for parameter \"" << name
+                       << "\" of plugin \"" << m_plugin->getName()
+                       << "\": invalid range " << min << " -> " << max
+                       << " with quantize step " << qtz << endl;
             } else {
-                rm = new LinearRangeMapper(imin, imax, min, max, unit);
+                RangeMapper *rm = 0;
+                if (hint & PortHint::Logarithmic) {
+                    rm = new LogRangeMapper(imin, imax, min, max, unit);
+                } else {
+                    rm = new LinearRangeMapper(imin, imax, min, max, unit);
+                }
+                dial->setRangeMapper(rm);
+                dial->setDefaultValue(rm->getPositionForValue(deft));
+                dial->setValue(rm->getPositionForValue(value));
             }
-            dial->setRangeMapper(rm);
-            dial->setDefaultValue(rm->getPositionForValue(deft));
-            dial->setValue(rm->getPositionForValue(value));
             dial->setShowToolTip(true);
             connect(dial, SIGNAL(valueChanged(int)),
                     this, SLOT(dialChanged(int)));
--- a/widgets/SubdividingMenu.cpp	Fri Sep 28 18:28:44 2018 +0100
+++ b/widgets/SubdividingMenu.cpp	Mon Oct 01 15:48:20 2018 +0100
@@ -22,6 +22,8 @@
 using std::set;
 using std::map;
 
+//#define DEBUG_SUBDIVIDING_MENU 1
+
 SubdividingMenu::SubdividingMenu(int lowerLimit, int upperLimit,
                                  QWidget *parent) :
     QMenu(parent),
@@ -29,6 +31,9 @@
     m_upperLimit(upperLimit ? upperLimit : (m_lowerLimit * 5) / 2),
     m_entriesSet(false)
 {
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu: constructed without title" << endl;
+#endif
 }
 
 SubdividingMenu::SubdividingMenu(const QString &title, int lowerLimit,
@@ -38,6 +43,10 @@
     m_upperLimit(upperLimit ? upperLimit : (m_lowerLimit * 5) / 2),
     m_entriesSet(false)
 {
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu: constructed with title \""
+         << title << "\"" << endl;
+#endif
 }
 
 SubdividingMenu::~SubdividingMenu()
@@ -53,6 +62,11 @@
 {
     m_entriesSet = true;
 
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu::setEntries(" << title() << "): "
+         << entries.size() << " entries" << endl;
+#endif
+
     int total = int(entries.size());
         
     if (total < m_upperLimit) return;
@@ -65,37 +79,51 @@
     QChar firstInitialInChunk;
     bool discriminateStartInitial = false;
 
-    for (set<QString>::const_iterator j = entries.begin();
-         j != entries.end();
-         ++j) {
+    // Re-sort using locale-aware comparator
 
-//        SVDEBUG << "SubdividingMenu::setEntries: j -> " << j->toStdString() << endl;
+    auto comparator = [](QString s1, QString s2) -> bool {
+                          return QString::localeAwareCompare(s1, s2) < 0;
+                      };
+    
+    set<QString, typeof(comparator)> sortedEntries(comparator);
+    sortedEntries.insert(entries.begin(), entries.end());
+    
+    for (auto j = sortedEntries.begin(); j != sortedEntries.end(); ++j) {
+
+#ifdef DEBUG_SUBDIVIDING_MENU
+        cerr << "SubdividingMenu::setEntries: entry is: " << j->toStdString() << endl;
+#endif
 
         m_nameToChunkMenuMap[*j] = chunkMenu;
 
-        set<QString>::iterator k = j;
+        auto k = j;
         ++k;
 
-        QChar initial = (*j)[0];
+        QChar initial = (*j)[0].toUpper();
 
         if (count == 0) {
             firstNameInChunk = *j;
             firstInitialInChunk = initial;
+#ifdef DEBUG_SUBDIVIDING_MENU
+            cerr << "starting new chunk at initial " << initial << endl;
+#endif
         }
 
-//        cerr << "count = "<< count << ", upper limit = " << m_upperLimit << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+        cerr << "count = "<< count << ", upper limit = " << m_upperLimit << endl;
+#endif
 
-        bool lastInChunk = (k == entries.end() ||
+        bool lastInChunk = (k == sortedEntries.end() ||
                             (count >= m_lowerLimit-1 &&
                              (count == m_upperLimit ||
-                              (*k)[0] != initial)));
+                              (*k)[0].toUpper() != initial)));
 
         ++count;
 
         if (lastInChunk) {
 
-            bool discriminateEndInitial = (k != entries.end() &&
-                                           (*k)[0] == initial);
+            bool discriminateEndInitial = (k != sortedEntries.end() &&
+                                           (*k)[0].toUpper() == initial);
 
             bool initialsEqual = (firstInitialInChunk == initial);
 
@@ -136,30 +164,40 @@
 SubdividingMenu::entriesAdded()
 {
     if (m_entriesSet) {
-        cerr << "ERROR: SubdividingMenu::entriesAdded: setEntries was also called -- should use one mechanism or the other, but not both" << endl;
+        SVCERR << "ERROR: SubdividingMenu::entriesAdded: setEntries was also called -- should use one mechanism or the other, but not both" << endl;
         return;
     }
     
     set<QString> entries;
-    for (map<QString, QObject *>::const_iterator i = m_pendingEntries.begin();
-         i != m_pendingEntries.end(); ++i) {
-        entries.insert(i->first);
+    for (auto i: m_pendingEntries) {
+        entries.insert(i.first);
+    }
+    setEntries(entries);
+
+    // Re-sort using locale-aware comparator (setEntries will do this
+    // again, for the set passed to it, but we need the same sorting
+    // for the subsequent loop in this function as well)
+    auto comparator = [](QString s1, QString s2) -> bool {
+                          return QString::localeAwareCompare(s1, s2) < 0;
+                      };
+    set<QString, typeof(comparator)> sortedEntries(comparator);
+    for (auto i: m_pendingEntries) {
+        sortedEntries.insert(i.first);
     }
     
-    setEntries(entries);
+    for (QString entry: sortedEntries) {
 
-    for (map<QString, QObject *>::iterator i = m_pendingEntries.begin();
-         i != m_pendingEntries.end(); ++i) {
-
-        QMenu *menu = dynamic_cast<QMenu *>(i->second);
+        QObject *obj = m_pendingEntries[entry];
+        
+        QMenu *menu = dynamic_cast<QMenu *>(obj);
         if (menu) {
-            addMenu(i->first, menu);
+            addMenu(entry, menu);
             continue;
         }
 
-        QAction *action = dynamic_cast<QAction *>(i->second);
+        QAction *action = dynamic_cast<QAction *>(obj);
         if (action) {
-            addAction(i->first, action);
+            addAction(entry, action);
             continue;
         }
     }
@@ -178,12 +216,16 @@
     }
 
     if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
-//        SVDEBUG << "SubdividingMenu::addAction(" << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+        cerr << "SubdividingMenu::addAction(" << title() << " | " << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#endif
         QMenu::addAction(action);
         return;
     }
 
-//    SVDEBUG << "SubdividingMenu::addAction(" << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu::addAction(" << title() << " | " << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#endif
     m_nameToChunkMenuMap[name]->addAction(action);
 }
 
@@ -197,11 +239,15 @@
     }
 
     if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
-//        SVDEBUG << "SubdividingMenu::addAction(" << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+        cerr << "SubdividingMenu::addAction(" << title() << " | " << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#endif
         return QMenu::addAction(name);
     }
 
-//    SVDEBUG << "SubdividingMenu::addAction(" << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu::addAction(" << title() << " | " << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#endif
     return m_nameToChunkMenuMap[name]->addAction(name);
 }
 
@@ -214,12 +260,16 @@
     }
 
     if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
-//        SVDEBUG << "SubdividingMenu::addAction(" << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+        cerr << "SubdividingMenu::addAction(" << title() << " | " << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#endif
         QMenu::addAction(action);
         return;
     }
 
-//    SVDEBUG << "SubdividingMenu::addAction(" << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu::addAction(" << title() << " | " << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#endif
     m_nameToChunkMenuMap[name]->addAction(action);
 }
 
@@ -234,12 +284,16 @@
     }
 
     if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
-//        SVDEBUG << "SubdividingMenu::addMenu(" << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+        cerr << "SubdividingMenu::addMenu(" << title() << " | " << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#endif
         QMenu::addMenu(menu);
         return;
     }
 
-//    SVDEBUG << "SubdividingMenu::addMenu(" << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu::addMenu(" << title() << " | " << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#endif
     m_nameToChunkMenuMap[name]->addMenu(menu);
 }
 
@@ -254,11 +308,15 @@
     }
 
     if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
-//        SVDEBUG << "SubdividingMenu::addMenu(" << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+        cerr << "SubdividingMenu::addMenu(" << title() << " | " << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#endif
         return QMenu::addMenu(name);
     }
 
-//    SVDEBUG << "SubdividingMenu::addMenu(" << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu::addMenu(" << title() << " | " << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#endif
     return m_nameToChunkMenuMap[name]->addMenu(name);
 }
 
@@ -271,12 +329,16 @@
     }
 
     if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
-//        SVDEBUG << "SubdividingMenu::addMenu(" << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+        cerr << "SubdividingMenu::addMenu(" << title() << " | " << name << "): not found in name-to-chunk map, adding to main menu" << endl;
+#endif
         QMenu::addMenu(menu);
         return;
     }
 
-//    SVDEBUG << "SubdividingMenu::addMenu(" << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#ifdef DEBUG_SUBDIVIDING_MENU
+    cerr << "SubdividingMenu::addMenu(" << title() << " | " << name << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title() << endl;
+#endif
     m_nameToChunkMenuMap[name]->addMenu(menu);
 }
 
--- a/widgets/SubdividingMenu.h	Fri Sep 28 18:28:44 2018 +0100
+++ b/widgets/SubdividingMenu.h	Mon Oct 01 15:48:20 2018 +0100
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _SUBDIVIDING_MENU_H_
-#define _SUBDIVIDING_MENU_H_
+#ifndef SV_SUBDIVIDING_MENU_H
+#define SV_SUBDIVIDING_MENU_H
 
 #include <QMenu>