changeset 601:021d42e6c8cb

Avoid setting the session file path when loading an incomplete document, so that the default-file save-on-exit and File->Save are not activated (to avoid losing references to unfound audio files)
author Chris Cannam
date Mon, 18 Jun 2018 14:16:06 +0100
parents ca96a514fbbb
children d767bdf4879b
files framework/Document.cpp framework/Document.h framework/MainWindowBase.cpp framework/SVFileReader.cpp
diffstat 4 files changed, 86 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/framework/Document.cpp	Mon Jun 11 14:40:56 2018 +0100
+++ b/framework/Document.cpp	Mon Jun 18 14:16:06 2018 +0100
@@ -51,7 +51,8 @@
 Document::Document() :
     m_mainModel(0),
     m_autoAlignment(false),
-    m_align(new Align())
+    m_align(new Align()),
+    m_isIncomplete(false)
 {
     connect(this,
             SIGNAL(modelAboutToBeDeleted(Model *)),
--- a/framework/Document.h	Mon Jun 11 14:40:56 2018 +0100
+++ b/framework/Document.h	Mon Jun 18 14:16:06 2018 +0100
@@ -196,7 +196,7 @@
      * Get the main model (the source for playback sample rate, etc).
      */
     const WaveFileModel *getMainModel() const { return m_mainModel; }
-
+    
     std::vector<Model *> getTransformInputModels();
 
     bool isKnownModel(const Model *) const;
@@ -293,6 +293,15 @@
      */
     void alignModels();
 
+    /**
+     * Return true if any external files (most obviously audio) failed
+     * to be found on load, so that the document is incomplete
+     * compared to its saved description.
+     */
+    bool isIncomplete() const { return m_isIncomplete; }
+
+    void setIncomplete(bool i) { m_isIncomplete = i; }
+
     void toXml(QTextStream &, QString indent, QString extraAttributes) const;
     void toXmlAsTemplate(QTextStream &, QString indent, QString extraAttributes) const;
 
@@ -443,6 +452,8 @@
 
     bool m_autoAlignment;
     Align *m_align;
+
+    bool m_isIncomplete;
 };
 
 #endif
--- a/framework/MainWindowBase.cpp	Mon Jun 11 14:40:56 2018 +0100
+++ b/framework/MainWindowBase.cpp	Mon Jun 18 14:16:06 2018 +0100
@@ -669,7 +669,7 @@
     emit canClearSelection(haveSelection);
     emit canEditSelection(haveSelection && haveCurrentEditableLayer);
     emit canSave(m_sessionFile != "" && m_documentModified);
-    emit canSaveAs(haveMainModel);
+    emit canSaveAs(haveMainModel); // possibly used only in Tony, not SV
     emit canSelectPreviousPane(havePrevPane);
     emit canSelectNextPane(haveNextPane);
     emit canSelectPreviousLayer(havePrevLayer);
@@ -2096,7 +2096,15 @@
                        .arg(QApplication::applicationName())
                        .arg(source.getLocation()));
 
-        if (!source.isRemote()) m_sessionFile = source.getLocalFilename();
+        if (!source.isRemote() && !m_document->isIncomplete()) {
+            // Setting the session file path enables the Save (as
+            // opposed to Save As...) option. We can't do this if we
+            // don't have a local path to save to, but we also don't
+            // want to do it if we failed to find an audio file or
+            // similar on load, as the audio reference would then end
+            // up being lost from any saved or auto-saved-on-exit copy
+            m_sessionFile = source.getLocalFilename();
+        }
 
         setupMenus();
         findTimeRulerLayer();
