[{"id":24850,"web_url":"https://patchwork.libcamera.org/comment/24850/","msgid":"<Yw8kbg3cORwQe4pD@pendragon.ideasonboard.com>","date":"2022-08-31T09:05:50","subject":"Re: [libcamera-devel] [PATCH v9 1/7] qcam: Use QDialog for\n\tselection of cameras at startup","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Wed, Aug 31, 2022 at 11:19:32AM +0530, Utkarsh Tiwari wrote:\n> Currently we use QInputDialog convenience dialogs to allow the user to\n> select a camera. This doesn't allow adding of more information (such as\n> camera location, model etc).\n> \n> Create a QDialog with a QFormLayout that shows a QComboBox with camera\n> Ids. Use a QDialogButtonBox to provide buttons for accepting and\n> cancelling the action.\n> \n> The CameraSelectorDialog is only initialized the first time when the\n> MainWindow is created.\n> \n> From this commit we cease to auto select the camera if only a single\n> camera is available to libcamera. We would always display the selection\n> dialog with the exception being that being if the camera is supplied on\n> the command line.\n> \n> Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n> Difference from v8:\n>     1. s/by the console/on the command line in the commit msg\n>     2. Removed <string> header from cam_select_dialog.cpp\n>     3. Drop <QDialog> from cam_select_dialog.cpp\n>     4. QComboBox is forward-declared in cam_select_dialog.h\n>     5. ~CameraSelectorDialog() implementation now resides in .cpp\n>     6. CameraSelectorDialog is forward-declared in main_window.h\n>  src/qcam/cam_select_dialog.cpp | 50 ++++++++++++++++++++++++++++++++++\n>  src/qcam/cam_select_dialog.h   | 35 ++++++++++++++++++++++++\n>  src/qcam/main_window.cpp       | 27 ++++--------------\n>  src/qcam/main_window.h         |  3 ++\n>  src/qcam/meson.build           |  2 ++\n>  5 files changed, 96 insertions(+), 21 deletions(-)\n>  create mode 100644 src/qcam/cam_select_dialog.cpp\n>  create mode 100644 src/qcam/cam_select_dialog.h\n> \n> diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp\n> new file mode 100644\n> index 00000000..a49d822b\n> --- /dev/null\n> +++ b/src/qcam/cam_select_dialog.cpp\n> @@ -0,0 +1,50 @@\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 <libcamera/camera.h>\n> +#include <libcamera/camera_manager.h>\n> +\n> +#include <QComboBox>\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> +CameraSelectorDialog::~CameraSelectorDialog() = default;\n> +\n> +std::string CameraSelectorDialog::getCameraId()\n> +{\n> +\treturn cameraIdComboBox_->currentText().toStdString();\n> +}\n> diff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h\n> new file mode 100644\n> index 00000000..c31f4f82\n> --- /dev/null\n> +++ b/src/qcam/cam_select_dialog.h\n> @@ -0,0 +1,35 @@\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 <QDialog>\n> +\n> +class QComboBox;\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\nYou can drop this blank line.\n\n> +\t~CameraSelectorDialog();\n> +\n> +\tstd::string getCameraId();\n> +\n> +private:\n> +\tlibcamera::CameraManager *cm_;\n> +\n> +\t/* UI elements. */\n> +\tQComboBox *cameraIdComboBox_;\n> +};\n> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> index 7433d647..14bcf03e 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> @@ -144,6 +144,8 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n>  \tcm_->cameraAdded.connect(this, &MainWindow::addCamera);\n>  \tcm_->cameraRemoved.connect(this, &MainWindow::removeCamera);\n>  \n> +\tcameraSelectorDialog_ = new CameraSelectorDialog(cm_, this);\n> +\n>  \t/* Open the camera and start capture. */\n>  \tret = openCamera();\n>  \tif (ret < 0) {\n> @@ -290,34 +292,17 @@ 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> +\tif (cameraSelectorDialog_->exec() != QDialog::Accepted)\n>  \t\treturn std::string();\n>  \n> -\treturn id.toStdString();\n> +\treturn cameraSelectorDialog_->getCameraId();\n>  }\n>  \n>  int MainWindow::openCamera()\n>  {\n>  \tstd::string cameraName;\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> +\t/* Use camera provided on the command line else prompt for selection.*/\n\nAnything wrong with the current comment ?\n\n>  \tif (options_.isSet(OptCamera))\n>  \t\tcameraName = static_cast<std::string>(options_[OptCamera]);\n>  \telse\n> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> index fc70920f..def44605 100644\n> --- a/src/qcam/main_window.h\n> +++ b/src/qcam/main_window.h\n> @@ -35,6 +35,7 @@ class QComboBox;\n>  \n>  class Image;\n>  class HotplugEvent;\n> +class CameraSelectorDialog;\n\nAlphabetical order please.\n\n>  \n>  enum {\n>  \tOptCamera = 'c',\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>  \n> diff --git a/src/qcam/meson.build b/src/qcam/meson.build\n> index 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>  ])","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 18351C0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 31 Aug 2022 09:06:03 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C7A8A61FC0;\n\tWed, 31 Aug 2022 11:06:02 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 412E5603E1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 31 Aug 2022 11:06:01 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C1885481;\n\tWed, 31 Aug 2022 11:06:00 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1661936762;\n\tbh=LFGmU2Xah7pPZeqd+9+i8GKfetosy1RlEJKCcwpUITY=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=JbvE6K7a1+p3ygbDNQPdQ2RE1YUB7O2BNPJ7/fbBYItp9JfQ+15GLmbMP0bot3V+b\n\t2ZZQXmYn0hymKABFmmfoqmYmZpZJTyWRG5hUinvVF+wKtCWX2XwUspGe6iPye0msA4\n\tbjkQLuql3ZRJpCSNpjUBx6LuVih5Zaj3pzG26JEV3iY1VR4qfWtJ9s9ZzjKxkL1p1o\n\tcx3yQCpXxohukSOXzwbQLYSu1u7qDTZu+hZvNDrUI8MiDDbvakgMYt8ew0U6dey4RG\n\t2nd1kLjoNe4FtpmBaquHGBhy7FLYeXI7ALkALhuApyGMrEkOJAxLzMLpKmJFbkuh4X\n\t9WVmz5yJlxChQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1661936761;\n\tbh=LFGmU2Xah7pPZeqd+9+i8GKfetosy1RlEJKCcwpUITY=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=fLXwMYocsomRbbPVJKqIuFLgDpKeiP6m0twktliq9PnHMgjfAHlWFxlqT9ngTanbX\n\t3k1KLUMqEFFzzW3Lmx6pUxV1Bx8X53+aTycKCkxy0CV1K4DU0+JUTCEqZUcHhUmCs4\n\tJzSvTT7dNz9oHFSRHKO33J84ZI9WQ4PCgiyWjSuQ="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"fLXwMYoc\"; dkim-atps=neutral","Date":"Wed, 31 Aug 2022 12:05:50 +0300","To":"Utkarsh Tiwari <utkarsh02t@gmail.com>","Message-ID":"<Yw8kbg3cORwQe4pD@pendragon.ideasonboard.com>","References":"<20220831054938.21617-1-utkarsh02t@gmail.com>\n\t<20220831054938.21617-2-utkarsh02t@gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220831054938.21617-2-utkarsh02t@gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v9 1/7] qcam: Use QDialog for\n\tselection of cameras 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":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]