//------------------------------------------------------------------------ // Copyright 2008-2009 (c) Jeff Brown // // 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #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 > vector; private slots: void updateControl(int value); public: MenuControl(QGroupBox *parent, zbar::QZBar *_zbar, char *_name, QVector > _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 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 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(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(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(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(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(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(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(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(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 = "" + QString::fromUtf8(group) + " Controls"; 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 > 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 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()); }