changeset 1451:e4f223fc9099 svg

Implement "Export SVG file..."
author Chris Cannam
date Mon, 19 Dec 2016 16:32:34 +0000
parents c8b03c666185
children b9898dd955b8
files .hgsubstate CHANGELOG main/MainWindow.cpp main/MainWindow.h
diffstat 4 files changed, 129 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsubstate	Sat Dec 17 11:06:48 2016 +0000
+++ b/.hgsubstate	Mon Dec 19 16:32:34 2016 +0000
@@ -7,7 +7,7 @@
 7d46098431f39c265e47254e420576559587b3fe icons/scalable
 3257ddb6fff110cc88f3ffeaeefa0f29d5eb3b6f piper-cpp
 5f67a29f0fc7f1b908f7cde4866173a7af337862 sv-dependency-builds
-36076ef960fb86ade2dd2eca13edb1ed154ef55f svapp
-576be7933ec70cd7a24327536c6ad5e315c51bde svcore
-a68c25ba1153ae20c0a387f28a7a79be243d69b2 svgui
+b777379e70d851aa75ff66b677fb3bd4c79808d4 svapp
+b1a7f45544003003008ee5098628fc009771c5dc svcore
+6828735468c9f096e02a3dfa67a6529876741f69 svgui
 0eebd22a081a824067bf3d5de65326696feab653 vamp-plugin-sdk
--- a/CHANGELOG	Sat Dec 17 11:06:48 2016 +0000
+++ b/CHANGELOG	Mon Dec 19 16:32:34 2016 +0000
@@ -14,6 +14,8 @@
  - Add ability to open, display, and analyse very long audio files (of
    more than 2^32 sample frames)
 
+ - Add ability to export scalable (SVG) image files
+
  - Run plugins in a separate process, so that if a plugin crashes, it
    no longer brings down Sonic Visualiser with it. In every other
    respect the behaviour should be unchanged
@@ -40,7 +42,7 @@
 
  - Finally switch the Windows built to 64-bit by default (with
    adapters to run either 32- or 64-bit plugins)
- 
+
 
 Changes in Sonic Visualiser 2.5 since the previous release 2.4.1:
 
--- a/main/MainWindow.cpp	Sat Dec 17 11:06:48 2016 +0000
+++ b/main/MainWindow.cpp	Mon Dec 19 16:32:34 2016 +0000
@@ -589,6 +589,12 @@
     connect(this, SIGNAL(canExportImage(bool)), action, SLOT(setEnabled(bool)));
     menu->addAction(action);
 
+    action = new QAction(tr("Export SVG File..."), this);
+    action->setStatusTip(tr("Export a single pane to a scalable SVG image file"));
+    connect(action, SIGNAL(triggered()), this, SLOT(exportSVG()));
+    connect(this, SIGNAL(canExportImage(bool)), action, SLOT(setEnabled(bool)));
+    menu->addAction(action);
+
     menu->addSeparator();
 
     action = new QAction(tr("Browse Recorded Audio Folder"), this);
@@ -2856,18 +2862,21 @@
     Pane *pane = m_paneStack->getCurrentPane();
     if (!pane) return;
     
+//!!!    QString path = getSaveFileName(FileFinder::ImageFile);
+//    if (path == "") return;
+//    if (QFileInfo(path).suffix() == "") path += ".png";
     QString path = getSaveFileName(FileFinder::ImageFile);
-
     if (path == "") return;
-
-    if (QFileInfo(path).suffix() == "") path += ".png";
-
+    if (QFileInfo(path).suffix() == "") path += ".svg";
+
+    bool scalable = true; //!!!
+    
     bool haveSelection = m_viewManager && !m_viewManager->getSelections().empty();
 
     QSize total, visible, selected;
-    total = pane->getImageSize();
-    visible = pane->getImageSize(pane->getFirstVisibleFrame(),
-                                 pane->getLastVisibleFrame());
+    total = pane->getRenderedImageSize();
+    visible = pane->getRenderedPartImageSize(pane->getFirstVisibleFrame(),
+                                             pane->getLastVisibleFrame());
 
     sv_frame_t sf0 = 0, sf1 = 0;
  
@@ -2877,7 +2886,7 @@
         MultiSelection::SelectionList::iterator e = selections.end();
         --e;
         sf1 = e->getEndFrame();
-        selected = pane->getImageSize(sf0, sf1);
+        selected = pane->getRenderedPartImageSize(sf0, sf1);
     }
 
     QStringList items;
@@ -2896,7 +2905,7 @@
     settings.beginGroup("MainWindow");
     int deflt = settings.value("lastimageexportregion", 0).toInt();
     if (deflt == 2 && !haveSelection) deflt = 1;
