Show a patch.

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

{
    "id": 17067,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/17067/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/17067/",
    "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": "<20220810150349.414043-2-utkarsh02t@gmail.com>",
    "date": "2022-08-10T15:03:42",
    "name": "[libcamera-devel,v8,1/8] qcam: Use QDialog for selection of cameras at startup",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "3879136a263514005756079a039de0a198dc5617",
    "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/17067/mbox/",
    "series": [
        {
            "id": 3402,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3402/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3402",
            "date": "2022-08-10T15:03:41",
            "name": "Introduce capture scripts to qcam",
            "version": 8,
            "mbox": "https://patchwork.libcamera.org/series/3402/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/17067/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/17067/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 21D7CC3272\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 10 Aug 2022 15:04:02 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D092063330;\n\tWed, 10 Aug 2022 17:04:01 +0200 (CEST)",
            "from mail-pg1-x530.google.com (mail-pg1-x530.google.com\n\t[IPv6:2607:f8b0:4864:20::530])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5B5676332C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Aug 2022 17:03:59 +0200 (CEST)",
            "by mail-pg1-x530.google.com with SMTP id l64so14641199pge.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Aug 2022 08:03:59 -0700 (PDT)",
            "from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed])\n\tby smtp.gmail.com with ESMTPSA id\n\tb3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.03.55\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 10 Aug 2022 08:03:57 -0700 (PDT)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1660143841;\n\tbh=k1ygg5cAr3MHmyh7/K9n38RIh+/ZsJClzfGBFmKNHc4=;\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=iG9YSM2B7HetCGoqsi0rRCS/qf9b2G2wpIAeoVPSU2qQ49agzydpLOJeoypovra4t\n\tLSTNVUVPg/gIA/H00IQirEbqIirJU5hVkZbkLpNOawppDeklcy+xhSRwFeNFSnk3mh\n\tlRdCe6I0kuUEeU6PPqFm1C3KShgGLzPvF7rbBUqNpGof/Hhiwx22RZyvPhdfD8eyi2\n\t2Z6+zgtodpgnCX4lb+iwW+Uv+rnKssVs91wPXczC7hHWZKbnLHrd6biasFbDOcrDss\n\tFXqqhvlWvLv08jX1Q1msVicb5DIawAc/57/eMjyFaPfMFidw1ZnLjPkmBdvSz4sVWu\n\tplyIjyK160dsw==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:from:to:cc;\n\tbh=nTSKjqEoOIkLDAJNk+hwruS61OgtqBGKbBboEl9JhZc=;\n\tb=ROzwz1dAwnOLN/DuOGoH9imuw7ta3Xl7c0V167yOz5Us0ZdeJTzOtDrdq83boBXzcV\n\tBDgr59DAYxWmfWar04ked6E2+3MNLU8bvnQ2wuw8x/q95+pXjuXee+szhW7Zo6QKYBKO\n\tiSHGB+UKBiNlbadBfNRqVUmCO0V9f4k6FEebwo4ZiQIPTYbkZ48ZPZvyd0a8uomwAd/+\n\t54bK3fDG9vZOAyWEH1xvbnCCPGFFNqBVqYfSo50UGe+BUE6ZXRS5owrB5UDFm59V0DdW\n\toRY3mfMfTbq4Uo5Mcj3qsnRY13Q4jvjwFtPoMnY5NqMYjVfQsyqb2U0a19zweM09hb9V\n\t7gag=="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"ROzwz1dA\"; dkim-atps=neutral",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc;\n\tbh=nTSKjqEoOIkLDAJNk+hwruS61OgtqBGKbBboEl9JhZc=;\n\tb=polQDav8Oj6QU2ILIQFx2Kims9v4SabXMcCDbi0dpgP8dSTegQEyY6lYEqMpjed7Xw\n\tvWmVQyE++dkinxQJv+VoQWgTE8DwmdkTpoqsJ9sLOArLmFMS/JXbAOXKC5pEX7jimhkk\n\tPf32NTkrOC3W/K7b+wpm0bocOrgZCDiqhbDj4K5OKlyUrXc2IJ9mhB1VBXYjoGkZEGxd\n\tSNcgiC6QlgFBFAY3KKg9nmRzjrY73p6ScLrDJoN4NCdDC/qBGCUVw9HbKgG2tzHYa1Df\n\taKV20Gmey8FZY2MsvePKrVgSFsK69jwHxIrBwueBibmHf22n4Yn1w6BrCv2oYBCshiFl\n\tSzsw==",
        "X-Gm-Message-State": "ACgBeo3JxerEu6WJYr4sPDP+YyCTivvYq77cQO1jTshYjvtPnbNjZjkn\n\tYxXzITCbnL2csXBYCYWfNVSS2efPvUI=",
        "X-Google-Smtp-Source": "AA6agR4utrwDXyXtJVov/NkofvwP2GWKIqT5Y3NCZNtfb+FZJZMQJo43ARjsL94S5fC/0y23FiTUdQ==",
        "X-Received": "by 2002:a05:6a00:cc1:b0:52d:a29d:fb1 with SMTP id\n\tb1-20020a056a000cc100b0052da29d0fb1mr27805499pfv.56.1660143837456; \n\tWed, 10 Aug 2022 08:03:57 -0700 (PDT)",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Wed, 10 Aug 2022 20:33:42 +0530",
        "Message-Id": "<20220810150349.414043-2-utkarsh02t@gmail.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20220810150349.414043-1-utkarsh02t@gmail.com>",
        "References": "<20220810150349.414043-1-utkarsh02t@gmail.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v8 1/8] qcam: Use QDialog for selection of\n\tcameras at startup",
        "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": "Currently we use QInputDialog convenience dialogs to allow the user to\nselect a camera. This doesn't allow adding of more information (such as\ncamera location, model etc).\n\nCreate a QDialog with a QFormLayout that shows a QComboBox with camera\nIds. Use a QDialogButtonBox to provide buttons for accepting and\ncancelling the action.\n\nThe CameraSelectorDialog is only initialized the first time when the\nMainWindow is created.\n\nFrom this commit we cease to auto select the camera if only a single\ncamera is available to libcamera. We would always display the selection\ndialog with the exception being that being if the camera is supplied by\nthe console.\n\nSigned-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\nDifference from v7:\n\t1. Updated the commit message to inform of the behavioural change in\n\t\tselecting the first camera.\n src/qcam/cam_select_dialog.cpp | 51 ++++++++++++++++++++++++++++++++++\n src/qcam/cam_select_dialog.h   | 34 +++++++++++++++++++++++\n src/qcam/main_window.cpp       | 44 +++++++++++------------------\n src/qcam/main_window.h         |  3 ++\n src/qcam/meson.build           |  2 ++\n 5 files changed, 106 insertions(+), 28 deletions(-)\n create mode 100644 src/qcam/cam_select_dialog.cpp\n create mode 100644 src/qcam/cam_select_dialog.h",
    "diff": "diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp\nnew file mode 100644\nindex 00000000..dceaa590\n--- /dev/null\n+++ b/src/qcam/cam_select_dialog.cpp\n@@ -0,0 +1,51 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2022, Utkarsh Tiwari <utkarsh02t@gmail.com>\n+ *\n+ * cam_select_dialog.cpp - qcam - Camera Selection dialog\n+ */\n+\n+#include \"cam_select_dialog.h\"\n+\n+#include <string>\n+\n+#include <libcamera/camera.h>\n+#include <libcamera/camera_manager.h>\n+\n+#include <QComboBox>\n+#include <QDialog>\n+#include <QDialogButtonBox>\n+#include <QFormLayout>\n+#include <QString>\n+\n+CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManager,\n+\t\t\t\t\t   QWidget *parent)\n+\t: QDialog(parent), cm_(cameraManager)\n+{\n+\t/* Use a QFormLayout for the dialog. */\n+\tQFormLayout *layout = new QFormLayout(this);\n+\n+\t/* Setup the camera id combo-box. */\n+\tcameraIdComboBox_ = new QComboBox;\n+\tfor (const auto &cam : cm_->cameras())\n+\t\tcameraIdComboBox_->addItem(QString::fromStdString(cam->id()));\n+\n+\t/* Setup the QDialogButton Box */\n+\tQDialogButtonBox *buttonBox =\n+\t\tnew QDialogButtonBox(QDialogButtonBox::Ok |\n+\t\t\t\t     QDialogButtonBox::Cancel);\n+\n+\tconnect(buttonBox, &QDialogButtonBox::accepted,\n+\t\tthis, &QDialog::accept);\n+\tconnect(buttonBox, &QDialogButtonBox::rejected,\n+\t\tthis, &QDialog::reject);\n+\n+\t/* Set the layout. */\n+\tlayout->addRow(\"Camera:\", cameraIdComboBox_);\n+\tlayout->addWidget(buttonBox);\n+}\n+\n+std::string CameraSelectorDialog::getCameraId()\n+{\n+\treturn cameraIdComboBox_->currentText().toStdString();\n+}\ndiff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h\nnew file mode 100644\nindex 00000000..5544f49a\n--- /dev/null\n+++ b/src/qcam/cam_select_dialog.h\n@@ -0,0 +1,34 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2022, Utkarsh Tiwari <utkarsh02t@gmail.com>\n+ *\n+ * cam_select_dialog.h - qcam - Camera Selection dialog\n+ */\n+\n+#pragma once\n+\n+#include <string>\n+\n+#include <libcamera/camera.h>\n+#include <libcamera/camera_manager.h>\n+\n+#include <QComboBox>\n+#include <QDialog>\n+\n+class CameraSelectorDialog : public QDialog\n+{\n+\tQ_OBJECT\n+public:\n+\tCameraSelectorDialog(libcamera::CameraManager *cameraManager,\n+\t\t\t     QWidget *parent);\n+\n+\t~CameraSelectorDialog() = default;\n+\n+\tstd::string getCameraId();\n+\n+private:\n+\tlibcamera::CameraManager *cm_;\n+\n+\t/* UI elements. */\n+\tQComboBox *cameraIdComboBox_;\n+};\ndiff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\nindex 7433d647..e794221a 100644\n--- a/src/qcam/main_window.cpp\n+++ b/src/qcam/main_window.cpp\n@@ -19,7 +19,6 @@\n #include <QFileDialog>\n #include <QImage>\n #include <QImageWriter>\n-#include <QInputDialog>\n #include <QMutexLocker>\n #include <QStandardPaths>\n #include <QStringList>\n@@ -30,6 +29,7 @@\n \n #include \"../cam/image.h\"\n \n+#include \"cam_select_dialog.h\"\n #include \"dng_writer.h\"\n #ifndef QT_NO_OPENGL\n #include \"viewfinder_gl.h\"\n@@ -97,8 +97,8 @@ private:\n };\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: saveRaw_(nullptr), cameraSelectorDialog_(nullptr), options_(options),\n+\t  cm_(cm), allocator_(nullptr), isCapturing_(false), captureRaw_(false)\n {\n \tint ret;\n \n@@ -290,38 +290,26 @@ void MainWindow::switchCamera(int index)\n \n std::string MainWindow::chooseCamera()\n {\n-\tQStringList cameras;\n-\tbool result;\n-\n-\t/* If only one camera is available, use it automatically. */\n-\tif (cm_->cameras().size() == 1)\n-\t\treturn cm_->cameras()[0]->id();\n-\n-\t/* Present a dialog box to pick a camera. */\n-\tfor (const std::shared_ptr<Camera> &cam : cm_->cameras())\n-\t\tcameras.append(QString::fromStdString(cam->id()));\n-\n-\tQString id = QInputDialog::getItem(this, \"Select Camera\",\n-\t\t\t\t\t   \"Camera:\", cameras, 0,\n-\t\t\t\t\t   false, &result);\n-\tif (!result)\n-\t\treturn std::string();\n-\n-\treturn id.toStdString();\n-}\n-\n-int MainWindow::openCamera()\n-{\n-\tstd::string cameraName;\n+\t/* Construct the selection dialog, only the first time. */\n+\tif (!cameraSelectorDialog_)\n+\t\tcameraSelectorDialog_ = new CameraSelectorDialog(cm_, this);\n \n \t/*\n \t * Use the camera specified on the command line, if any, or display the\n \t * camera selection dialog box otherwise.\n \t */\n \tif (options_.isSet(OptCamera))\n-\t\tcameraName = static_cast<std::string>(options_[OptCamera]);\n+\t\treturn static_cast<std::string>(options_[OptCamera]);\n+\n+\tif (cameraSelectorDialog_->exec() == QDialog::Accepted)\n+\t\treturn cameraSelectorDialog_->getCameraId();\n \telse\n-\t\tcameraName = chooseCamera();\n+\t\treturn std::string();\n+}\n+\n+int MainWindow::openCamera()\n+{\n+\tstd::string cameraName = chooseCamera();\n \n \tif (cameraName == \"\")\n \t\treturn -EINVAL;\ndiff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\nindex fc70920f..4ad5e6e9 100644\n--- a/src/qcam/main_window.h\n+++ b/src/qcam/main_window.h\n@@ -28,6 +28,7 @@\n \n #include \"../cam/stream_options.h\"\n \n+#include \"cam_select_dialog.h\"\n #include \"viewfinder.h\"\n \n class QAction;\n@@ -99,6 +100,8 @@ private:\n \tQString title_;\n \tQTimer titleTimer_;\n \n+\tCameraSelectorDialog *cameraSelectorDialog_;\n+\n \t/* Options */\n \tconst OptionsParser::Options &options_;\n \ndiff --git a/src/qcam/meson.build b/src/qcam/meson.build\nindex c46f4631..61861ea6 100644\n--- a/src/qcam/meson.build\n+++ b/src/qcam/meson.build\n@@ -18,6 +18,7 @@ qcam_sources = files([\n     '../cam/image.cpp',\n     '../cam/options.cpp',\n     '../cam/stream_options.cpp',\n+    'cam_select_dialog.cpp',\n     'format_converter.cpp',\n     'main.cpp',\n     'main_window.cpp',\n@@ -26,6 +27,7 @@ qcam_sources = files([\n ])\n \n qcam_moc_headers = files([\n+    'cam_select_dialog.h',\n     'main_window.h',\n     'viewfinder_qt.h',\n ])\n",
    "prefixes": [
        "libcamera-devel",
        "v8",
        "1/8"
    ]
}