| 1901 | } |
| 1902 | |
| 1903 | void RenderingController::HandlePUT_mxnCamera(const httplib::Request& req, httplib::Response& res) const |
| 1904 | { |
| 1905 | const auto id = ReadRequiredPathParam(req, "id"); |
| 1906 | |
| 1907 | if (!IsValidMxNWindowId(id)) |
| 1908 | { |
| 1909 | const auto error = ErrorResponse::InvalidRequest( |
| 1910 | "Malformed MxN window id '" + id + "'. Expected pattern: <prefix>__<bare> with URL-segment-safe characters.", |
| 1911 | req.path); |
| 1912 | this->SendErrorResponse(res, 400, error); |
| 1913 | return; |
| 1914 | } |
| 1915 | |
| 1916 | if (req.body.empty()) |
| 1917 | { |
| 1918 | const auto error = ErrorResponse::InvalidRequest("Request body is required.", req.path); |
| 1919 | this->SendErrorResponse(res, 400, error); |
| 1920 | return; |
| 1921 | } |
| 1922 | |
| 1923 | nlohmann::json body; |
| 1924 | try |
| 1925 | { |
| 1926 | body = nlohmann::json::parse(req.body); |
| 1927 | } |
| 1928 | catch (const nlohmann::json::exception&) |
| 1929 | { |
| 1930 | const auto error = ErrorResponse::InvalidRequest("Invalid JSON body.", req.path); |
| 1931 | this->SendErrorResponse(res, 400, error); |
| 1932 | return; |
| 1933 | } |
| 1934 | |
| 1935 | // is3d hard-coded false for v2: the schema's view_direction enum has no |
| 1936 | // "3d" value, so by construction every MxN cell is 2D. The plugin's |
| 1937 | // V2_MXN_WINDOW_KIND constant pins this invariant at compile time and |
| 1938 | // its v3 migration checklist (QmitkRestApiBridgeBindings.cpp) lists this |
| 1939 | // handler as a required update site -- when a 3D MxN cell type is |
| 1940 | // introduced, derive `is3d` from the windows list provider's `kind` |
| 1941 | // for the addressed cell here before calling ParseCameraPatch. |
| 1942 | CameraPatch patch; |
| 1943 | if (const auto err = ParseCameraPatch(body, /*is3d=*/false, patch)) |
| 1944 | { |
| 1945 | const auto error = ErrorResponse::InvalidRequest(*err, req.path); |
| 1946 | this->SendErrorResponse(res, 400, error); |
| 1947 | return; |
| 1948 | } |
| 1949 | |
| 1950 | if (m_RenderWindowBridge == nullptr || !m_RenderWindowBridge->HasMxNCameraSetter()) |
| 1951 | { |
| 1952 | const auto error = ErrorResponse::RenderWindowNotAvailable(req.path); |
| 1953 | this->SendErrorResponse(res, 503, error); |
| 1954 | return; |
| 1955 | } |
| 1956 | |
| 1957 | try |
| 1958 | { |
| 1959 | m_RenderWindowBridge->SetMxNCamera(id, patch); |
| 1960 | res.status = 204; |