diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 00:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 00:06:44 +0000 |
commit | 44cf8ec67278bd1ab6c7f83a9993f7a5686a9541 (patch) | |
tree | 5eec4b0d1a3f163d279c3c27c03324ba49fa235a /zbarcam/zbarcam-qt.cpp | |
parent | Initial commit. (diff) | |
download | zbar-44cf8ec67278bd1ab6c7f83a9993f7a5686a9541.tar.xz zbar-44cf8ec67278bd1ab6c7f83a9993f7a5686a9541.zip |
Adding upstream version 0.23.93.upstream/0.23.93upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'zbarcam/zbarcam-qt.cpp')
-rw-r--r-- | zbarcam/zbarcam-qt.cpp | 1050 |
1 files changed, 1050 insertions, 0 deletions
diff --git a/zbarcam/zbarcam-qt.cpp b/zbarcam/zbarcam-qt.cpp new file mode 100644 index 0000000..b98a32a --- /dev/null +++ b/zbarcam/zbarcam-qt.cpp @@ -0,0 +1,1050 @@ +//------------------------------------------------------------------------ +// Copyright 2008-2009 (c) Jeff Brown <spadix@users.sourceforge.net> +// +// This file is part of the ZBar Bar Code Reader. +// +// The ZBar Bar Code Reader is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser Public License as +// published by the Free Software Foundation; either version 2.1 of +// the License, or (at your option) any later version. +// +// The ZBar Bar Code Reader is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser Public License for more details. +// +// You should have received a copy of the GNU Lesser Public License +// along with the ZBar Bar Code Reader; if not, write to the Free +// Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA +// +// http://sourceforge.net/projects/zbar +//------------------------------------------------------------------------ + +#include <QApplication> +#include <QCheckBox> +#include <QComboBox> +#include <QCommandLineParser> +#include <QFileDialog> +#include <QImage> +#include <QLayout> +#include <QPushButton> +#include <QTextEdit> +#include <QWidget> +#include <QtGlobal> +#include <config.h> +#include <zbar.h> +#include <zbar/QZBar.h> + +#define TEST_IMAGE_FORMATS \ + "Image Files (*.png *.jpg *.jpeg *.bmp *.gif *.ppm *.pgm *.pbm *.tiff " \ + "*.xpm *.xbm)" + +#define SYM_GROUP "Symbology" +#define CAM_GROUP "Camera" +#define DBUS_NAME "D-Bus" +#define OPTION_BAR "option_bar.enable" +#define CONTROL_BAR "control_bar.enable" + +extern "C" { +int scan_video(void *add_device, void *userdata, const char *default_device); +} + +struct configs_s { + QString name; + zbar::zbar_symbol_type_t sym; +}; + +static const struct configs_s configs[] = { + { "Composite codes", zbar::ZBAR_COMPOSITE }, + { "Image Scanner", zbar::ZBAR_PARTIAL }, +#if ENABLE_CODABAR == 1 + { "Codabar", zbar::ZBAR_CODABAR }, +#endif +#if ENABLE_CODE128 == 1 + { "Code-128", zbar::ZBAR_CODE128 }, +#endif +#if ENABLE_I25 == 1 + { "Code 2 of 5 interlaced", zbar::ZBAR_I25 }, +#endif +#if ENABLE_CODE39 == 1 + { "Code-39", zbar::ZBAR_CODE39 }, +#endif +#if ENABLE_CODE93 == 1 + { "Code-93", zbar::ZBAR_CODE93 }, +#endif +#if ENABLE_DATABAR == 1 + { "DataBar", zbar::ZBAR_DATABAR }, + { "DataBar expanded", zbar::ZBAR_DATABAR_EXP }, +#endif +#if ENABLE_EAN == 1 + { "EAN-2", zbar::ZBAR_EAN2 }, + { "EAN-5", zbar::ZBAR_EAN5 }, + { "EAN-8", zbar::ZBAR_EAN8 }, + { "EAN-13", zbar::ZBAR_EAN13 }, + { "ISBN-10", zbar::ZBAR_ISBN10 }, + { "ISBN-13", zbar::ZBAR_ISBN13 }, + { "UPC-A", zbar::ZBAR_UPCA }, + { "UPC-E", zbar::ZBAR_UPCE }, +#endif +#if ENABLE_PDF417 == 1 + { "PDF417", zbar::ZBAR_PDF417 }, +#endif +#if ENABLE_QRCODE == 1 + { "QR code", zbar::ZBAR_QRCODE }, +#endif +#if ENABLE_SQCODE == 1 + { "SQ code", zbar::ZBAR_SQCODE }, +#endif +}; + +#define CONFIGS_SIZE (sizeof(configs) / sizeof(*configs)) + +struct settings_s { + QString name; + zbar::zbar_config_t ctrl; + bool is_bool; +}; + +static const struct settings_s settings[] = { + { "x-density", zbar::ZBAR_CFG_Y_DENSITY, false }, + { "y-density", zbar::ZBAR_CFG_Y_DENSITY, false }, + { "min-length", zbar::ZBAR_CFG_MIN_LEN, false }, + { "max-length", zbar::ZBAR_CFG_MAX_LEN, false }, + { "uncertainty", zbar::ZBAR_CFG_UNCERTAINTY, false }, + { "ascii", zbar::ZBAR_CFG_ASCII, true }, + { "binary", zbar::ZBAR_CFG_BINARY, true }, + { "add-check", zbar::ZBAR_CFG_ADD_CHECK, true }, + { "emit-check", zbar::ZBAR_CFG_EMIT_CHECK, true }, + { "position", zbar::ZBAR_CFG_POSITION, true }, + { "test-inverted", zbar::ZBAR_CFG_TEST_INVERTED, true }, +}; +#define SETTINGS_SIZE (sizeof(settings) / sizeof(*settings)) + +// Represents an integer control + +class IntegerControl : public QSpinBox +{ + Q_OBJECT + +private: + char *name; + zbar::QZBar *zbar; + +private slots: + void updateControl(int value); + +public: + IntegerControl(QGroupBox *parent, zbar::QZBar *_zbar, char *_name, int min, + int max, int def, int step) + : QSpinBox(parent) + { + int val; + + zbar = _zbar; + name = _name; + + setRange(min, max); + setSingleStep(step); + if (!zbar->get_control(name, &val)) + setValue(val); + else + setValue(def); + + connect(this, SIGNAL(valueChanged(int)), this, + SLOT(updateControl(int))); + } +}; + +void IntegerControl::updateControl(int value) +{ + zbar->set_control(name, value); +} + +// Represents a menu control +class MenuControl : public QComboBox +{ + Q_OBJECT + +private: + char *name; + zbar::QZBar *zbar; + QVector<QPair<int, QString> > vector; + +private slots: + void updateControl(int value); + +public: + MenuControl(QGroupBox *parent, zbar::QZBar *_zbar, char *_name, + QVector<QPair<int, QString> > _vector) + : QComboBox(parent) + { + int val; + + zbar = _zbar; + name = _name; + vector = _vector; + + if (zbar->get_control(name, &val)) + val = 0; + for (int i = 0; i < vector.size(); ++i) { + QPair<int, QString> pair = vector.at(i); + addItem(pair.second, pair.first); + + if (val == pair.first) + setCurrentIndex(i); + } + connect(this, SIGNAL(currentIndexChanged(int)), this, + SLOT(updateControl(int))); + } +}; + +void MenuControl::updateControl(int index) +{ + zbar->set_control(name, vector.at(index).first); +} + +class IntegerSetting : public QSpinBox +{ + Q_OBJECT + +public: + QString name; + + IntegerSetting(QString _name, int val = 0) : name(_name) + { + setValue(val); + } +}; + +class SettingsDialog : public QDialog +{ + Q_OBJECT + +private: + QVector<int> val; + zbar::QZBar *zbar; + zbar::zbar_symbol_type_t sym; + +private slots: + + void accept() + { + for (unsigned i = 0; i < SETTINGS_SIZE; i++) + zbar->set_config(sym, settings[i].ctrl, val[i]); + QDialog::accept(); + }; + void reject() + { + QDialog::reject(); + }; + void clicked() + { + QCheckBox *button = qobject_cast<QCheckBox *>(sender()); + if (!button) + return; + + QString name = button->text(); + + for (unsigned i = 0; i < SETTINGS_SIZE; i++) { + if (settings[i].name == name) { + val[i] = button->isChecked(); + return; + } + } + // ERROR! + }; + void update(int value) + { + IntegerSetting *setting = qobject_cast<IntegerSetting *>(sender()); + if (!setting) + return; + + for (unsigned i = 0; i < SETTINGS_SIZE; i++) { + if (settings[i].name == setting->name) { + val[i] = value; + return; + } + } + // ERROR! + }; + +public: + SettingsDialog(zbar::QZBar *_zbar, QString &name, + zbar::zbar_symbol_type_t _sym) + : zbar(_zbar), sym(_sym) + { + val = QVector<int>(SETTINGS_SIZE); + + QGridLayout *layout = new QGridLayout(this); + + this->setWindowTitle(name); + + for (unsigned i = 0; i < SETTINGS_SIZE; i++) { + int value = 0; + + if (zbar->get_config(sym, settings[i].ctrl, value)) + continue; + val[i] = value; + + if (settings[i].is_bool) { + QCheckBox *button = new QCheckBox(settings[i].name, this); + + button->setChecked(value); + + layout->addWidget(button, i, 0, 1, 2, + Qt::AlignTop | Qt::AlignLeft); + connect(button, SIGNAL(clicked()), this, SLOT(clicked())); + } else { + QLabel *label = new QLabel(settings[i].name); + + layout->addWidget(label, i, 0, 1, 1, + Qt::AlignTop | Qt::AlignLeft); + IntegerSetting *spin = + new IntegerSetting(settings[i].name, value); + layout->addWidget(spin, i, 1, 1, 1, + Qt::AlignTop | Qt::AlignLeft); + connect(spin, SIGNAL(valueChanged(int)), this, + SLOT(update(int))); + } + } + QDialogButtonBox *buttonBox = new QDialogButtonBox( + QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + layout->addWidget(buttonBox); + } +}; + +class SettingsButton : public QPushButton +{ + Q_OBJECT + +private: + QString name; + zbar::QZBar *zbar; + zbar::zbar_symbol_type_t sym; + +public: + SettingsButton(zbar::QZBar *_zbar, const QIcon &_icon, QString _name, + zbar::zbar_symbol_type_t _sym) + : QPushButton(_icon, ""), name(_name), zbar(_zbar), sym(_sym) + { + int size = font().pointSize(); + + if (size < 0) + size = font().pixelSize(); + + if (size > 0) + setIconSize(QSize(size, size)); + }; + +public Q_SLOTS: + void button_clicked() + { + SettingsButton *button = qobject_cast<SettingsButton *>(sender()); + if (!button) + return; + + QString name = button->name; + + SettingsDialog *dialog = new SettingsDialog(zbar, name, sym); + dialog->setModal(true); + dialog->show(); + } +}; + +struct CamRes { + unsigned width; + unsigned height; + float max_fps; +}; + +class ZbarcamQZBar : public QWidget +{ + Q_OBJECT + +protected: + static void add_device(QComboBox *list, const char *device) + { + list->addItem(QString(device)); + } + +public Q_SLOTS: + void turn_show_options() + { + QPushButton *button = qobject_cast<QPushButton *>(sender()); + if (!button) + return; + + show_options = !show_options; + if (show_options) { + button->setText("Hide Options"); + optionsGroup->show(); + } else { + button->setText("Show Options"); + optionsGroup->hide(); + } + } + + void turn_show_controls() + { + QPushButton *button = qobject_cast<QPushButton *>(sender()); + if (!button) + return; + + show_controls = !show_controls; + if (show_controls) { + button->setText("Hide Controls"); + controlGroup->show(); + } else { + button->setText("Show Controls"); + controlGroup->hide(); + } + } + +public: + ~ZbarcamQZBar() + { + saveSettings(); + } + ZbarcamQZBar(const QStringList *names, int verbose = 0) : resolutions(NULL) + { + // drop-down list of video devices + QComboBox *videoList = new QComboBox; + + // toggle button to disable/enable video + statusButton = new QPushButton; + + QStyle *style = QApplication::style(); + QIcon statusIcon = style->standardIcon(QStyle::SP_DialogNoButton); + QIcon yesIcon = style->standardIcon(QStyle::SP_DialogYesButton); + statusIcon.addPixmap(yesIcon.pixmap(QSize(128, 128), QIcon::Normal, + QIcon::On), + QIcon::Normal, QIcon::On); + + statusButton->setIcon(statusIcon); + statusButton->setText("&Enable"); + statusButton->setCheckable(true); + statusButton->setEnabled(false); + statusButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + // command button to open image files for scanning + QPushButton *openButton = new QPushButton("&Open"); + QIcon openIcon = style->standardIcon(QStyle::SP_DialogOpenButton); + openButton->setIcon(openIcon); + openButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + // collect video list and buttons horizontally + ZBarMenu = new QHBoxLayout; + ZBarMenu->setAlignment(Qt::AlignLeft); + ZBarMenu->addWidget(videoList, 5); + ZBarMenu->addWidget(statusButton, 1); + ZBarMenu->addWidget(openButton, 1); + + // video barcode scanner + zbar = new zbar::QZBar(NULL, verbose); + zbar->setAcceptDrops(true); + + // text box for results + QTextEdit *results = new QTextEdit; + results->setReadOnly(true); + + QGridLayout *grid = new QGridLayout; + grid->addLayout(ZBarMenu, 0, 0, 1, -1); + grid->addWidget(zbar, 1, 0, 1, 1); + grid->addWidget(results, 2, 0, 1, 1); + + // Group box where controls will be added + optionsGroup = new QGroupBox(tr("Options"), this); + QGridLayout *optionsBoxLayout = new QGridLayout(optionsGroup); + optionsGroup->setAlignment(Qt::AlignHCenter); + optionsBoxLayout->setContentsMargins(0, 0, 16, 0); + grid->addWidget(optionsGroup, 1, 1, -1, 1, Qt::AlignTop); + + controlGroup = new QGroupBox(this); + controlBoxLayout = new QGridLayout(controlGroup); + controlBoxLayout->setContentsMargins(0, 0, 0, 0); + grid->addWidget(controlGroup, 1, 2, -1, 1, Qt::AlignTop); + + loadSettings(); + zbar->request_size(curWidth, curHeight, false); + + int pos = 0; + +#ifdef HAVE_DBUS + QCheckBox *button = new QCheckBox(DBUS_NAME, this); + button->setChecked(dbus_enabled); + optionsBoxLayout->addWidget(button, ++pos, 0, 1, 1, + Qt::AlignTop | Qt::AlignLeft); + connect(button, SIGNAL(clicked()), this, SLOT(code_clicked())); + zbar->request_dbus(0); +#endif + + for (unsigned i = 0; i < CONFIGS_SIZE; i++) { + int val = 0; + + if (configs[i].sym == zbar::ZBAR_PARTIAL) { + QLabel *label = new QLabel(configs[i].name, this); + optionsBoxLayout->addWidget(label, ++pos, 0, 1, 1, + Qt::AlignTop | Qt::AlignLeft); + } else { + QCheckBox *button = new QCheckBox(configs[i].name, this); + + zbar->get_config(configs[i].sym, zbar::ZBAR_CFG_ENABLE, val); + + button->setChecked(val); + optionsBoxLayout->addWidget(button, ++pos, 0, 1, 1, + Qt::AlignTop | Qt::AlignLeft); + connect(button, SIGNAL(clicked()), this, SLOT(code_clicked())); + } + + /* Composite doesn't have configuration */ + if (configs[i].sym == zbar::ZBAR_COMPOSITE) + continue; + + QIcon icon = QIcon::fromTheme(QLatin1String("configure-toolbars")); + SettingsButton *settings = + new SettingsButton(zbar, icon, configs[i].name, configs[i].sym); + optionsBoxLayout->addWidget(settings, pos, 1, 1, 1, + Qt::AlignTop | Qt::AlignLeft); + + connect(settings, &SettingsButton::clicked, settings, + &SettingsButton::button_clicked); + } + + // Allow showing/hiding options/controls menus + QPushButton *showOptionsButton, *showControlsButton; + + if (show_options) { + showOptionsButton = new QPushButton("Hide Options"); + optionsGroup->show(); + } else { + showOptionsButton = new QPushButton("Show Options"); + optionsGroup->hide(); + } + showOptionsButton->setSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed); + ZBarMenu->addWidget(showOptionsButton); + connect(showOptionsButton, SIGNAL(clicked()), this, + SLOT(turn_show_options())); + + if (show_controls) { + showControlsButton = new QPushButton("Hide Controls"); + controlGroup->show(); + } else { + showControlsButton = new QPushButton("Show Controls"); + controlGroup->hide(); + } + showControlsButton->setSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed); + ZBarMenu->addWidget(showControlsButton); + connect(showControlsButton, SIGNAL(clicked()), this, + SLOT(turn_show_controls())); + + if (!geometry.isEmpty()) + restoreGeometry(geometry); + + setLayout(grid); + + videoList->addItem(""); + + int active = 0; + for (int i = 0; i < names->size(); i++) + active += scan_video((void *)add_device, videoList, + names->at(i).toUtf8()); + + if (names->isEmpty()) + active += scan_video((void *)add_device, videoList, NULL); + + // directly connect combo box change signal to scanner video open + connect(videoList, SIGNAL(currentIndexChanged(const QString &)), zbar, + SLOT(setVideoDevice(const QString &))); + + // directly connect status button state to video enabled state + connect(statusButton, SIGNAL(toggled(bool)), zbar, + SLOT(setVideoEnabled(bool))); + + // also update status button state when video is opened/closed + connect(zbar, SIGNAL(videoOpened(bool)), this, SLOT(setEnabled(bool))); + + // prompt for image file to scan when openButton is clicked + connect(openButton, SIGNAL(clicked()), SLOT(openImage())); + + // directly connect video scanner decode result to display in text box + connect(zbar, SIGNAL(decodedText(const QString &)), results, + SLOT(append(const QString &))); + + if (active >= 0) + videoList->setCurrentIndex(active); + } + +public Q_SLOTS: + void openImage() + { + file = QFileDialog::getOpenFileName(this, "Open Image", file, + TEST_IMAGE_FORMATS); + if (!file.isEmpty()) + zbar->scanImage(QImage(file)); + } + + void control_clicked() + { + QCheckBox *button = qobject_cast<QCheckBox *>(sender()); + if (!button) + return; + + QString name = button->text(); + bool val = button->isChecked(); + + zbar->set_control(name.toUtf8().data(), val); + } + + void code_clicked() + { + QCheckBox *button = qobject_cast<QCheckBox *>(sender()); + if (!button) + return; + + QString name = button->text(); + bool val = button->isChecked(); + + if (name == DBUS_NAME) { + zbar->request_dbus(val); + dbus_enabled = val; + return; + } + + for (unsigned i = 0; i < CONFIGS_SIZE; i++) { + if (configs[i].name == name) { + zbar->set_config(configs[i].sym, zbar::ZBAR_CFG_ENABLE, val); + return; + } + } + } + + void clearLayout(QLayout *layout) + { + QLayoutItem *item; + while ((item = layout->takeAt(0))) { + if (item->layout()) { + clearLayout(item->layout()); + delete item->layout(); + } + if (item->widget()) { + delete item->widget(); + } + delete item; + } + } + + void setVideoResolution(int index) + { + struct CamRes *cur_res; + + if (index < 0 || res.isEmpty()) + return; + + cur_res = &res[index]; + + unsigned width = zbar->videoWidth(); + unsigned height = zbar->videoHeight(); + + if (width == cur_res->width && height == cur_res->height) + return; + + zbar->request_size(cur_res->width, cur_res->height); + + curWidth = cur_res->width; + curHeight = cur_res->height; + } + + void setEnabled(bool videoEnabled) + { + zbar->setVideoEnabled(videoEnabled); + + // Update the status button + statusButton->setEnabled(videoEnabled); + statusButton->setChecked(videoEnabled); + + // Delete items before creating a new set of controls + clearLayout(controlBoxLayout); + + if (!videoEnabled) + return; + + // get_controls + loadSettings(false); + + // FIXME: clear a previous resolutions box + + bool isNewResolutions = false; + + if (!resolutions) { + resolutions = new QComboBox; + resolutions->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + isNewResolutions = true; + } + + resolutions->blockSignals(true); + res.clear(); + resolutions->clear(); + + for (int i = 0;; i++) { + QString new_res, fps; + struct CamRes cur_res; + + if (!zbar->get_resolution(i, cur_res.width, cur_res.height, + cur_res.max_fps)) + break; + + fps.setNum(cur_res.max_fps, 'f', 2); + new_res = QString("%1x%2 - %3 fps (max)") + .arg(cur_res.width) + .arg(cur_res.height) + .arg(fps); + + resolutions->addItem(new_res); + res.append(cur_res); + + if (curWidth == cur_res.width && curHeight == cur_res.height) + resolutions->setCurrentIndex(i); + } + + if (isNewResolutions) { + ZBarMenu->addWidget(resolutions); + connect(resolutions, SIGNAL(currentIndexChanged(int)), this, + SLOT(setVideoResolution(int))); + } + resolutions->blockSignals(false); + + // Restore saved resolution + unsigned width = zbar->videoWidth(); + unsigned height = zbar->videoHeight(); + + if (width != curWidth || height != curHeight) { + for (int i = 0; i < res.size(); i++) { + if (res[i].width == curWidth && res[i].height == curHeight) { + resolutions->setCurrentIndex(i); + break; + } + } + } + + int pos = 0; + QString oldGroup = ""; + for (int i = 0;; i++) { + char *name, *group; + enum zbar::QZBar::ControlType type; + int min, max, def, step; + + int ret = zbar->get_controls(i, &name, &group, &type, &min, &max, + &def, &step); + if (!ret) + break; + + QString newGroup = + "<strong>" + QString::fromUtf8(group) + " Controls</strong>"; + + if (newGroup != oldGroup) { + if (oldGroup != "") + controlBoxLayout->addItem(new QSpacerItem(0, 12), pos++, 2, + 1, 2, Qt::AlignLeft); + QLabel *label = new QLabel(newGroup); + controlBoxLayout->addWidget(label, pos++, 0, 1, 2, + Qt::AlignTop | Qt::AlignHCenter); + pos++; + oldGroup = newGroup; + } + + switch (type) { + case zbar::QZBar::Button: + case zbar::QZBar::Boolean: { + bool val; + + QCheckBox *button = new QCheckBox(name, controlGroup); + controlBoxLayout->addWidget(button, pos++, 0, 1, 2, + Qt::AlignLeft); + + if (!zbar->get_control(name, &val)) + button->setChecked(val); + else + button->setChecked(def); + connect(button, SIGNAL(clicked()), this, + SLOT(control_clicked())); + break; + } + case zbar::QZBar::Integer: { + IntegerControl *ctrl; + + QLabel *label = new QLabel(QString::fromUtf8(name)); + ctrl = new IntegerControl(controlGroup, zbar, name, min, max, + def, step); + + controlBoxLayout->addWidget(label, pos, 0, Qt::AlignLeft); + controlBoxLayout->addWidget(ctrl, pos++, 1, Qt::AlignLeft); + break; + } + case zbar::QZBar::Menu: { + MenuControl *ctrl; + + QLabel *label = new QLabel(QString::fromUtf8(name)); + + QVector<QPair<int, QString> > vector; + vector = zbar->get_menu(i); + ctrl = new MenuControl(controlGroup, zbar, name, vector); + + controlBoxLayout->addWidget(label, pos, 0, Qt::AlignLeft); + controlBoxLayout->addWidget(ctrl, pos++, 1, Qt::AlignLeft); + break; + } + default: + // Just ignore other types + break; + } + } + } + +private: + QString file; + zbar::QZBar *zbar; + QHBoxLayout *ZBarMenu; + QPushButton *statusButton; + QGroupBox *controlGroup, *optionsGroup; + QComboBox *resolutions; + QGridLayout *controlBoxLayout; + QSignalMapper *signalMapper; + bool dbus_enabled, show_options, show_controls; + QByteArray geometry; + QVector<struct CamRes> res; + unsigned curWidth, curHeight; + + void loadSettings(bool getRes = true) + { + QSettings qSettings(QCoreApplication::organizationName(), + QCoreApplication::applicationName()); + QString key; + QVariant qVal; + + geometry = qSettings.value("geometry").toByteArray(); + + key = OPTION_BAR; + qVal = qSettings.value(key, true); + show_options = qVal.toBool(); + + key = CONTROL_BAR; + qVal = qSettings.value(key, true); + show_controls = qVal.toBool(); + + if (getRes) { + qVal = qSettings.value("width"); + curWidth = qVal.toUInt(); + qVal = qSettings.value("height"); + curHeight = qVal.toUInt(); + } + +#ifdef HAVE_DBUS + key = DBUS_NAME ".enable"; + qVal = qSettings.value(key, false); + dbus_enabled = qVal.toBool(); +#endif + + qSettings.beginGroup(SYM_GROUP); + + for (unsigned i = 0; i < CONFIGS_SIZE; i++) { + int val = 0; + if (zbar->get_config(configs[i].sym, zbar::ZBAR_CFG_ENABLE, val)) + continue; + key = QString(configs[i].name) + QString(".enable"); + key.replace(" ", "_"); + qVal = qSettings.value(key, val); + zbar->set_config(configs[i].sym, zbar::ZBAR_CFG_ENABLE, + qVal.toInt()); + + if (configs[i].sym == zbar::ZBAR_COMPOSITE) + continue; + + for (unsigned j = 0; j < SETTINGS_SIZE; j++) { + int val = 0; + + if (zbar->get_config(configs[i].sym, settings[j].ctrl, val)) + continue; + key = QString(configs[i].name) + QString(".") + + QString(settings[j].name); + key.replace(" ", "_"); + + qVal = qSettings.value(key, val); + zbar->set_config(configs[i].sym, settings[j].ctrl, + qVal.toInt()); + } + } + qSettings.endGroup(); + + qSettings.beginGroup(CAM_GROUP); + for (unsigned i = 0;; i++) { + char *name, *group; + enum zbar::QZBar::ControlType type; + int min, max, def, step, val; + + int ret = zbar->get_controls(i, &name, &group, &type, &min, &max, + &def, &step); + if (!ret) + break; + + switch (type) { + case zbar::QZBar::Button: + case zbar::QZBar::Boolean: + case zbar::QZBar::Menu: + case zbar::QZBar::Integer: { + key = QString::fromUtf8(name); + + if (zbar->get_control(name, &val)) + continue; + + key.replace(QRegularExpression("[^\\w\\d]+"), "_"); + key.replace(QRegularExpression("_$"), ""); + + qVal = qSettings.value(key, val); + zbar->set_control(name, qVal.toInt()); + break; + } + default: + // Just ignore other types + break; + } + } + qSettings.endGroup(); + } + + void saveSettings() + { + QSettings qSettings(QCoreApplication::organizationName(), + QCoreApplication::applicationName()); + QString key; + unsigned int i; + + qSettings.setValue("geometry", saveGeometry()); + + key = OPTION_BAR; + qSettings.setValue(key, show_options); + + key = CONTROL_BAR; + qSettings.setValue(key, show_controls); + + curWidth = zbar->videoWidth(); + curHeight = zbar->videoHeight(); + qSettings.setValue("width", curWidth); + qSettings.setValue("height", curHeight); + +#ifdef HAVE_DBUS + // FIXME: track dbus enable-disable and store last state + key = DBUS_NAME ".enable"; + qSettings.setValue(key, dbus_enabled); +#endif + + qSettings.beginGroup(SYM_GROUP); + for (i = 0; i < CONFIGS_SIZE; i++) { + int val = 0; + + if (zbar->get_config(configs[i].sym, zbar::ZBAR_CFG_ENABLE, val)) + continue; + key = QString(configs[i].name) + QString(".enable"); + key.replace(" ", "_"); + qSettings.setValue(key, val); + + if (configs[i].sym == zbar::ZBAR_COMPOSITE) + continue; + + for (unsigned j = 0; j < SETTINGS_SIZE; j++) { + int val = 0; + + if (zbar->get_config(configs[i].sym, settings[j].ctrl, val)) + continue; + key = QString(configs[i].name) + QString(".") + + QString(settings[j].name); + key.replace(" ", "_"); + qSettings.setValue(key, val); + } + } + qSettings.endGroup(); + + for (i = 0;; i++) { + char *name, *group; + enum zbar::QZBar::ControlType type; + int min, max, def, step, val; + + int ret = zbar->get_controls(i, &name, &group, &type, &min, &max, + &def, &step); + if (!ret) + break; + + if (i == 0) + qSettings.beginGroup(CAM_GROUP); + + switch (type) { + case zbar::QZBar::Button: + case zbar::QZBar::Boolean: + case zbar::QZBar::Menu: + case zbar::QZBar::Integer: { + key = QString::fromUtf8(name); + + if (zbar->get_control(name, &val)) + continue; + + key.replace(QRegularExpression("[^\\w\\d]+"), "_"); + key.replace(QRegularExpression("_$"), ""); + qSettings.setValue(key, val); + break; + } + default: + // Just ignore other types + break; + } + } + if (i > 0) + qSettings.endGroup(); + } +}; + +#include "moc_zbarcam_qt.h" + +int main(int argc, char *argv[]) +{ + int verbose = 0; + QApplication app(argc, argv); + app.setApplicationName("zbarcam_qt"); + app.setOrganizationName("LinuxTV"); + app.setOrganizationDomain("linuxtv.org"); + app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); + + QCommandLineParser parser; + parser.setApplicationDescription("ZBar bar code reader Qt application"); + parser.addHelpOption(); + + parser.addPositionalArgument("name", QObject::tr("device or file name")); + + QCommandLineOption debugOption(QStringList() << "d" + << "debug", + QObject::tr("Enable debug mode.")); + parser.addOption(debugOption); + + QCommandLineOption verboseOption(QStringList() << "v" + << "verbosity", + QObject::tr("Verbosity level."), + QObject::tr("value")); + parser.addOption(verboseOption); + + parser.process(app); + + if (parser.isSet(verboseOption)) + verbose = parser.value(verboseOption).toInt(); + + if (parser.isSet(debugOption)) + verbose = 127; + + const QStringList args = parser.positionalArguments(); + + ZbarcamQZBar window(&args, verbose); + window.show(); + return (app.exec()); +} |