--- a/framework/SVFileReader.cpp	Mon Jun 11 14:40:56 2018 +0100
+++ b/framework/SVFileReader.cpp	Mon Jun 18 14:16:06 2018 +0100
@@ -103,7 +103,7 @@
 SVFileReader::~SVFileReader()
 {
     if (!m_awaitingDatasets.empty()) {
-        cerr << "WARNING: SV-XML: File ended with "
+        SVCERR << "WARNING: SV-XML: File ended with "
                   << m_awaitingDatasets.size() << " unfilled model dataset(s)"
                   << endl;
     }
@@ -118,7 +118,7 @@
     }
 
     if (!unaddedModels.empty()) {
-        cerr << "WARNING: SV-XML: File contained "
+        SVCERR << "WARNING: SV-XML: File contained "
                   << unaddedModels.size() << " unused models"
                   << endl;
         while (!unaddedModels.empty()) {
@@ -241,12 +241,12 @@
         ok = readParameter(attributes);
 
     } else {
-        cerr << "WARNING: SV-XML: Unexpected element \""
+        SVCERR << "WARNING: SV-XML: Unexpected element \""
                   << name << "\"" << endl;
     }
 
     if (!ok) {
-        cerr << "WARNING: SV-XML: Failed to completely process element \""
+        SVCERR << "WARNING: SV-XML: Failed to completely process element \""
                   << name << "\"" << endl;
     }
 
@@ -261,7 +261,7 @@
     if (m_inRow) {
         ok = readRowData(text);
         if (!ok) {
-            cerr << "WARNING: SV-XML: Failed to read row data content for row " << m_rowNumber << endl;
+            SVCERR << "WARNING: SV-XML: Failed to read row data content for row " << m_rowNumber << endl;
         }
     }
 
@@ -291,7 +291,7 @@
             }
 
             if (!foundInAwaiting) {
-                cerr << "WARNING: SV-XML: Dataset precedes model, or no model uses dataset" << endl;
+                SVCERR << "WARNING: SV-XML: Dataset precedes model, or no model uses dataset" << endl;
             }
         }
 
@@ -306,10 +306,10 @@
 
         if (!m_currentDerivedModel) {
             if (m_currentDerivedModelId < 0) {
-                cerr << "WARNING: SV-XML: Bad derivation output model id "
+                SVCERR << "WARNING: SV-XML: Bad derivation output model id "
                           << m_currentDerivedModelId << endl;
             } else if (haveModel(m_currentDerivedModelId)) {
-                cerr << "WARNING: SV-XML: Derivation has existing model "
+                SVCERR << "WARNING: SV-XML: Derivation has existing model "
                           << m_currentDerivedModelId
                           << " as target, not regenerating" << endl;
             } else {
@@ -368,7 +368,7 @@
         .arg(exception.message())
         .arg(exception.lineNumber())
         .arg(exception.columnNumber());
-    cerr << m_errorString << endl;
+    SVCERR << m_errorString << endl;
     return QXmlDefaultHandler::error(exception);
 }
 
@@ -380,7 +380,7 @@
         .arg(exception.message())
         .arg(exception.lineNumber())
         .arg(exception.columnNumber());
-    cerr << m_errorString << endl;
+    SVCERR << m_errorString << endl;
     return QXmlDefaultHandler::fatalError(exception);
 }
 
@@ -388,7 +388,7 @@
 #define READ_MANDATORY(TYPE, NAME, CONVERSION)                      \
     TYPE NAME = attributes.value(#NAME).trimmed().CONVERSION(&ok); \
     if (!ok) { \
-        cerr << "WARNING: SV-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << endl; \
+        SVCERR << "WARNING: SV-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << endl; \
         return false; \
     }
 
@@ -439,7 +439,7 @@
     READ_MANDATORY(int, id, toInt);
 
     if (haveModel(id)) {
-        cerr << "WARNING: SV-XML: Ignoring duplicate model id " << id
+        SVCERR << "WARNING: SV-XML: Ignoring duplicate model id " << id
                   << endl;
         return false;
     }
@@ -469,9 +469,9 @@
         file.waitForStatus();
 
         if (!file.isOK()) {
-            cerr << "SVFileReader::readModel: Failed to retrieve file \"" << path << "\" for wave file model: " << file.getErrorString() << endl;
+            SVCERR << "SVFileReader::readModel: Failed to retrieve file \"" << path << "\" for wave file model: " << file.getErrorString() << endl;
         } else if (!file.isAvailable()) {
-            cerr << "SVFileReader::readModel: Failed to retrieve file \"" << path << "\" for wave file model: Source unavailable" << endl;
+            SVCERR << "SVFileReader::readModel: Failed to retrieve file \"" << path << "\" for wave file model: Source unavailable" << endl;
         } else {
 
             file.waitForData();
@@ -494,7 +494,10 @@
             }
         }
 
