From f545eea5ed40534362e39680501b430f6019dbdb Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 9 May 2022 21:31:14 +0200 Subject: [PATCH] v7: created API to manage workspaces. Implements #1240 --- sdrbase/maincore.cpp | 2 + sdrbase/maincore.h | 30 + sdrbase/resources/webapi/doc/html2/index.html | 680 +++++++++++++++++- .../resources/webapi/doc/swagger/swagger.yaml | 31 + sdrbase/webapi/webapiadapter.cpp | 28 + sdrbase/webapi/webapiadapter.h | 8 + sdrbase/webapi/webapiadapterinterface.cpp | 1 + sdrbase/webapi/webapiadapterinterface.h | 29 + sdrbase/webapi/webapirequestmapper.cpp | 41 ++ sdrbase/webapi/webapirequestmapper.h | 2 + sdrgui/mainwindow.cpp | 10 + swagger/sdrangel/api/swagger/swagger.yaml | 31 + swagger/sdrangel/code/html2/index.html | 680 +++++++++++++++++- .../code/qt5/client/SWGWorkspaceApi.cpp | 136 ++++ .../code/qt5/client/SWGWorkspaceApi.h | 57 ++ 15 files changed, 1764 insertions(+), 2 deletions(-) create mode 100644 swagger/sdrangel/code/qt5/client/SWGWorkspaceApi.cpp create mode 100644 swagger/sdrangel/code/qt5/client/SWGWorkspaceApi.h diff --git a/sdrbase/maincore.cpp b/sdrbase/maincore.cpp index 363955e5f..47db34a50 100644 --- a/sdrbase/maincore.cpp +++ b/sdrbase/maincore.cpp @@ -38,6 +38,8 @@ MESSAGE_CLASS_DEFINITION(MainCore::MsgDeletePreset, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgLoadConfiguration, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgSaveConfiguration, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgDeleteConfiguration, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgAddWorkspace, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgDeleteEmptyWorkspaces, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgLoadFeatureSetPreset, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgSaveFeatureSetPreset, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgDeleteFeatureSetPreset, Message) diff --git a/sdrbase/maincore.h b/sdrbase/maincore.h index 464861f8e..0bf3324cc 100644 --- a/sdrbase/maincore.h +++ b/sdrbase/maincore.h @@ -230,6 +230,36 @@ public: { } }; + class SDRBASE_API MsgAddWorkspace : public Message { + MESSAGE_CLASS_DECLARATION + + public: + static MsgAddWorkspace* create() + { + return new MsgAddWorkspace(); + } + + private: + MsgAddWorkspace() : + Message() + { } + }; + + class SDRBASE_API MsgDeleteEmptyWorkspaces : public Message { + MESSAGE_CLASS_DECLARATION + + public: + static MsgDeleteEmptyWorkspaces* create() + { + return new MsgDeleteEmptyWorkspaces(); + } + + private: + MsgDeleteEmptyWorkspaces() : + Message() + { } + }; + class SDRBASE_API MsgLoadFeatureSetPreset : public Message { MESSAGE_CLASS_DECLARATION diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index 3a117e943..b685023c3 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -14754,6 +14754,13 @@ margin-bottom: 20px;
  • instanceSummary
  • + +
  • + instanceWorkspaceAdd +
  • +
  • + instanceWorkspacesDeleteEmpty +
  • @@ -55812,6 +55819,677 @@ except ApiException as e:
    +
    +

    Workspace

    +
    +
    +
    +

    instanceWorkspaceAdd

    +

    +
    +
    +
    +

    +

    Add new workspace

    +

    +
    +
    /sdrangel/workspace
    +

    +

    Usage and SDK Samples

    +

    + + +
    +
    +
    curl -X POST "http://localhost/sdrangel/workspace"
    +
    +
    +
    import SWGSDRangel.*;
    +import SWGSDRangel.auth.*;
    +import SWGSDRangel.model.*;
    +import SWGSDRangel.api.WorkspaceApi;
    +
    +import java.io.File;
    +import java.util.*;
    +
    +public class WorkspaceApiExample {
    +
    +    public static void main(String[] args) {
    +        
    +        WorkspaceApi apiInstance = new WorkspaceApi();
    +        try {
    +            SuccessResponse result = apiInstance.instanceWorkspaceAdd();
    +            System.out.println(result);
    +        } catch (ApiException e) {
    +            System.err.println("Exception when calling WorkspaceApi#instanceWorkspaceAdd");
    +            e.printStackTrace();
    +        }
    +    }
    +}
    +
    + +
    +
    import SWGSDRangel.api.WorkspaceApi;
    +
    +public class WorkspaceApiExample {
    +
    +    public static void main(String[] args) {
    +        WorkspaceApi apiInstance = new WorkspaceApi();
    +        try {
    +            SuccessResponse result = apiInstance.instanceWorkspaceAdd();
    +            System.out.println(result);
    +        } catch (ApiException e) {
    +            System.err.println("Exception when calling WorkspaceApi#instanceWorkspaceAdd");
    +            e.printStackTrace();
    +        }
    +    }
    +}
    +
    + +
    +
    
    +WorkspaceApi *apiInstance = [[WorkspaceApi alloc] init];
    +
    +[apiInstance instanceWorkspaceAddWithCompletionHandler: 
    +              ^(SuccessResponse output, NSError* error) {
    +                            if (output) {
    +                                NSLog(@"%@", output);
    +                            }
    +                            if (error) {
    +                                NSLog(@"Error: %@", error);
    +                            }
    +                        }];
    +
    +
    + +
    +
    var SdRangel = require('sd_rangel');
    +
    +var api = new SdRangel.WorkspaceApi()
    +
    +var callback = function(error, data, response) {
    +  if (error) {
    +    console.error(error);
    +  } else {
    +    console.log('API called successfully. Returned data: ' + data);
    +  }
    +};
    +api.instanceWorkspaceAdd(callback);
    +
    +
    + + +
    +
    using System;
    +using System.Diagnostics;
    +using SWGSDRangel.Api;
    +using SWGSDRangel.Client;
    +using SWGSDRangel.Model;
    +
    +namespace Example
    +{
    +    public class instanceWorkspaceAddExample
    +    {
    +        public void main()
    +        {
    +            
    +            var apiInstance = new WorkspaceApi();
    +
    +            try
    +            {
    +                SuccessResponse result = apiInstance.instanceWorkspaceAdd();
    +                Debug.WriteLine(result);
    +            }
    +            catch (Exception e)
    +            {
    +                Debug.Print("Exception when calling WorkspaceApi.instanceWorkspaceAdd: " + e.Message );
    +            }
    +        }
    +    }
    +}
    +
    +
    + +
    +
    <?php
    +require_once(__DIR__ . '/vendor/autoload.php');
    +
    +$api_instance = new Swagger\Client\Api\WorkspaceApi();
    +
    +try {
    +    $result = $api_instance->instanceWorkspaceAdd();
    +    print_r($result);
    +} catch (Exception $e) {
    +    echo 'Exception when calling WorkspaceApi->instanceWorkspaceAdd: ', $e->getMessage(), PHP_EOL;
    +}
    +?>
    +
    + +
    +
    use Data::Dumper;
    +use SWGSDRangel::Configuration;
    +use SWGSDRangel::WorkspaceApi;
    +
    +my $api_instance = SWGSDRangel::WorkspaceApi->new();
    +
    +eval { 
    +    my $result = $api_instance->instanceWorkspaceAdd();
    +    print Dumper($result);
    +};
    +if ($@) {
    +    warn "Exception when calling WorkspaceApi->instanceWorkspaceAdd: $@\n";
    +}
    +
    + +
    +
    from __future__ import print_statement
    +import time
    +import swagger_sdrangel
    +from swagger_sdrangel.rest import ApiException
    +from pprint import pprint
    +
    +# create an instance of the API class
    +api_instance = swagger_sdrangel.WorkspaceApi()
    +
    +try: 
    +    api_response = api_instance.instance_workspace_add()
    +    pprint(api_response)
    +except ApiException as e:
    +    print("Exception when calling WorkspaceApi->instanceWorkspaceAdd: %s\n" % e)
    +
    +
    + +

    Parameters

    + + + + + + +

    Responses

    +

    Status: 202 -

    + + + +
    +
    +
    + +
    + +
    +
    + +

    Status: 500 - Error

    + + + +
    +
    +
    + +
    + +
    +
    + +

    Status: 501 - Function not implemented

    + + + +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +

    instanceWorkspacesDeleteEmpty

    +

    +
    +
    +
    +

    +

    Delete empty workspaces

    +

    +
    +
    /sdrangel/workspace
    +

    +

    Usage and SDK Samples

    +

    + + +
    +
    +
    curl -X DELETE "http://localhost/sdrangel/workspace"
    +
    +
    +
    import SWGSDRangel.*;
    +import SWGSDRangel.auth.*;
    +import SWGSDRangel.model.*;
    +import SWGSDRangel.api.WorkspaceApi;
    +
    +import java.io.File;
    +import java.util.*;
    +
    +public class WorkspaceApiExample {
    +
    +    public static void main(String[] args) {
    +        
    +        WorkspaceApi apiInstance = new WorkspaceApi();
    +        try {
    +            SuccessResponse result = apiInstance.instanceWorkspacesDeleteEmpty();
    +            System.out.println(result);
    +        } catch (ApiException e) {
    +            System.err.println("Exception when calling WorkspaceApi#instanceWorkspacesDeleteEmpty");
    +            e.printStackTrace();
    +        }
    +    }
    +}
    +
    + +
    +
    import SWGSDRangel.api.WorkspaceApi;
    +
    +public class WorkspaceApiExample {
    +
    +    public static void main(String[] args) {
    +        WorkspaceApi apiInstance = new WorkspaceApi();
    +        try {
    +            SuccessResponse result = apiInstance.instanceWorkspacesDeleteEmpty();
    +            System.out.println(result);
    +        } catch (ApiException e) {
    +            System.err.println("Exception when calling WorkspaceApi#instanceWorkspacesDeleteEmpty");
    +            e.printStackTrace();
    +        }
    +    }
    +}
    +
    + +
    +
    
    +WorkspaceApi *apiInstance = [[WorkspaceApi alloc] init];
    +
    +[apiInstance instanceWorkspacesDeleteEmptyWithCompletionHandler: 
    +              ^(SuccessResponse output, NSError* error) {
    +                            if (output) {
    +                                NSLog(@"%@", output);
    +                            }
    +                            if (error) {
    +                                NSLog(@"Error: %@", error);
    +                            }
    +                        }];
    +
    +
    + +
    +
    var SdRangel = require('sd_rangel');
    +
    +var api = new SdRangel.WorkspaceApi()
    +
    +var callback = function(error, data, response) {
    +  if (error) {
    +    console.error(error);
    +  } else {
    +    console.log('API called successfully. Returned data: ' + data);
    +  }
    +};
    +api.instanceWorkspacesDeleteEmpty(callback);
    +
    +
    + + +
    +
    using System;
    +using System.Diagnostics;
    +using SWGSDRangel.Api;
    +using SWGSDRangel.Client;
    +using SWGSDRangel.Model;
    +
    +namespace Example
    +{
    +    public class instanceWorkspacesDeleteEmptyExample
    +    {
    +        public void main()
    +        {
    +            
    +            var apiInstance = new WorkspaceApi();
    +
    +            try
    +            {
    +                SuccessResponse result = apiInstance.instanceWorkspacesDeleteEmpty();
    +                Debug.WriteLine(result);
    +            }
    +            catch (Exception e)
    +            {
    +                Debug.Print("Exception when calling WorkspaceApi.instanceWorkspacesDeleteEmpty: " + e.Message );
    +            }
    +        }
    +    }
    +}
    +
    +
    + +
    +
    <?php
    +require_once(__DIR__ . '/vendor/autoload.php');
    +
    +$api_instance = new Swagger\Client\Api\WorkspaceApi();
    +
    +try {
    +    $result = $api_instance->instanceWorkspacesDeleteEmpty();
    +    print_r($result);
    +} catch (Exception $e) {
    +    echo 'Exception when calling WorkspaceApi->instanceWorkspacesDeleteEmpty: ', $e->getMessage(), PHP_EOL;
    +}
    +?>
    +
    + +
    +
    use Data::Dumper;
    +use SWGSDRangel::Configuration;
    +use SWGSDRangel::WorkspaceApi;
    +
    +my $api_instance = SWGSDRangel::WorkspaceApi->new();
    +
    +eval { 
    +    my $result = $api_instance->instanceWorkspacesDeleteEmpty();
    +    print Dumper($result);
    +};
    +if ($@) {
    +    warn "Exception when calling WorkspaceApi->instanceWorkspacesDeleteEmpty: $@\n";
    +}
    +
    + +
    +
    from __future__ import print_statement
    +import time
    +import swagger_sdrangel
    +from swagger_sdrangel.rest import ApiException
    +from pprint import pprint
    +
    +# create an instance of the API class
    +api_instance = swagger_sdrangel.WorkspaceApi()
    +
    +try: 
    +    api_response = api_instance.instance_workspaces_delete_empty()
    +    pprint(api_response)
    +except ApiException as e:
    +    print("Exception when calling WorkspaceApi->instanceWorkspacesDeleteEmpty: %s\n" % e)
    +
    +
    + +

    Parameters

    + + + + + + +

    Responses

    +

    Status: 202 -

    + + + +
    +
    +
    + +
    + +
    +
    + +

    Status: 500 - Error

    + + + +
    +
    +
    + +
    + +
    +
    + +

    Status: 501 - Function not implemented

    + + + +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    diff --git a/sdrbase/resources/webapi/doc/swagger/swagger.yaml b/sdrbase/resources/webapi/doc/swagger/swagger.yaml index f03bcf827..d6b6fda7e 100644 --- a/sdrbase/resources/webapi/doc/swagger/swagger.yaml +++ b/sdrbase/resources/webapi/doc/swagger/swagger.yaml @@ -1282,6 +1282,37 @@ paths: "501": $ref: "#/responses/Response_501" + /sdrangel/workspace: + x-swagger-router-controller: instance + post: + description: Add new workspace + operationId: InstanceWorkspaceAdd + tags: + - Workspace + responses: + "202": + descriptions: Successful sending of the message + schema: + $ref: "#/definitions/SuccessResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + delete: + description: Delete empty workspaces + operationId: InstanceWorkspacesDeleteEmpty + tags: + - Workspace + responses: + "202": + descriptions: Successful sending of the message + schema: + $ref: "#/definitions/SuccessResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + /sdrangel/deviceset: x-swagger-router-controller: instance post: diff --git a/sdrbase/webapi/webapiadapter.cpp b/sdrbase/webapi/webapiadapter.cpp index 2d4ded98d..d9804f000 100644 --- a/sdrbase/webapi/webapiadapter.cpp +++ b/sdrbase/webapi/webapiadapter.cpp @@ -2077,6 +2077,34 @@ int WebAPIAdapter::instanceDeviceSetDelete( } } +int WebAPIAdapter::instanceWorkspacePost( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + (void) error; + MainCore::MsgAddWorkspace *msg = MainCore::MsgAddWorkspace::create(); + m_mainCore->m_mainMessageQueue->push(msg); + + response.init(); + *response.getMessage() = QString("Message to add a new workspace (MsgAddWorkspace) was submitted successfully"); + + return 202; +} + +int WebAPIAdapter::instanceWorkspaceDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + (void) error; + MainCore::MsgDeleteEmptyWorkspaces *msg = MainCore::MsgDeleteEmptyWorkspaces::create(); + m_mainCore->m_mainMessageQueue->push(msg); + + response.init(); + *response.getMessage() = QString("Message to delete empty workspaces (MsgDeleteEmptyWorkspaces) was submitted successfully"); + + return 202; +} + int WebAPIAdapter::devicesetGet( int deviceSetIndex, SWGSDRangel::SWGDeviceSet& response, diff --git a/sdrbase/webapi/webapiadapter.h b/sdrbase/webapi/webapiadapter.h index 212a9beda..e90d3416a 100644 --- a/sdrbase/webapi/webapiadapter.h +++ b/sdrbase/webapi/webapiadapter.h @@ -276,6 +276,14 @@ public: SWGSDRangel::SWGSuccessResponse& response, SWGSDRangel::SWGErrorResponse& error); + virtual int instanceWorkspacePost( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int instanceWorkspaceDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetGet( int deviceSetIndex, SWGSDRangel::SWGDeviceSet& response, diff --git a/sdrbase/webapi/webapiadapterinterface.cpp b/sdrbase/webapi/webapiadapterinterface.cpp index f0deeab98..5aa38447a 100644 --- a/sdrbase/webapi/webapiadapterinterface.cpp +++ b/sdrbase/webapi/webapiadapterinterface.cpp @@ -49,6 +49,7 @@ QString WebAPIAdapterInterface::instanceFeaturePresetsURL = "/sdrangel/featurepr QString WebAPIAdapterInterface::instanceFeaturePresetURL = "/sdrangel/featurepreset"; QString WebAPIAdapterInterface::instanceDeviceSetsURL = "/sdrangel/devicesets"; QString WebAPIAdapterInterface::instanceDeviceSetURL = "/sdrangel/deviceset"; +QString WebAPIAdapterInterface::instanceWorkspaceURL = "/sdrangel/workspace"; QString WebAPIAdapterInterface::featuresetURL("/sdrangel/featureset"); QString WebAPIAdapterInterface::featuresetFeatureURL("/sdrangel/featureset/feature"); QString WebAPIAdapterInterface::featuresetPresetURL("/sdrangel/featureset/preset"); diff --git a/sdrbase/webapi/webapiadapterinterface.h b/sdrbase/webapi/webapiadapterinterface.h index 54a53d4a2..11c4cd31f 100644 --- a/sdrbase/webapi/webapiadapterinterface.h +++ b/sdrbase/webapi/webapiadapterinterface.h @@ -868,6 +868,34 @@ public: return 501; } + /** + * Handler of /sdrangel/workspace (POST) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int instanceWorkspacePost( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) + { + (void) response; + error.init(); + *error.getMessage() = QString("Function not implemented"); + return 501; + } + + /** + * Handler of /sdrangel/workspace (DELETE) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int instanceWorkspaceDelete( + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) + { + (void) response; + error.init(); + *error.getMessage() = QString("Function not implemented"); + return 501; + } + /** * Handler of /sdrangel/deviceset (POST) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels * returns the Http status code (default 501: not implemented) @@ -1651,6 +1679,7 @@ public: static QString instanceFeaturePresetURL; static QString instanceDeviceSetsURL; static QString instanceDeviceSetURL; + static QString instanceWorkspaceURL; static QString featuresetURL; static QString featuresetFeatureURL; static QString featuresetPresetURL; diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp index e51727673..e2f7566ec 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -174,6 +174,8 @@ void WebAPIRequestMapper::service(qtwebapp::HttpRequest& request, qtwebapp::Http instanceDeviceSetsService(request, response); } else if (path == WebAPIAdapterInterface::instanceDeviceSetURL) { instanceDeviceSetService(request, response); + } else if (path == WebAPIAdapterInterface::instanceWorkspaceURL) { + instanceWorkspaceService(request, response); } else if (path == WebAPIAdapterInterface::featuresetURL) { featuresetService(request, response); } else if (path == WebAPIAdapterInterface::featuresetFeatureURL) { @@ -1991,6 +1993,45 @@ void WebAPIRequestMapper::instanceDeviceSetService(qtwebapp::HttpRequest& reques } } +void WebAPIRequestMapper::instanceWorkspaceService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) +{ + SWGSDRangel::SWGErrorResponse errorResponse; + response.setHeader("Content-Type", "application/json"); + response.setHeader("Access-Control-Allow-Origin", "*"); + + if (request.getMethod() == "POST") + { + SWGSDRangel::SWGSuccessResponse normalResponse; + int status = m_adapter->instanceWorkspacePost(normalResponse, errorResponse); + response.setStatus(status); + + if (status/100 == 2) { + response.write(normalResponse.asJson().toUtf8()); + } else { + response.write(errorResponse.asJson().toUtf8()); + } + } + else if (request.getMethod() == "DELETE") + { + SWGSDRangel::SWGSuccessResponse normalResponse; + int status = m_adapter->instanceWorkspaceDelete(normalResponse, errorResponse); + response.setStatus(status); + + if (status/100 == 2) { + response.write(normalResponse.asJson().toUtf8()); + } else { + response.write(errorResponse.asJson().toUtf8()); + } + } + else + { + response.setStatus(405,"Invalid HTTP method"); + errorResponse.init(); + *errorResponse.getMessage() = "Invalid HTTP method"; + response.write(errorResponse.asJson().toUtf8()); + } +} + void WebAPIRequestMapper::devicesetService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h index 3e9c37b83..3921a5ad4 100644 --- a/sdrbase/webapi/webapirequestmapper.h +++ b/sdrbase/webapi/webapirequestmapper.h @@ -85,6 +85,7 @@ private: void instanceFeaturePresetService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void instanceDeviceSetsService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void instanceDeviceSetService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); + void instanceWorkspaceService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetFocusService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); @@ -112,6 +113,7 @@ private: void featuresetFeatureReportService(const std::string& featureIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void featuresetFeatureActionsService(const std::string& featureIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); + bool validatePresetTransfer(SWGSDRangel::SWGPresetTransfer& presetTransfer); bool validatePresetIdentifer(SWGSDRangel::SWGPresetIdentifier& presetIdentifier); bool validatePresetExport(SWGSDRangel::SWGPresetExport& presetExport); diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index a3c8a54a6..dcdb11c3f 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -1621,6 +1621,16 @@ bool MainWindow::handleMessage(const Message& cmd) m_mainCore->m_settings.deleteConfiguration(configurationToDelete); return true; } + else if (MainCore::MsgDeleteEmptyWorkspaces::match(cmd)) + { + removeEmptyWorkspaces(); + return true; + } + else if (MainCore::MsgAddWorkspace::match(cmd)) + { + addWorkspace(); + return true; + } else if (MainCore::MsgDeleteFeatureSetPreset::match(cmd)) { MainCore::MsgDeleteFeatureSetPreset& notif = (MainCore::MsgDeleteFeatureSetPreset&) cmd; diff --git a/swagger/sdrangel/api/swagger/swagger.yaml b/swagger/sdrangel/api/swagger/swagger.yaml index ea129fa44..cbb350a9b 100644 --- a/swagger/sdrangel/api/swagger/swagger.yaml +++ b/swagger/sdrangel/api/swagger/swagger.yaml @@ -1282,6 +1282,37 @@ paths: "501": $ref: "#/responses/Response_501" + /sdrangel/workspace: + x-swagger-router-controller: instance + post: + description: Add new workspace + operationId: InstanceWorkspaceAdd + tags: + - Workspace + responses: + "202": + descriptions: Successful sending of the message + schema: + $ref: "#/definitions/SuccessResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + delete: + description: Delete empty workspaces + operationId: InstanceWorkspacesDeleteEmpty + tags: + - Workspace + responses: + "202": + descriptions: Successful sending of the message + schema: + $ref: "#/definitions/SuccessResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + /sdrangel/deviceset: x-swagger-router-controller: instance post: diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index 3a117e943..b685023c3 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -14754,6 +14754,13 @@ margin-bottom: 20px;
  • instanceSummary
  • + +
  • + instanceWorkspaceAdd +
  • +
  • + instanceWorkspacesDeleteEmpty +
  • @@ -55812,6 +55819,677 @@ except ApiException as e:
    +
    +

    Workspace

    +
    +
    +
    +

    instanceWorkspaceAdd

    +

    +
    +
    +
    +

    +

    Add new workspace

    +

    +
    +
    /sdrangel/workspace
    +

    +

    Usage and SDK Samples

    +

    + + +
    +
    +
    curl -X POST "http://localhost/sdrangel/workspace"
    +
    +
    +
    import SWGSDRangel.*;
    +import SWGSDRangel.auth.*;
    +import SWGSDRangel.model.*;
    +import SWGSDRangel.api.WorkspaceApi;
    +
    +import java.io.File;
    +import java.util.*;
    +
    +public class WorkspaceApiExample {
    +
    +    public static void main(String[] args) {
    +        
    +        WorkspaceApi apiInstance = new WorkspaceApi();
    +        try {
    +            SuccessResponse result = apiInstance.instanceWorkspaceAdd();
    +            System.out.println(result);
    +        } catch (ApiException e) {
    +            System.err.println("Exception when calling WorkspaceApi#instanceWorkspaceAdd");
    +            e.printStackTrace();
    +        }
    +    }
    +}
    +
    + +
    +
    import SWGSDRangel.api.WorkspaceApi;
    +
    +public class WorkspaceApiExample {
    +
    +    public static void main(String[] args) {
    +        WorkspaceApi apiInstance = new WorkspaceApi();
    +        try {
    +            SuccessResponse result = apiInstance.instanceWorkspaceAdd();
    +            System.out.println(result);
    +        } catch (ApiException e) {
    +            System.err.println("Exception when calling WorkspaceApi#instanceWorkspaceAdd");
    +            e.printStackTrace();
    +        }
    +    }
    +}
    +
    + +
    +
    
    +WorkspaceApi *apiInstance = [[WorkspaceApi alloc] init];
    +
    +[apiInstance instanceWorkspaceAddWithCompletionHandler: 
    +              ^(SuccessResponse output, NSError* error) {
    +                            if (output) {
    +                                NSLog(@"%@", output);
    +                            }
    +                            if (error) {
    +                                NSLog(@"Error: %@", error);
    +                            }
    +                        }];
    +
    +
    + +
    +
    var SdRangel = require('sd_rangel');
    +
    +var api = new SdRangel.WorkspaceApi()
    +
    +var callback = function(error, data, response) {
    +  if (error) {
    +    console.error(error);
    +  } else {
    +    console.log('API called successfully. Returned data: ' + data);
    +  }
    +};
    +api.instanceWorkspaceAdd(callback);
    +
    +
    + + +
    +
    using System;
    +using System.Diagnostics;
    +using SWGSDRangel.Api;
    +using SWGSDRangel.Client;
    +using SWGSDRangel.Model;
    +
    +namespace Example
    +{
    +    public class instanceWorkspaceAddExample
    +    {
    +        public void main()
    +        {
    +            
    +            var apiInstance = new WorkspaceApi();
    +
    +            try
    +            {
    +                SuccessResponse result = apiInstance.instanceWorkspaceAdd();
    +                Debug.WriteLine(result);
    +            }
    +            catch (Exception e)
    +            {
    +                Debug.Print("Exception when calling WorkspaceApi.instanceWorkspaceAdd: " + e.Message );
    +            }
    +        }
    +    }
    +}
    +
    +
    + +
    +
    <?php
    +require_once(__DIR__ . '/vendor/autoload.php');
    +
    +$api_instance = new Swagger\Client\Api\WorkspaceApi();
    +
    +try {
    +    $result = $api_instance->instanceWorkspaceAdd();
    +    print_r($result);
    +} catch (Exception $e) {
    +    echo 'Exception when calling WorkspaceApi->instanceWorkspaceAdd: ', $e->getMessage(), PHP_EOL;
    +}
    +?>
    +
    + +
    +
    use Data::Dumper;
    +use SWGSDRangel::Configuration;
    +use SWGSDRangel::WorkspaceApi;
    +
    +my $api_instance = SWGSDRangel::WorkspaceApi->new();
    +
    +eval { 
    +    my $result = $api_instance->instanceWorkspaceAdd();
    +    print Dumper($result);
    +};
    +if ($@) {
    +    warn "Exception when calling WorkspaceApi->instanceWorkspaceAdd: $@\n";
    +}
    +
    + +
    +
    from __future__ import print_statement
    +import time
    +import swagger_sdrangel
    +from swagger_sdrangel.rest import ApiException
    +from pprint import pprint
    +
    +# create an instance of the API class
    +api_instance = swagger_sdrangel.WorkspaceApi()
    +
    +try: 
    +    api_response = api_instance.instance_workspace_add()
    +    pprint(api_response)
    +except ApiException as e:
    +    print("Exception when calling WorkspaceApi->instanceWorkspaceAdd: %s\n" % e)
    +
    +
    + +

    Parameters

    + + + + + + +

    Responses

    +

    Status: 202 -

    + + + +
    +
    +
    + +
    + +
    +
    + +

    Status: 500 - Error

    + + + +
    +
    +
    + +
    + +
    +
    + +

    Status: 501 - Function not implemented

    + + + +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +

    instanceWorkspacesDeleteEmpty

    +

    +
    +
    +
    +

    +

    Delete empty workspaces

    +

    +
    +
    /sdrangel/workspace
    +

    +

    Usage and SDK Samples

    +

    + + +
    +
    +
    curl -X DELETE "http://localhost/sdrangel/workspace"
    +
    +
    +
    import SWGSDRangel.*;
    +import SWGSDRangel.auth.*;
    +import SWGSDRangel.model.*;
    +import SWGSDRangel.api.WorkspaceApi;
    +
    +import java.io.File;
    +import java.util.*;
    +
    +public class WorkspaceApiExample {
    +
    +    public static void main(String[] args) {
    +        
    +        WorkspaceApi apiInstance = new WorkspaceApi();
    +        try {
    +            SuccessResponse result = apiInstance.instanceWorkspacesDeleteEmpty();
    +            System.out.println(result);
    +        } catch (ApiException e) {
    +            System.err.println("Exception when calling WorkspaceApi#instanceWorkspacesDeleteEmpty");
    +            e.printStackTrace();
    +        }
    +    }
    +}
    +
    + +
    +
    import SWGSDRangel.api.WorkspaceApi;
    +
    +public class WorkspaceApiExample {
    +
    +    public static void main(String[] args) {
    +        WorkspaceApi apiInstance = new WorkspaceApi();
    +        try {
    +            SuccessResponse result = apiInstance.instanceWorkspacesDeleteEmpty();
    +            System.out.println(result);
    +        } catch (ApiException e) {
    +            System.err.println("Exception when calling WorkspaceApi#instanceWorkspacesDeleteEmpty");
    +            e.printStackTrace();
    +        }
    +    }
    +}
    +
    + +
    +
    
    +WorkspaceApi *apiInstance = [[WorkspaceApi alloc] init];
    +
    +[apiInstance instanceWorkspacesDeleteEmptyWithCompletionHandler: 
    +              ^(SuccessResponse output, NSError* error) {
    +                            if (output) {
    +                                NSLog(@"%@", output);
    +                            }
    +                            if (error) {
    +                                NSLog(@"Error: %@", error);
    +                            }
    +                        }];
    +
    +
    + +
    +
    var SdRangel = require('sd_rangel');
    +
    +var api = new SdRangel.WorkspaceApi()
    +
    +var callback = function(error, data, response) {
    +  if (error) {
    +    console.error(error);
    +  } else {
    +    console.log('API called successfully. Returned data: ' + data);
    +  }
    +};
    +api.instanceWorkspacesDeleteEmpty(callback);
    +
    +
    + + +
    +
    using System;
    +using System.Diagnostics;
    +using SWGSDRangel.Api;
    +using SWGSDRangel.Client;
    +using SWGSDRangel.Model;
    +
    +namespace Example
    +{
    +    public class instanceWorkspacesDeleteEmptyExample
    +    {
    +        public void main()
    +        {
    +            
    +            var apiInstance = new WorkspaceApi();
    +
    +            try
    +            {
    +                SuccessResponse result = apiInstance.instanceWorkspacesDeleteEmpty();
    +                Debug.WriteLine(result);
    +            }
    +            catch (Exception e)
    +            {
    +                Debug.Print("Exception when calling WorkspaceApi.instanceWorkspacesDeleteEmpty: " + e.Message );
    +            }
    +        }
    +    }
    +}
    +
    +
    + +
    +
    <?php
    +require_once(__DIR__ . '/vendor/autoload.php');
    +
    +$api_instance = new Swagger\Client\Api\WorkspaceApi();
    +
    +try {
    +    $result = $api_instance->instanceWorkspacesDeleteEmpty();
    +    print_r($result);
    +} catch (Exception $e) {
    +    echo 'Exception when calling WorkspaceApi->instanceWorkspacesDeleteEmpty: ', $e->getMessage(), PHP_EOL;
    +}
    +?>
    +
    + +
    +
    use Data::Dumper;
    +use SWGSDRangel::Configuration;
    +use SWGSDRangel::WorkspaceApi;
    +
    +my $api_instance = SWGSDRangel::WorkspaceApi->new();
    +
    +eval { 
    +    my $result = $api_instance->instanceWorkspacesDeleteEmpty();
    +    print Dumper($result);
    +};
    +if ($@) {
    +    warn "Exception when calling WorkspaceApi->instanceWorkspacesDeleteEmpty: $@\n";
    +}
    +
    + +
    +
    from __future__ import print_statement
    +import time
    +import swagger_sdrangel
    +from swagger_sdrangel.rest import ApiException
    +from pprint import pprint
    +
    +# create an instance of the API class
    +api_instance = swagger_sdrangel.WorkspaceApi()
    +
    +try: 
    +    api_response = api_instance.instance_workspaces_delete_empty()
    +    pprint(api_response)
    +except ApiException as e:
    +    print("Exception when calling WorkspaceApi->instanceWorkspacesDeleteEmpty: %s\n" % e)
    +
    +
    + +

    Parameters

    + + + + + + +

    Responses

    +

    Status: 202 -

    + + + +
    +
    +
    + +
    + +
    +
    + +

    Status: 500 - Error

    + + + +
    +
    +
    + +
    + +
    +
    + +

    Status: 501 - Function not implemented

    + + + +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    diff --git a/swagger/sdrangel/code/qt5/client/SWGWorkspaceApi.cpp b/swagger/sdrangel/code/qt5/client/SWGWorkspaceApi.cpp new file mode 100644 index 000000000..4c4333f6d --- /dev/null +++ b/swagger/sdrangel/code/qt5/client/SWGWorkspaceApi.cpp @@ -0,0 +1,136 @@ +/** + * SDRangel + * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- + * + * OpenAPI spec version: 6.0.0 + * Contact: f4exb06@gmail.com + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +#include "SWGWorkspaceApi.h" +#include "SWGHelpers.h" +#include "SWGModelFactory.h" + +#include +#include + +namespace SWGSDRangel { + +SWGWorkspaceApi::SWGWorkspaceApi() {} + +SWGWorkspaceApi::~SWGWorkspaceApi() {} + +SWGWorkspaceApi::SWGWorkspaceApi(QString host, QString basePath) { + this->host = host; + this->basePath = basePath; +} + +void +SWGWorkspaceApi::instanceWorkspaceAdd() { + QString fullPath; + fullPath.append(this->host).append(this->basePath).append("/sdrangel/workspace"); + + + + SWGHttpRequestWorker *worker = new SWGHttpRequestWorker(); + SWGHttpRequestInput input(fullPath, "POST"); + + + + + + foreach(QString key, this->defaultHeaders.keys()) { + input.headers.insert(key, this->defaultHeaders.value(key)); + } + + connect(worker, + &SWGHttpRequestWorker::on_execution_finished, + this, + &SWGWorkspaceApi::instanceWorkspaceAddCallback); + + worker->execute(&input); +} + +void +SWGWorkspaceApi::instanceWorkspaceAddCallback(SWGHttpRequestWorker * worker) { + QString msg; + QString error_str = worker->error_str; + QNetworkReply::NetworkError error_type = worker->error_type; + + if (worker->error_type == QNetworkReply::NoError) { + msg = QString("Success! %1 bytes").arg(worker->response.length()); + } + else { + msg = "Error: " + worker->error_str; + } + + + QString json(worker->response); + SWGSuccessResponse* output = static_cast(create(json, QString("SWGSuccessResponse"))); + worker->deleteLater(); + + if (worker->error_type == QNetworkReply::NoError) { + emit instanceWorkspaceAddSignal(output); + } else { + emit instanceWorkspaceAddSignalE(output, error_type, error_str); + emit instanceWorkspaceAddSignalEFull(worker, error_type, error_str); + } +} + +void +SWGWorkspaceApi::instanceWorkspacesDeleteEmpty() { + QString fullPath; + fullPath.append(this->host).append(this->basePath).append("/sdrangel/workspace"); + + + + SWGHttpRequestWorker *worker = new SWGHttpRequestWorker(); + SWGHttpRequestInput input(fullPath, "DELETE"); + + + + + + foreach(QString key, this->defaultHeaders.keys()) { + input.headers.insert(key, this->defaultHeaders.value(key)); + } + + connect(worker, + &SWGHttpRequestWorker::on_execution_finished, + this, + &SWGWorkspaceApi::instanceWorkspacesDeleteEmptyCallback); + + worker->execute(&input); +} + +void +SWGWorkspaceApi::instanceWorkspacesDeleteEmptyCallback(SWGHttpRequestWorker * worker) { + QString msg; + QString error_str = worker->error_str; + QNetworkReply::NetworkError error_type = worker->error_type; + + if (worker->error_type == QNetworkReply::NoError) { + msg = QString("Success! %1 bytes").arg(worker->response.length()); + } + else { + msg = "Error: " + worker->error_str; + } + + + QString json(worker->response); + SWGSuccessResponse* output = static_cast(create(json, QString("SWGSuccessResponse"))); + worker->deleteLater(); + + if (worker->error_type == QNetworkReply::NoError) { + emit instanceWorkspacesDeleteEmptySignal(output); + } else { + emit instanceWorkspacesDeleteEmptySignalE(output, error_type, error_str); + emit instanceWorkspacesDeleteEmptySignalEFull(worker, error_type, error_str); + } +} + + +} diff --git a/swagger/sdrangel/code/qt5/client/SWGWorkspaceApi.h b/swagger/sdrangel/code/qt5/client/SWGWorkspaceApi.h new file mode 100644 index 000000000..5d1a5b371 --- /dev/null +++ b/swagger/sdrangel/code/qt5/client/SWGWorkspaceApi.h @@ -0,0 +1,57 @@ +/** + * SDRangel + * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- + * + * OpenAPI spec version: 6.0.0 + * Contact: f4exb06@gmail.com + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +#ifndef _SWG_SWGWorkspaceApi_H_ +#define _SWG_SWGWorkspaceApi_H_ + +#include "SWGHttpRequest.h" + +#include "SWGErrorResponse.h" +#include "SWGSuccessResponse.h" + +#include + +namespace SWGSDRangel { + +class SWGWorkspaceApi: public QObject { + Q_OBJECT + +public: + SWGWorkspaceApi(); + SWGWorkspaceApi(QString host, QString basePath); + ~SWGWorkspaceApi(); + + QString host; + QString basePath; + QMap defaultHeaders; + + void instanceWorkspaceAdd(); + void instanceWorkspacesDeleteEmpty(); + +private: + void instanceWorkspaceAddCallback (SWGHttpRequestWorker * worker); + void instanceWorkspacesDeleteEmptyCallback (SWGHttpRequestWorker * worker); + +signals: + void instanceWorkspaceAddSignal(SWGSuccessResponse* summary); + void instanceWorkspacesDeleteEmptySignal(SWGSuccessResponse* summary); + + void instanceWorkspaceAddSignalE(SWGSuccessResponse* summary, QNetworkReply::NetworkError error_type, QString& error_str); + void instanceWorkspacesDeleteEmptySignalE(SWGSuccessResponse* summary, QNetworkReply::NetworkError error_type, QString& error_str); + + void instanceWorkspaceAddSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); + void instanceWorkspacesDeleteEmptySignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); + +}; + +} +#endif