Show a patch.

GET /api/1.1/patches/16658/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 16658,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/16658/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/16658/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20220715191400.890976-4-utkarsh02t@gmail.com>",
    "date": "2022-07-15T19:13:52",
    "name": "[libcamera-devel,03/11] qcam: Add GUI way to change control values",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "89b840516993228a85b35e7ec40b12f57fe64061",
    "submitter": {
        "id": 114,
        "url": "https://patchwork.libcamera.org/api/1.1/people/114/?format=api",
        "name": "Utkarsh Tiwari",
        "email": "utkarsh02t@gmail.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/16658/mbox/",
    "series": [
        {
            "id": 3292,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3292/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3292",
            "date": "2022-07-15T19:13:49",
            "name": "Introduce control interaction to qcam",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/3292/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/16658/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/16658/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>",
        "X-Original-To": "parsemail@patchwork.libcamera.org",
        "Delivered-To": "parsemail@patchwork.libcamera.org",
        "Received": [
            "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9CA16BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 15 Jul 2022 19:14:14 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6565A6331C;\n\tFri, 15 Jul 2022 21:14:14 +0200 (CEST)",
            "from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com\n\t[IPv6:2607:f8b0:4864:20::1029])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E25B663312\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 15 Jul 2022 21:14:12 +0200 (CEST)",
            "by mail-pj1-x1029.google.com with SMTP id o15so6466186pjh.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 15 Jul 2022 12:14:12 -0700 (PDT)",
            "from localhost.localdomain\n\t([2406:3003:2005:1c27:d8e8:f9ac:919c:9ac8])\n\tby smtp.gmail.com with ESMTPSA id\n\ts10-20020a170903214a00b0016be834d544sm3834315ple.237.2022.07.15.12.14.09\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 15 Jul 2022 12:14:10 -0700 (PDT)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1657912454;\n\tbh=D4tPv2pcGoac+7pJ3/rPN0x+tV79NXmrCX7NjS6peAs=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=u3lgv6uUInx9vAvqm6LQ9OA619ED0H4kUe1/gRQZpBlMohDADMsvyf1Hce6yS2Rh0\n\tqp/64ovoLlmw2lmhNlcLyg+QejrdeIXp12zjAjzyDrWvd+YHD5UupAziHZ7TcraPL3\n\t+HWjhP5Ur2AH+LE+wHfEMWKuVz/qFyYMJXIQskfP8YA77PLhnqGirgTiLDpj7u/Uzb\n\thqOlZIEGW4RXShi6QXeytJlnL3wg5GNGf6srvX8O2xL82qnYCAI6KqP+Y1g5l8v0XW\n\tE826DGk4kAZD1WxsnqAOu0uhgSbUN05pnSRiyW1P64C1U4hOSgb+Lc2kFHZiLMUunA\n\twfs5sEi8ryBJA==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=0MiMzge+VGNgCec63JdCht73U4viSdAiz/rpsk0XHS0=;\n\tb=CI9b4HGt6ltItBk+B0dmlTgmhkn2c79IB31QPwOMd2RX2reTudkOt/T8HlhnAOEnPq\n\tNaOvVWgqHzzz5nEGmFgFprT4lY30E7nIgQHK6Q5T0L+1uHR5B2OrvGSfG37s+Ys8XfKh\n\tGwIa+JovYfHqFBfTn5AdPQMpaFv3qiWkh0QXGl1LH3h7DkidnvrkLLMLafm5Xr+i0BMY\n\tz8c4A98AvVaSYmB9A6FMAMu+Rdg3or1+OfEEAj722wzEsf3R+BqfNdhjGlPe0BvLPa9t\n\twU+bIaNew5mR5OFaX9NvWtjg7rV3wk8lpkSxonFXxE8GybjVtHoYwtjbVeWesVXv2IrN\n\tVoWg=="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"CI9b4HGt\"; dkim-atps=neutral",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=0MiMzge+VGNgCec63JdCht73U4viSdAiz/rpsk0XHS0=;\n\tb=xzNm1FZ45aLcrPqKQIhMQY5kfhV8pB/BSAlRbl/bLPRrWIOi1sXWDS2jYDgx3X/VaH\n\tD0QMUNefS1vajDlCz6kFNUpl+H5oECj4lLeWobzmCYhRIG2Iy+UPJrQ35RaqfhsO5QIz\n\tGDiKu/kMnJg3NeZb7YpRIr5HWU3SHFE3W7z9UF9LuSr272Xj0cVHOQXpNY14lvbM4wIe\n\t+Cf+t8EnatRvSATy8hSz55wL568DRuPbXBNr1APU70RrN1RJKLIW8bVzGAzAt1UBCGbI\n\tZM41Lq4Cu06R765FICK14ymgAMQ8ADtKmL0p1tUtviur+HTy3u01uje+pDhr/unEgnRX\n\t2Rcg==",
        "X-Gm-Message-State": "AJIora+Dcgq/gvOwcEc4pD+MJXWb9FkGqAQNAkNhmMqHbfMoywjs9lNi\n\tNfKjGsR4Qsn+xluX1DkLPFRuCzB99CtDUg==",
        "X-Google-Smtp-Source": "AGRyM1twThedweFcFymnbjvdQBXXJynqBaK1yRYSTRtvopNSni5T8JkmWNfpBdNVMwVmnX/lg/TrGg==",
        "X-Received": "by 2002:a17:90b:4f85:b0:1f0:95d:c02b with SMTP id\n\tqe5-20020a17090b4f8500b001f0095dc02bmr23410718pjb.89.1657912450844; \n\tFri, 15 Jul 2022 12:14:10 -0700 (PDT)",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Sat, 16 Jul 2022 03:13:52 +0800",
        "Message-Id": "<20220715191400.890976-4-utkarsh02t@gmail.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20220715191400.890976-1-utkarsh02t@gmail.com>",
        "References": "<20220715191400.890976-1-utkarsh02t@gmail.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH 03/11] qcam: Add GUI way to change control\n\tvalues",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "From": "Utkarsh Tiwari via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Utkarsh Tiwari <utkarsh02t@gmail.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Introduce GUI ability to change control values currently only for\nboolean control types.\n\nEach of the ControlFrame first identifies the type of control it is and\nthen accordingly constructs the widget that would help the user to\ninteract with it.\n\nThe current model of connecting the controls change info to the\nMaindWindow is as follows.\n\n            +-----------+\n            |Main Window|\n            +-----^-----+\n                  |\n                  |\n          +-------+-------+\n          |Settings Dialog|\n          +--^----^------^+\n             |    |      |\n      +------+    |      +-----+\n      |           |            |\n+-----+---+  +----+----+  +----+----+\n|Various  |  | Tabs    |  |   ...   |\n++---+----+  +---+---+-+  ++--+--+--+\n |   |           |   |     |  |  |\n |   |           |   |     |  |  |\n |   |           |   |     |  |  |\n\nImplement a controlLatch mechanism to update thec ontrolList. As the\nSettings QDialog and ControlFrame processing the change in control lie\nin the same thread there would be no race to access the ControlList.\n\nThis allows us to use to shared_ptr to the ControlList\nto help us the same function from MaindWindow::queueRequest()\nand the controlListChanged() signal.\n\nWe clear the controlList_ in MainWindow::queueRequest() and not in the\nMainWindow::controlListLatch() because when in controlListLatch() we\nneed to clear it when we don't have script nor the alerted by the signal.\nBut what Can happen is that we have controlListLatch() is triggered by the\nsignal and then immediately called by the queueRequest() which would\nclear the controlList and it would not end up getting set.\n\nSigned-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\n---\n src/qcam/main_window.cpp            | 38 +++++++++++++--\n src/qcam/main_window.h              |  4 ++\n src/qcam/settings/control_frame.cpp | 75 +++++++++++++++++++++++++++--\n src/qcam/settings/control_frame.h   | 13 ++++-\n src/qcam/settings/controls_tab.cpp  | 19 +++++++-\n src/qcam/settings/controls_tab.h    | 10 ++++\n src/qcam/settings/settings_dialog.h |  5 ++\n 7 files changed, 156 insertions(+), 8 deletions(-)",
    "diff": "diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\nindex f0916b8e..5d11ef98 100644\n--- a/src/qcam/main_window.cpp\n+++ b/src/qcam/main_window.cpp\n@@ -98,7 +98,7 @@ private:\n \n MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n \t: saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr),\n-\t  isCapturing_(false), captureRaw_(false)\n+\t  isCapturing_(false), captureRaw_(false), controlList_(ControlList())\n {\n \tint ret;\n \n@@ -353,6 +353,8 @@ void MainWindow::openSettingsDialog()\n \t}\n \n \tsettingsDialog_ = std::make_unique<SettingsDialog>(camera_, this);\n+\tconnect(settingsDialog_.get(), &SettingsDialog::controlListChanged,\n+\t\tthis, &MainWindow::controlListLatch);\n \tsettingsDialog_->show();\n }\n \n@@ -891,10 +893,40 @@ void MainWindow::renderComplete(FrameBuffer *buffer)\n \n int MainWindow::queueRequest(Request *request)\n {\n-\tif (script_)\n-\t\trequest->controls() = script_->frameControls(queueCount_);\n+\t/*\n+\t * Call the controlListLatch with a nullptr to indicate that it\n+\t * has been called by us and not by the signal.\n+\t */\n+\n+\tcontrolListLatch(nullptr);\n+\trequest->controls() = controlList_;\n+\n+\t/* Clear controlList_ to remove old controls that have been set.*/\n+\tif (controlList_.size())\n+\t\tcontrolList_.clear();\n \n \tqueueCount_++;\n \n \treturn camera_->queueRequest(request);\n }\n+\n+void MainWindow::controlListLatch(std::shared_ptr<const libcamera::ControlList> controlList)\n+{\n+\t/*\n+\t * If we have been given a non-null shared_ptr then it means we\n+\t * have been alerted by the SettingsWindow::controlListChanged signal.\n+\t */\n+\n+\tif (controlList) {\n+\t\tcontrolList_ = *(controlList);\n+\n+\t\t/* Shut down the capture script */\n+\t\tif (script_)\n+\t\t\ttoggleScriptAction(true);\n+\n+\t\treturn;\n+\t}\n+\n+\tif (script_)\n+\t\tcontrolList_ = script_->frameControls(queueCount_);\n+}\ndiff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\nindex e35f9029..05207023 100644\n--- a/src/qcam/main_window.h\n+++ b/src/qcam/main_window.h\n@@ -71,6 +71,8 @@ private Q_SLOTS:\n \n \tvoid renderComplete(libcamera::FrameBuffer *buffer);\n \n+\tvoid controlListLatch(std::shared_ptr<const libcamera::ControlList> controlList);\n+\n private:\n \tint createToolbars();\n \n@@ -139,4 +141,6 @@ private:\n \n \tstd::vector<std::unique_ptr<libcamera::Request>> requests_;\n \tstd::unique_ptr<CaptureScript> script_;\n+\n+\tlibcamera::ControlList controlList_;\n };\ndiff --git a/src/qcam/settings/control_frame.cpp b/src/qcam/settings/control_frame.cpp\nindex 785e4040..e335d373 100644\n--- a/src/qcam/settings/control_frame.cpp\n+++ b/src/qcam/settings/control_frame.cpp\n@@ -9,7 +9,9 @@\n \n #include <libcamera/controls.h>\n \n+#include <QCheckBox>\n #include <QFrame>\n+#include <QHBoxLayout>\n #include <QLabel>\n #include <QString>\n #include <QVBoxLayout>\n@@ -27,11 +29,11 @@ ControlFrame::ControlFrame(const libcamera::ControlId *control,\n \tframeVLayout->addWidget(new QLabel(QString::fromStdString(control_->name())));\n \n \t/*\n-\t * No need to pass parents to widgets,\n-\t * as QVBoxLayout transfers ownership to\n-\t * its parent widget.\n+\t * No need to pass parents to widgets, as QVBoxLayout transfers\n+\t * ownership to its parent widget.\n \t */\n \tframeVLayout->addWidget(defaultValueLabel());\n+\tframeVLayout->addWidget(controlInteraction());\n \n \tsetFrameStyle(QFrame::StyledPanel);\n }\n@@ -49,6 +51,73 @@ QLabel *ControlFrame::defaultValueLabel(QWidget *parent)\n \treturn defaultValLabel;\n }\n \n+QWidget *ControlFrame::controlInteraction(QWidget *parent)\n+{\n+\tQWidget *containerWidget = new QWidget(parent);\n+\n+\tswitch (control_->type()) {\n+\tcase ControlTypeBool: {\n+\t\tQHBoxLayout *HCheckBoxLayout = new QHBoxLayout(containerWidget);\n+\n+\t\tHCheckBoxLayout->addWidget(new QLabel(\"Enabled :\"));\n+\n+\t\tcontrolCheckBox_ = new QCheckBox;\n+\t\t/*\n+\t\t * In the start we are not sure what is exactly the state of\n+\t\t * the control. Do not assume. Set in partially checked state.\n+\t\t */\n+\t\tcontrolCheckBox_->setCheckState(Qt::PartiallyChecked);\n+\n+\t\tconnect(controlCheckBox_, &QCheckBox::stateChanged,\n+\t\t\tthis, &ControlFrame::notifyControlChange);\n+\n+\t\tHCheckBoxLayout->addWidget(controlCheckBox_);\n+\n+\t\t/* Align it with the name of the control. */\n+\t\tHCheckBoxLayout->setAlignment(Qt::AlignLeft);\n+\t\tHCheckBoxLayout->setMargin(0);\n+\t\treturn containerWidget;\n+\t}\n+\tdefault:\n+\t\treturn (new QLabel(\"Currently Unavailable\"));\n+\t}\n+}\n+\n+/* -----------------------------------------------------------------------------\n+ * Qt Slots\n+ */\n+\n+void ControlFrame::notifyControlChange()\n+{\n+\tControlValue controlValue = ControlValue();\n+\n+\tswitch (control_->type()) {\n+\tcase ControlTypeBool:\n+\n+\t\t/*\n+\t\t * When clicked for the first time, the switch comes from a\n+\t\t * partially checked state. Turn the triset off so we can have\n+\t\t * only enabled and disabled states.\n+\t\t */\n+\t\tcontrolCheckBox_->setTristate(false);\n+\t\t/*\n+\t\t * When this function is invoked, the checkbox can only be in\n+\t\t * the Checked or Unchecked State (after the first time).\n+\t\t */\n+\t\tif (controlCheckBox_->checkState() == Qt::CheckState::Checked)\n+\t\t\tcontrolValue.set<bool>(true);\n+\t\telse\n+\t\t\tcontrolValue.set<bool>(false);\n+\n+\t\tbreak;\n+\tdefault:\n+\t\t/* Nothing to emit so return */\n+\t\treturn;\n+\t}\n+\n+\tQ_EMIT controlChanged(control_, controlValue);\n+}\n+\n /* -----------------------------------------------------------------------------\n  * Helpers\n  */\ndiff --git a/src/qcam/settings/control_frame.h b/src/qcam/settings/control_frame.h\nindex 884feb6b..61005ea5 100644\n--- a/src/qcam/settings/control_frame.h\n+++ b/src/qcam/settings/control_frame.h\n@@ -9,8 +9,9 @@\n \n #include <libcamera/controls.h>\n \n-#include <QLabel>\n+#include <QCheckBox>\n #include <QFrame>\n+#include <QLabel>\n #include <QWidget>\n \n class ControlFrame : public QFrame\n@@ -23,13 +24,23 @@ public:\n \t\t     QWidget *parent);\n \t~ControlFrame() = default;\n \n+Q_SIGNALS:\n+\tvoid controlChanged(const libcamera::ControlId *controlId,\n+\t\t\t    const libcamera::ControlValue);\n+\n+private Q_SLOTS:\n+\tvoid notifyControlChange();\n+\n private:\n \tconst libcamera::ControlId *control_;\n \tconst libcamera::ControlInfo &controlInfo_;\n \n \t/* Widgets */\n+\tQWidget *controlInteraction(QWidget *parent = nullptr);\n \tQLabel *defaultValueLabel(QWidget *parent = nullptr);\n \n+\tQCheckBox *controlCheckBox_;\n+\n \t/* Helper Hunctions */\n \tQString getDefaultValueQStr();\n };\ndiff --git a/src/qcam/settings/controls_tab.cpp b/src/qcam/settings/controls_tab.cpp\nindex adc24326..0777d708 100644\n--- a/src/qcam/settings/controls_tab.cpp\n+++ b/src/qcam/settings/controls_tab.cpp\n@@ -17,9 +17,11 @@\n \n #include \"control_frame.h\"\n \n+using namespace libcamera;\n+\n ControlsTab::ControlsTab(std::shared_ptr<libcamera::Camera> camera_,\n \t\t\t QWidget *parent)\n-\t: QWidget(parent)\n+\t: QWidget(parent), controlList_(std::make_shared<ControlList>())\n {\n \t/* Main Layout for the tab */\n \tQGridLayout *controlGLayout = new QGridLayout(this);\n@@ -27,6 +29,8 @@ ControlsTab::ControlsTab(std::shared_ptr<libcamera::Camera> camera_,\n \tint controlCount = 0;\n \tfor (auto &[control, info] : camera_->controls()) {\n \t\tControlFrame *controlFrame = new ControlFrame(control, info, this);\n+\t\tconnect(controlFrame, &ControlFrame::controlChanged,\n+\t\t\tthis, &ControlsTab::controlChanged);\n \n \t\tcontrolGLayout->addWidget(controlFrame, controlCount / 2,\n \t\t\t\t\t  controlCount % 2);\n@@ -36,3 +40,16 @@ ControlsTab::ControlsTab(std::shared_ptr<libcamera::Camera> camera_,\n \tif (controlCount == 0)\n \t\tcontrolGLayout->addWidget(new QLabel(\"No controls available\"));\n }\n+\n+/* -----------------------------------------------------------------------------\n+ * Qt Slots\n+ */\n+\n+void ControlsTab::controlChanged(const libcamera::ControlId *controlId,\n+\t\t\t\t const libcamera::ControlValue controlValue)\n+{\n+\tcontrolList_->clear();\n+\n+\tcontrolList_->set(controlId->id(), controlValue);\n+\tQ_EMIT controlListChanged(controlList_);\n+}\ndiff --git a/src/qcam/settings/controls_tab.h b/src/qcam/settings/controls_tab.h\nindex 6a63f334..5bac7d48 100644\n--- a/src/qcam/settings/controls_tab.h\n+++ b/src/qcam/settings/controls_tab.h\n@@ -21,4 +21,14 @@ class ControlsTab : public QWidget\n public:\n \tControlsTab(std::shared_ptr<libcamera::Camera> camera_, QWidget *parent);\n \t~ControlsTab() = default;\n+\n+Q_SIGNALS:\n+\tvoid controlListChanged(const std::shared_ptr<const libcamera::ControlList>);\n+\n+public Q_SLOTS:\n+\tvoid controlChanged(const libcamera::ControlId *controlId,\n+\t\t\t    const libcamera::ControlValue controlValue);\n+\n+private:\n+\tstd::shared_ptr<libcamera::ControlList> controlList_;\n };\ndiff --git a/src/qcam/settings/settings_dialog.h b/src/qcam/settings/settings_dialog.h\nindex c2fa61ea..e6efd876 100644\n--- a/src/qcam/settings/settings_dialog.h\n+++ b/src/qcam/settings/settings_dialog.h\n@@ -32,8 +32,13 @@ public:\n \n \t\tControlsTab *controlsTab = new ControlsTab(camera, this);\n \t\tsettingTabWidget->addTab(controlsTab, \"Controls\");\n+\t\tconnect(controlsTab, &ControlsTab::controlListChanged,\n+\t\t\tthis, &SettingsDialog::controlListChanged);\n \n \t\tsetWindowTitle(\"Settings\");\n \t}\n \t~SettingsDialog() = default;\n+\n+Q_SIGNALS:\n+\tvoid controlListChanged(std::shared_ptr<const libcamera::ControlList>);\n };\n",
    "prefixes": [
        "libcamera-devel",
        "03/11"
    ]
}