-        if (!model) return false;
+        if (!model) {
+            m_document->setIncomplete(true);
+            return false;
+        }
 
         model->setObjectName(name);
         m_models[id] = model;
@@ -544,7 +547,7 @@
 
         } else {
 
-            cerr << "WARNING: SV-XML: Unexpected dense model dimension ("
+            SVCERR << "WARNING: SV-XML: Unexpected dense model dimension ("
                       << dimensions << ")" << endl;
         }
     } else if (type == "sparse") {
@@ -669,7 +672,7 @@
 
         } else {
 
-            cerr << "WARNING: SV-XML: Unexpected sparse model dimension ("
+            SVCERR << "WARNING: SV-XML: Unexpected sparse model dimension ("
                       << dimensions << ")" << endl;
         }
 
@@ -684,7 +687,7 @@
         if (m_models.find(reference) != m_models.end()) {
             refModel = m_models[reference];
         } else {
-            cerr << "WARNING: SV-XML: Unknown reference model id "
+            SVCERR << "WARNING: SV-XML: Unknown reference model id "
                       << reference << " in alignment model id " << id
                       << endl;
         }
@@ -692,7 +695,7 @@
         if (m_models.find(aligned) != m_models.end()) {
             alignedModel = m_models[aligned];
         } else {
-            cerr << "WARNING: SV-XML: Unknown aligned model id "
+            SVCERR << "WARNING: SV-XML: Unknown aligned model id "
                       << aligned << " in alignment model id " << id
                       << endl;
         }
@@ -700,7 +703,7 @@
         if (m_models.find(path) != m_models.end()) {
             pathModel = m_models[path];
         } else {
-            cerr << "WARNING: SV-XML: Unknown path model id "
+            SVCERR << "WARNING: SV-XML: Unknown path model id "
                       << path << " in alignment model id " << id
                       << endl;
         }