-    if (deflt == 0 && total.width() > 32767) deflt = 1;
+    if (deflt == 0 && !scalable && total.width() > 32767) deflt = 1;
 
     ListInputDialog *lid = new ListInputDialog
         (this, tr("Select region to export"),
@@ -2906,7 +2915,7 @@
     if (!haveSelection) {
         lid->setItemAvailability(2, false);
     }
-    if (total.width() > 32767) { // appears to be the limit of a QImage
+    if (!scalable && total.width() > 32767) { // appears to be limit of a QImage
         lid->setItemAvailability(0, false);
         lid->setFootnote(tr("Note: the whole pane is too wide to be exported as a single image."));
     }
@@ -2919,25 +2928,114 @@
 
     settings.setValue("lastimageexportregion", deflt);
 
-    QImage *image = 0;
-
+    if (scalable) {
+
+        bool result = false;
+        
+        if (item == items[0]) {
+            result = pane->renderToSvgFile(path );
+        } else if (item == items[1]) {
+            result = pane->renderPartToSvgFile(path,
+                                               pane->getFirstVisibleFrame(),
+                                               pane->getLastVisibleFrame());
+        } else if (haveSelection) {
+            result = pane->renderPartToSvgFile(path, sf0, sf1);
+        }
+
+        if (!result) {
+            QMessageBox::critical(this, tr("Failed to save SVG file"),
+                                  tr("Failed to save SVG file %1").arg(path));
+        }
+
+    } else {
+        
+        QImage *image = 0;
+
+        if (item == items[0]) {
+            image = pane->renderToNewImage();
+        } else if (item == items[1]) {
+            image = pane->renderPartToNewImage(pane->getFirstVisibleFrame(),
+                                               pane->getLastVisibleFrame());
+        } else if (haveSelection) {
+            image = pane->renderPartToNewImage(sf0, sf1);
+        }
+
+        if (!image) return;
+
+        if (!image->save(path, "PNG")) {
+            QMessageBox::critical(this, tr("Failed to save image file"),
+                                  tr("Failed to save image file %1").arg(path));
+        }
+    
+        delete image;
+    }
+}
+
+void
+MainWindow::exportSVG()
+{
+    Pane *pane = m_paneStack->getCurrentPane();
+    if (!pane) return;
+    
+    QString path = getSaveFileName(FileFinder::SVGFile);
+    if (path == "") return;
+    if (QFileInfo(path).suffix() == "") path += ".svg";
+
+    bool haveSelection = m_viewManager && !m_viewManager->getSelections().empty();
+
+    sv_frame_t sf0 = 0, sf1 = 0;
+ 
+    if (haveSelection) {
+        MultiSelection::SelectionList selections = m_viewManager->getSelections();
+        sf0 = selections.begin()->getStartFrame();
+        MultiSelection::SelectionList::iterator e = selections.end();
+        --e;
+        sf1 = e->getEndFrame();
+    }
+
+    QStringList items;
+    items << tr("Export the whole pane");
+    items << tr("Export the visible area only");
+    items << tr("Export the selection extent");
+
+    QSettings settings;
+    settings.beginGroup("MainWindow");
+    int deflt = settings.value("lastsvgexportregion", 0).toInt();
+    if (deflt == 2 && !haveSelection) deflt = 1;
+
+    ListInputDialog *lid = new ListInputDialog
+        (this, tr("Select region to export"),
+         tr("Which region of the current pane do you want to export as a scalable SVG image?"),
+         items, deflt);
+
+    if (!haveSelection) {
+        lid->setItemAvailability(2, false);
+    }
+
+    bool ok = lid->exec();
+    QString item = lid->getCurrentString();
+    delete lid;
+	    
+    if (!ok || item.isEmpty()) return;
+
+    settings.setValue("lastsvgexportregion", deflt);
+
+    bool result = false;
+        
     if (item == items[0]) {
-        image = pane->toNewImage();
+        result = pane->renderToSvgFile(path );
     } else if (item == items[1]) {
-        image = pane->toNewImage(pane->getFirstVisibleFrame(),
-                                 pane->getLastVisibleFrame());
+        result = pane->renderPartToSvgFile(path,
+                                           pane->getFirstVisibleFrame(),
+                                           pane->getLastVisibleFrame());
     } else if (haveSelection) {
-        image = pane->toNewImage(sf0, sf1);
-    }
-
-    if (!image) return;
-
-    if (!image->save(path, "PNG")) {
-        QMessageBox::critical(this, tr("Failed to save image file"),
-                              tr("Failed to save image file %1").arg(path));
+        result = pane->renderPartToSvgFile(path, sf0, sf1);
     }
     
-    delete image;
+    if (!result) {
+        QMessageBox::critical(this, tr("Failed to save SVG file"),
+                              tr("Failed to save SVG file %1").arg(path));
+    }
 }
 
 void
--- a/main/MainWindow.h	Sat Dec 17 11:06:48 2016 +0000
+++ b/main/MainWindow.h	Mon Dec 19 16:32:34 2016 +0000
@@ -63,6 +63,7 @@
     virtual void importLayer();
     virtual void exportLayer();
     virtual void exportImage();
+    virtual void exportSVG();
     virtual void browseRecordedAudio();
     virtual void saveSession();
     virtual void saveSessionAs();