@@ -710,7 +713,7 @@
                 (refModel, alignedModel, 0, 0);
             PathModel *pm = dynamic_cast<PathModel *>(pathModel);
             if (!pm) {
-                cerr << "WARNING: SV-XML: Model id " << path
+                SVCERR << "WARNING: SV-XML: Model id " << path
                           << " referenced as path for alignment " << id
                           << " is not a path model" << endl;
             } else {
@@ -739,17 +742,17 @@
     m_currentPane = 0;
     
     if (type != "pane") {
-        cerr << "WARNING: SV-XML: Unexpected view type \""
+        SVCERR << "WARNING: SV-XML: Unexpected view type \""
                   << type << "\"" << endl;
         return false;
     }
 
     m_currentPane = m_paneCallback.addPane();
 
-    cerr << "SVFileReader::addPane: pane is " << m_currentPane << endl;
+    SVCERR << "SVFileReader::addPane: pane is " << m_currentPane << endl;
 
     if (!m_currentPane) {
-        cerr << "WARNING: SV-XML: Internal error: Failed to add pane!"
+        SVCERR << "WARNING: SV-XML: Internal error: Failed to add pane!"
                   << endl;
         return false;
     }
@@ -800,7 +803,7 @@
     id = attributes.value("id").trimmed().toInt(&ok);
 
     if (!ok) {
-        cerr << "WARNING: SV-XML: No layer id for layer of type \""
+        SVCERR << "WARNING: SV-XML: No layer id for layer of type \""
                   << type
                   << "\"" << endl;
         return false;
@@ -818,7 +821,7 @@
     if (m_inData) {
 
         if (m_layers.find(id) != m_layers.end()) {
-            cerr << "WARNING: SV-XML: Ignoring duplicate layer id " << id
+            SVCERR << "WARNING: SV-XML: Ignoring duplicate layer id " << id
                       << " in data section" << endl;
             return false;
         }
@@ -834,7 +837,7 @@
     } else {
 
         if (!m_currentPane) {
-            cerr << "WARNING: SV-XML: No current pane for layer " << id
+            SVCERR << "WARNING: SV-XML: No current pane for layer " << id
                       << " in view section" << endl;
             return false;
         }
@@ -844,7 +847,7 @@
             layer = m_layers[id];
         
         } else {
-            cerr << "WARNING: SV-XML: Layer id " << id 
+            SVCERR << "WARNING: SV-XML: Layer id " << id 
                       << " in view section has not been defined -- defining it here"
                       << endl;
 
@@ -859,7 +862,7 @@
     }
             
     if (!layer) {
-        cerr << "WARNING: SV-XML: Failed to add layer of type \""
+        SVCERR << "WARNING: SV-XML: Failed to add layer of type \""
                   << type
                   << "\"" << endl;
         return false;
@@ -882,7 +885,7 @@
                 Model *model = m_models[modelId];
                 m_document->setModel(layer, model);
             } else {
-                cerr << "WARNING: SV-XML: Unknown model id " << modelId
+                SVCERR << "WARNING: SV-XML: Unknown model id " << modelId
                           << " in layer definition" << endl;
                 if (!layer->canExistWithoutModel()) {
                     // Don't add a layer with an unknown model id
@@ -931,7 +934,7 @@
     READ_MANDATORY(int, dimensions, toInt);
     
     if (m_awaitingDatasets.find(id) == m_awaitingDatasets.end()) {
-        cerr << "WARNING: SV-XML: Unwanted dataset " << id << endl;
+        SVCERR << "WARNING: SV-XML: Unwanted dataset " << id << endl;
         return false;
     }
     
@@ -941,7 +944,7 @@
     if (haveModel(modelId)) {
         model = m_models[modelId];
     } else {
-        cerr << "WARNING: SV-XML: Internal error: Unknown model " << modelId
+        SVCERR << "WARNING: SV-XML: Internal error: Unknown model " << modelId
                   << " expecting dataset " << id << endl;
         return false;
     }
@@ -972,7 +975,7 @@
     }
 
     if (!good) {
-        cerr << "WARNING: SV-XML: Model id " << modelId << " has wrong number of dimensions or inappropriate type for " << dimensions << "-D dataset " << id << endl;
+        SVCERR << "WARNING: SV-XML: Model id " << modelId << " has wrong number of dimensions or inappropriate type for " << dimensions << "-D dataset " << id << endl;
         m_currentDataset = 0;
         return false;
     }
@@ -994,7 +997,7 @@
         (m_currentDataset);
 
     if (sodm) {
-//        cerr << "Current dataset is a sparse one dimensional model" << endl;
+//        SVCERR << "Current dataset is a sparse one dimensional model" << endl;
         QString label = attributes.value("label");
         sodm->addPoint(SparseOneDimensionalModel::Point(frame, label));
         return true;
@@ -1004,7 +1007,7 @@
         (m_currentDataset);
 
     if (stvm) {
-//        cerr << "Current dataset is a sparse time-value model" << endl;
+//        SVCERR << "Current dataset is a sparse time-value model" << endl;
         float value = 0.0;
         value = attributes.value("value").trimmed().toFloat(&ok);
         QString label = attributes.value("label");
@@ -1015,7 +1018,7 @@
     NoteModel *nm = dynamic_cast<NoteModel *>(m_currentDataset);
 
     if (nm) {
-//        cerr << "Current dataset is a note model" << endl;
+//        SVCERR << "Current dataset is a note model" << endl;
         float value = 0.0;
         value = attributes.value("value").trimmed().toFloat(&ok);
         int duration = 0;
@@ -1033,7 +1036,7 @@
     FlexiNoteModel *fnm = dynamic_cast<FlexiNoteModel *>(m_currentDataset);
 
     if (fnm) {
-//        cerr << "Current dataset is a flexinote model" << endl;
+//        SVCERR << "Current dataset is a flexinote model" << endl;
         float value = 0.0;
         value = attributes.value("value").trimmed().toFloat(&ok);
         int duration = 0;
@@ -1051,7 +1054,7 @@
     RegionModel *rm = dynamic_cast<RegionModel *>(m_currentDataset);
 
     if (rm) {
-//        cerr << "Current dataset is a region model" << endl;
+//        SVCERR << "Current dataset is a region model" << endl;
         float value = 0.0;
         value = attributes.value("value").trimmed().toFloat(&ok);
         int duration = 0;
@@ -1064,7 +1067,7 @@
     TextModel *tm = dynamic_cast<TextModel *>(m_currentDataset);
 
     if (tm) {
-//        cerr << "Current dataset is a text model" << endl;
+//        SVCERR << "Current dataset is a text model" << endl;
         float height = 0.0;
         height = attributes.value("height").trimmed().toFloat(&ok);
         QString label = attributes.value("label");
@@ -1076,7 +1079,7 @@
     PathModel *pm = dynamic_cast<PathModel *>(m_currentDataset);
 
     if (pm) {
-//        cerr << "Current dataset is a path model" << endl;
+//        SVCERR << "Current dataset is a path model" << endl;
         int mapframe = attributes.value("mapframe").trimmed().toInt(&ok);
 //        SVDEBUG << "SVFileReader::addPointToDataset: PathModel: frame = " << frame << ", mapframe = " << mapframe << ", ok = " << ok << endl;
         pm->addPoint(PathModel::Point(frame, mapframe));
@@ -1086,7 +1089,7 @@
     ImageModel *im = dynamic_cast<ImageModel *>(m_currentDataset);
 
     if (im) {
-//        cerr << "Current dataset is an image model" << endl;
+//        SVCERR << "Current dataset is an image model" << endl;
         QString image = attributes.value("image");
         QString label = attributes.value("label");
 //        SVDEBUG << "SVFileReader::addPointToDataset: ImageModel: frame = " << frame << ", image = " << image << ", label = " << label << ", ok = " << ok << endl;
@@ -1094,7 +1097,7 @@
         return ok;
     }
 
-    cerr << "WARNING: SV-XML: Point element found in non-point dataset" << endl;
+    SVCERR << "WARNING: SV-XML: Point element found in non-point dataset" << endl;
 
     return false;
 }
@@ -1111,7 +1114,7 @@
         bool ok = false;
         int n = attributes.value("number").trimmed().toInt(&ok);
         if (!ok) {
-            cerr << "WARNING: SV-XML: Missing or invalid bin number"
+            SVCERR << "WARNING: SV-XML: Missing or invalid bin number"
                       << endl;
             return false;
         }
@@ -1122,7 +1125,7 @@
         return true;
     }
 
-    cerr << "WARNING: SV-XML: Bin definition found in incompatible dataset" << endl;
+    SVCERR << "WARNING: SV-XML: Bin definition found in incompatible dataset" << endl;
 
     return false;
 }
@@ -1136,14 +1139,14 @@
     bool ok = false;
     m_rowNumber = attributes.value("n").trimmed().toInt(&ok);
     if (!ok) {
-        cerr << "WARNING: SV-XML: Missing or invalid row number"
+        SVCERR << "WARNING: SV-XML: Missing or invalid row number"
                   << endl;
         return false;
     }
     
     m_inRow = true;
 
-//    cerr << "SV-XML: In row " << m_rowNumber << endl;
+//    SVCERR << "SV-XML: In row " << m_rowNumber << endl;
     
     return true;
 }
@@ -1166,7 +1169,7 @@
 
             if (int(values.size()) == dtdm->getHeight()) {
                 if (!warned) {
-                    cerr << "WARNING: SV-XML: Too many y-bins in 3-D dataset row "
+                    SVCERR << "WARNING: SV-XML: Too many y-bins in 3-D dataset row "
                               << m_rowNumber << endl;
                     warned = true;
                 }
@@ -1175,7 +1178,7 @@
             bool ok;
             float value = i->toFloat(&ok);
             if (!ok) {
-                cerr << "WARNING: SV-XML: Bad floating-point value "
+                SVCERR << "WARNING: SV-XML: Bad floating-point value "
                           << i->toLocal8Bit().data()
                           << " in row data" << endl;
             } else {
@@ -1187,7 +1190,7 @@
         return true;
     }
 
-    cerr << "WARNING: SV-XML: Row data found in non-row dataset" << endl;
+    SVCERR << "WARNING: SV-XML: Row data found in non-row dataset" << endl;
 
     return false;
 }
@@ -1200,7 +1203,7 @@
     modelId = attributes.value("model").trimmed().toInt(&modelOk);
 
     if (!modelOk) {
-        cerr << "WARNING: SV-XML: No model id specified for derivation" << endl;
+        SVCERR << "WARNING: SV-XML: No model id specified for derivation" << endl;
         return false;
     }
 
@@ -1294,7 +1297,7 @@
     modelId = attributes.value("model").trimmed().toInt(&modelOk);
 
     if (!modelOk) {
-        cerr << "WARNING: SV-XML: No model id specified for play parameters" << endl;
+        SVCERR << "WARNING: SV-XML: No model id specified for play parameters" << endl;
         return false;
     }
 
@@ -1306,7 +1309,7 @@
             getPlayParameters(m_models[modelId]);
 
         if (!parameters) {
-            cerr << "WARNING: SV-XML: Play parameters for model "
+            SVCERR << "WARNING: SV-XML: Play parameters for model "
                       << modelId
                       << " not found - has model been added to document?"
                       << endl;
@@ -1327,11 +1330,11 @@
         
         m_currentPlayParameters = parameters;
 
-//        cerr << "Current play parameters for model: " << m_models[modelId] << ": " << m_currentPlayParameters << endl;
+//        SVCERR << "Current play parameters for model: " << m_models[modelId] << ": " << m_currentPlayParameters << endl;
 
     } else {
 
-        cerr << "WARNING: SV-XML: Unknown model " << modelId
+        SVCERR << "WARNING: SV-XML: Unknown model " << modelId
                   << " for play parameters" << endl;
         return false;
     }
@@ -1347,7 +1350,7 @@
     } else if (m_currentPlayParameters) {
         return readPluginForPlayback(attributes);
     } else {
-        cerr << "WARNING: SV-XML: Plugin found outside derivation or play parameters" << endl;
+        SVCERR << "WARNING: SV-XML: Plugin found outside derivation or play parameters" << endl;
         return false;
     }
 }
@@ -1394,7 +1397,7 @@
 SVFileReader::readTransform(const QXmlAttributes &attributes)
 {
     if (m_currentDerivedModelId < 0) {
-        cerr << "WARNING: SV-XML: Transform found outside derivation" << endl;
+        SVCERR << "WARNING: SV-XML: Transform found outside derivation" << endl;
         return false;
     }
 
@@ -1407,13 +1410,13 @@
 SVFileReader::readParameter(const QXmlAttributes &attributes)
 {
     if (m_currentDerivedModelId < 0) {
-        cerr << "WARNING: SV-XML: Parameter found outside derivation" << endl;
+        SVCERR << "WARNING: SV-XML: Parameter found outside derivation" << endl;
         return false;
     }
 
     QString name = attributes.value("name");
     if (name == "") {
-        cerr << "WARNING: SV-XML: Ignoring nameless transform parameter"
+        SVCERR << "WARNING: SV-XML: Ignoring nameless transform parameter"
                   << endl;
         return false;
     }
@@ -1444,7 +1447,7 @@
               << m_inLayer << ", layer " << m_currentLayer << endl;
 
     if (!m_inLayer) {
-        cerr << "WARNING: SV-XML: Measurement found outside layer" << endl;
+        SVCERR << "WARNING: SV-XML: Measurement found outside layer" << endl;
         return false;
     }