File indexing completed on 2025-01-19 03:59:42

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2003-02-10
0007  * Description : camera setup tab.
0008  *
0009  * SPDX-FileCopyrightText: 2003-2005 by Renchi Raju <renchi dot raju at gmail dot com>
0010  * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "setupcamera.h"
0017 
0018 // Qt includes
0019 
0020 #include <QDateTime>
0021 #include <QGridLayout>
0022 #include <QGroupBox>
0023 #include <QHeaderView>
0024 #include <QPixmap>
0025 #include <QPointer>
0026 #include <QCheckBox>
0027 #include <QPushButton>
0028 #include <QRadioButton>
0029 #include <QButtonGroup>
0030 #include <QTreeWidget>
0031 #include <QTreeWidgetItemIterator>
0032 #include <QVBoxLayout>
0033 #include <QListWidget>
0034 #include <QApplication>
0035 #include <QStyle>
0036 #include <QComboBox>
0037 #include <QStandardPaths>
0038 #include <QIcon>
0039 #include <QMessageBox>
0040 
0041 // KDE includes
0042 
0043 #include <kconfiggroup.h>
0044 #include <ksharedconfig.h>
0045 #include <klocalizedstring.h>
0046 
0047 // Local includes
0048 
0049 #include "albumselectwidget.h"
0050 #include "cameralist.h"
0051 #include "cameraselection.h"
0052 #include "cameratype.h"
0053 #include "digikam_config.h"
0054 #include "gpcamera.h"
0055 #include "importfiltercombobox.h"
0056 #include "importfilterdlg.h"
0057 #include "dfontselect.h"
0058 #include "importsettings.h"
0059 #include "fullscreensettings.h"
0060 #include "dxmlguiwindow.h"
0061 #include "dactivelabel.h"
0062 
0063 namespace Digikam
0064 {
0065 
0066 class Q_DECL_HIDDEN SetupCameraItem : public QTreeWidgetItem
0067 {
0068 
0069 public:
0070 
0071     explicit SetupCameraItem(QTreeWidget* const parent, CameraType* const ctype)
0072         : QTreeWidgetItem(parent),
0073           m_ctype        (nullptr)
0074     {
0075         setCameraType(ctype);
0076     };
0077 
0078     ~SetupCameraItem() override
0079     {
0080         delete m_ctype;
0081     };
0082 
0083     void setCameraType(CameraType* const ctype)
0084     {
0085         delete m_ctype;
0086 
0087         m_ctype = new CameraType(*ctype);
0088 
0089         if (m_ctype)
0090         {
0091             setText(0, m_ctype->title());
0092             setText(1, m_ctype->model());
0093             setText(2, m_ctype->port());
0094             setText(3, m_ctype->path());
0095         }
0096     };
0097 
0098     CameraType* cameraType() const
0099     {
0100         return m_ctype;
0101     };
0102 
0103 private:
0104 
0105     CameraType* m_ctype;
0106 
0107 private:
0108 
0109     Q_DISABLE_COPY(SetupCameraItem)
0110 };
0111 
0112 // -------------------------------------------------------------------
0113 
0114 class Q_DECL_HIDDEN CameraAutoDetectThread::Private
0115 {
0116 public:
0117 
0118     explicit Private()
0119       : result(0)
0120     {
0121     }
0122 
0123     int     result;
0124 
0125     QString model;
0126     QString port;
0127 };
0128 
0129 CameraAutoDetectThread::CameraAutoDetectThread(QObject* const parent)
0130     : DBusyThread(parent),
0131       d          (new Private)
0132 {
0133     d->result = -1;
0134 }
0135 
0136 CameraAutoDetectThread::~CameraAutoDetectThread()
0137 {
0138     delete d;
0139 }
0140 
0141 void CameraAutoDetectThread::run()
0142 {
0143     d->result = GPCamera::autoDetect(d->model, d->port);
0144 
0145     Q_EMIT signalComplete();
0146 }
0147 
0148 int CameraAutoDetectThread::result() const
0149 {
0150     return(d->result);
0151 }
0152 
0153 QString CameraAutoDetectThread::model() const
0154 {
0155     return(d->model);
0156 }
0157 
0158 QString CameraAutoDetectThread::port() const
0159 {
0160     return(d->port);
0161 }
0162 
0163 // -------------------------------------------------------------------
0164 
0165 class Q_DECL_HIDDEN SetupCamera::Private
0166 {
0167 public:
0168 
0169     explicit Private()
0170       : addButton                   (nullptr),
0171         removeButton                (nullptr),
0172         editButton                  (nullptr),
0173         autoDetectButton            (nullptr),
0174         importAddButton             (nullptr),
0175         importRemoveButton          (nullptr),
0176         importEditButton            (nullptr),
0177         storeDiffButton             (nullptr),
0178         overwriteButton             (nullptr),
0179         skipFileButton              (nullptr),
0180         conflictButtonGroup         (nullptr),
0181         useFileMetadata             (nullptr),
0182         turnHighQualityThumbs       (nullptr),
0183         useDefaultTargetAlbum       (nullptr),
0184         iconShowNameBox             (nullptr),
0185         iconShowSizeBox             (nullptr),
0186         iconShowDateBox             (nullptr),
0187         iconShowResolutionBox       (nullptr),
0188         iconShowTagsBox             (nullptr),
0189         iconShowOverlaysBox         (nullptr),
0190         iconShowRatingBox           (nullptr),
0191         iconShowFormatBox           (nullptr),
0192         iconShowCoordinatesBox      (nullptr),
0193         previewLoadFullImageSize    (nullptr),
0194         previewItemsWhileDownload   (nullptr),
0195         previewShowIcons            (nullptr),
0196         leftClickActionComboBox     (nullptr),
0197         iconViewFontSelect          (nullptr),
0198         target1AlbumSelector        (nullptr),
0199         listView                    (nullptr),
0200         importListView              (nullptr),
0201         tab                         (nullptr),
0202         ignoreNamesEdit             (nullptr),
0203         ignoreExtensionsEdit        (nullptr),
0204         fullScreenSettings          (nullptr)
0205     {
0206     }
0207 
0208     static const QString configGroupName;
0209     static const QString configUseFileMetadata;
0210     static const QString configTrunHighQualityThumbs;
0211     static const QString configUseDefaultTargetAlbum;
0212     static const QString configDefaultTargetAlbumId;
0213     static const QString configFileSaveConflictRule;
0214     static const QString importFiltersConfigGroupName;
0215 
0216     QPushButton*         addButton;
0217     QPushButton*         removeButton;
0218     QPushButton*         editButton;
0219     QPushButton*         autoDetectButton;
0220     QPushButton*         importAddButton;
0221     QPushButton*         importRemoveButton;
0222     QPushButton*         importEditButton;
0223 
0224     QRadioButton*        storeDiffButton;
0225     QRadioButton*        overwriteButton;
0226     QRadioButton*        skipFileButton;
0227 
0228     QButtonGroup*        conflictButtonGroup;
0229 
0230     QCheckBox*           useFileMetadata;
0231     QCheckBox*           turnHighQualityThumbs;
0232     QCheckBox*           useDefaultTargetAlbum;
0233 
0234     QCheckBox*           iconShowNameBox;
0235     QCheckBox*           iconShowSizeBox;
0236     QCheckBox*           iconShowDateBox;
0237     QCheckBox*           iconShowResolutionBox;
0238     QCheckBox*           iconShowTagsBox;
0239     QCheckBox*           iconShowOverlaysBox;
0240     QCheckBox*           iconShowRatingBox;
0241     QCheckBox*           iconShowFormatBox;
0242     QCheckBox*           iconShowCoordinatesBox;
0243     QCheckBox*           previewLoadFullImageSize;
0244     QCheckBox*           previewItemsWhileDownload;
0245     QCheckBox*           previewShowIcons;
0246 
0247     QComboBox*           leftClickActionComboBox;
0248 
0249     DFontSelect*         iconViewFontSelect;
0250 
0251 
0252     AlbumSelectWidget*   target1AlbumSelector;
0253 
0254     QTreeWidget*         listView;
0255     QListWidget*         importListView;
0256 
0257     QTabWidget*          tab;
0258 
0259     QLineEdit*           ignoreNamesEdit;
0260     QLineEdit*           ignoreExtensionsEdit;
0261 
0262     FilterList           filters;
0263 
0264     FullScreenSettings*  fullScreenSettings;
0265 };
0266 
0267 const QString SetupCamera::Private::configGroupName(QLatin1String("Camera Settings"));
0268 const QString SetupCamera::Private::configUseFileMetadata(QLatin1String("UseFileMetadata"));
0269 const QString SetupCamera::Private::configTrunHighQualityThumbs(QLatin1String("TurnHighQualityThumbs"));
0270 const QString SetupCamera::Private::configUseDefaultTargetAlbum(QLatin1String("UseDefaultTargetAlbum"));
0271 const QString SetupCamera::Private::configDefaultTargetAlbumId(QLatin1String("DefaultTargetAlbumId"));
0272 const QString SetupCamera::Private::configFileSaveConflictRule(QLatin1String("FileSaveConflictRule"));
0273 const QString SetupCamera::Private::importFiltersConfigGroupName(QLatin1String("Import Filters"));
0274 
0275 SetupCamera::SetupCamera(QWidget* const parent)
0276     : QScrollArea(parent),
0277       d          (new Private)
0278 {
0279     d->tab               = new QTabWidget(viewport());
0280     setWidget(d->tab);
0281     setWidgetResizable(true);
0282 
0283     const int spacing    = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0284                              QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0285 
0286     QWidget* const panel = new QWidget(d->tab);
0287 
0288     QGridLayout* const grid = new QGridLayout(panel);
0289     d->listView             = new QTreeWidget(panel);
0290     d->listView->sortItems(0, Qt::AscendingOrder);
0291     d->listView->setColumnCount(4);
0292     d->listView->setRootIsDecorated(false);
0293     d->listView->setSelectionMode(QAbstractItemView::SingleSelection);
0294     d->listView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0295     d->listView->setAllColumnsShowFocus(true);
0296     d->listView->setWhatsThis(i18n("Here you can see the digital camera list used by digiKam "
0297                                    "via the Gphoto interface."));
0298 
0299     QStringList labels;
0300     labels.append(i18nc("@title: camera title",      "Title"));
0301     labels.append(i18nc("@title: camera model",      "Model"));
0302     labels.append(i18nc("@title: camera port",       "Port"));
0303     labels.append(i18nc("@title: camera mount path", "Path"));
0304     d->listView->setHeaderLabels(labels);
0305     d->listView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
0306     d->listView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
0307     d->listView->header()->setSectionResizeMode(2, QHeaderView::Stretch);
0308     d->listView->header()->setSectionResizeMode(3, QHeaderView::Stretch);
0309 
0310     // -------------------------------------------------------------
0311 
0312     d->addButton        = new QPushButton(panel);
0313     d->removeButton     = new QPushButton(panel);
0314     d->editButton       = new QPushButton(panel);
0315     d->autoDetectButton = new QPushButton(panel);
0316 
0317     d->addButton->setText(i18n("&Add..."));
0318     d->addButton->setIcon(QIcon::fromTheme(QLatin1String("list-add")));
0319     d->removeButton->setText(i18n("&Remove"));
0320     d->removeButton->setIcon(QIcon::fromTheme(QLatin1String("list-remove")));
0321     d->editButton->setText(i18n("&Edit..."));
0322     d->editButton->setIcon(QIcon::fromTheme(QLatin1String("configure")));
0323     d->autoDetectButton->setText(i18n("Auto-&Detect"));
0324     d->autoDetectButton->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
0325     d->removeButton->setEnabled(false);
0326     d->editButton->setEnabled(false);
0327 
0328     // -------------------------------------------------------------
0329 
0330     QSpacerItem* const spacer           = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
0331     DActiveLabel* const gphotoLogoLabel = new DActiveLabel(QUrl(QLatin1String("http://www.gphoto.org")),        // krazy:exclude=insecurenet
0332                                                            QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/logo-gphoto.png")),
0333                                                            panel);
0334     gphotoLogoLabel->setToolTip(i18n("Visit Gphoto project website"));
0335 
0336 #ifndef HAVE_GPHOTO2
0337 
0338     // If digiKam is compiled without Gphoto2 support, we hide widgets relevant.
0339     d->autoDetectButton->hide();
0340     gphotoLogoLabel->hide();
0341 
0342 #endif // HAVE_GPHOTO2
0343 
0344     // -------------------------------------------------------------
0345 
0346     grid->setContentsMargins(spacing, spacing, spacing, spacing);
0347     grid->setSpacing(spacing);
0348     grid->setAlignment(Qt::AlignTop);
0349     grid->addWidget(d->listView,         0, 0, 6, 1);
0350     grid->addWidget(d->addButton,        0, 1, 1, 1);
0351     grid->addWidget(d->removeButton,     1, 1, 1, 1);
0352     grid->addWidget(d->editButton,       2, 1, 1, 1);
0353     grid->addWidget(d->autoDetectButton, 3, 1, 1, 1);
0354     grid->addItem(spacer,                4, 1, 1, 1);
0355     grid->addWidget(gphotoLogoLabel,     5, 1, 1, 1);
0356 
0357     d->tab->insertTab(Devices, panel, i18n("Devices"));
0358 
0359     // -------------------------------------------------------------
0360 
0361     QWidget* const panel2     = new QWidget(d->tab);
0362 
0363     QVBoxLayout* const layout = new QVBoxLayout(panel2);
0364     d->useFileMetadata        = new QCheckBox(i18n("Use file metadata (makes connection slower)"), panel2);
0365     d->turnHighQualityThumbs  = new QCheckBox(i18n("Turn on high quality thumbnail loading (slower loading)"), panel2);
0366     d->useDefaultTargetAlbum  = new QCheckBox(i18n("Use a default target album to download from camera"), panel2);
0367     d->target1AlbumSelector   = new AlbumSelectWidget(panel2);
0368 
0369     QGroupBox* const conflictBox = new QGroupBox(panel2);
0370     QLabel* const conflictIcon   = new QLabel(conflictBox);
0371     conflictIcon->setPixmap(QIcon::fromTheme(QLatin1String("document-save-as")).pixmap(32));
0372     QLabel* const conflictLabel  = new QLabel(i18n("If target file exists when downloaded from camera"), conflictBox);
0373     QGridLayout* const boxLayout = new QGridLayout(conflictBox);
0374     d->conflictButtonGroup       = new QButtonGroup(conflictBox);
0375     d->storeDiffButton           = new QRadioButton(i18n("Store as a different name"), conflictBox);
0376     d->overwriteButton           = new QRadioButton(i18n("Overwrite automatically"),   conflictBox);
0377     d->skipFileButton            = new QRadioButton(i18n("Skip automatically"),        conflictBox);
0378     d->conflictButtonGroup->addButton(d->overwriteButton, OVERWRITE);
0379     d->conflictButtonGroup->addButton(d->storeDiffButton, DIFFNAME);
0380     d->conflictButtonGroup->addButton(d->skipFileButton,  SKIPFILE);
0381     d->conflictButtonGroup->setExclusive(true);
0382     d->storeDiffButton->setChecked(true);
0383 
0384     boxLayout->setContentsMargins(spacing, spacing, spacing, spacing);
0385     boxLayout->setSpacing(spacing);
0386     boxLayout->addWidget(conflictIcon,       0, 0);
0387     boxLayout->addWidget(conflictLabel,      0, 1);
0388     boxLayout->addWidget(d->storeDiffButton, 1, 0, 1, 3);
0389     boxLayout->addWidget(d->overwriteButton, 2, 0, 1, 3);
0390     boxLayout->addWidget(d->skipFileButton,  3, 0, 1, 3);
0391     boxLayout->setColumnStretch(2, 1);
0392     conflictBox->setLayout(boxLayout);
0393 
0394     d->tab->insertTab(Behavior, panel2, i18n("Behavior"));
0395 
0396     layout->setContentsMargins(spacing, spacing, spacing, spacing);
0397     layout->setSpacing(spacing);
0398     layout->addWidget(d->useFileMetadata);
0399     layout->addWidget(d->turnHighQualityThumbs);
0400     layout->addWidget(d->useDefaultTargetAlbum);
0401     layout->addWidget(d->target1AlbumSelector);
0402     layout->addWidget(conflictBox);
0403     layout->addStretch();
0404 
0405     // -------------------------------------------------------------
0406 
0407     QWidget* const panel3         = new QWidget(d->tab);
0408 
0409     QGridLayout* const importGrid = new QGridLayout(panel3);
0410     d->importListView             = new QListWidget(panel3);
0411     d->importListView->setSelectionMode(QAbstractItemView::SingleSelection);
0412     d->importListView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0413     d->importListView->setWhatsThis(i18n("Here you can see filters that can be used to filter "
0414                                          "files in import dialog."));
0415 
0416     d->importAddButton         = new QPushButton(panel3);
0417     d->importRemoveButton      = new QPushButton(panel3);
0418     d->importEditButton        = new QPushButton(panel3);
0419     QSpacerItem* const spacer2 = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
0420 
0421     QGroupBox* const groupBox         = new QGroupBox(panel3);
0422     QVBoxLayout* const verticalLayout = new QVBoxLayout(groupBox);
0423     QLabel* const label               = new QLabel(groupBox);
0424     verticalLayout->addWidget(label);
0425     d->ignoreNamesEdit                = new QLineEdit(groupBox);
0426     d->ignoreNamesEdit->setToolTip(i18n("Use a space as a separator to specify "
0427                                         "multiple file names to ignore."));
0428     verticalLayout->addWidget(d->ignoreNamesEdit);
0429     QLabel* const label2              = new QLabel(groupBox);
0430     verticalLayout->addWidget(label2);
0431     d->ignoreExtensionsEdit           = new QLineEdit(groupBox);
0432     d->ignoreExtensionsEdit->setToolTip(i18n("Use a space as a separator to specify "
0433                                              "multiple file extensions to ignore."));
0434     verticalLayout->addWidget(d->ignoreExtensionsEdit);
0435 
0436     groupBox->setTitle(i18n("Always ignore"));
0437     label->setText(i18n("Ignored file names:"));
0438     label2->setText(i18n("Ignored file extensions:"));
0439     d->importAddButton->setText(i18n("&Add..."));
0440     d->importAddButton->setIcon(QIcon::fromTheme(QLatin1String("list-add")));
0441     d->importRemoveButton->setText(i18n("&Remove"));
0442     d->importRemoveButton->setIcon(QIcon::fromTheme(QLatin1String("list-remove")));
0443     d->importEditButton->setText(i18n("&Edit..."));
0444     d->importEditButton->setIcon(QIcon::fromTheme(QLatin1String("configure")));
0445     d->importRemoveButton->setEnabled(false);
0446     d->importEditButton->setEnabled(false);
0447 
0448     importGrid->setContentsMargins(spacing, spacing, spacing, spacing);
0449     importGrid->setSpacing(spacing);
0450     importGrid->setAlignment(Qt::AlignTop);
0451     importGrid->addWidget(d->importListView,     0, 0, 4, 1);
0452     importGrid->addWidget(groupBox,              5, 0, 1, 1);
0453     importGrid->addWidget(d->importAddButton,    0, 1, 1, 1);
0454     importGrid->addWidget(d->importRemoveButton, 1, 1, 1, 1);
0455     importGrid->addWidget(d->importEditButton,   2, 1, 1, 1);
0456     importGrid->addItem(spacer2,                 3, 1, 1, 1);
0457 
0458     d->tab->insertTab(ImportFilters, panel3, i18n("Import Filters"));
0459 
0460     // -- Import Icon View ----------------------------------------------------------
0461 
0462     QWidget* const panel4      = new QWidget(d->tab);
0463 
0464     QVBoxLayout* const layout2 = new QVBoxLayout(panel4);
0465 
0466     QGroupBox* const iconViewGroup = new QGroupBox(i18n("Icon-View Options"), panel4);
0467     QGridLayout* const grid2       = new QGridLayout(iconViewGroup);
0468 
0469     d->iconShowNameBox       = new QCheckBox(i18n("Show file&name"), iconViewGroup);
0470     d->iconShowNameBox->setWhatsThis(i18n("Set this option to show the filename below the image thumbnail."));
0471 
0472     d->iconShowSizeBox       = new QCheckBox(i18n("Show file si&ze"), iconViewGroup);
0473     d->iconShowSizeBox->setWhatsThis(i18n("Set this option to show the file size below the image thumbnail."));
0474 
0475     d->iconShowDateBox       = new QCheckBox(i18n("Show camera creation &date"), iconViewGroup);
0476     d->iconShowDateBox->setWhatsThis(i18n("Set this option to show the camera creation date "
0477                                              "below the image thumbnail."));
0478 
0479 /*
0480     d->iconShowResolutionBox = new QCheckBox(i18n("Show ima&ge dimensions"), iconViewGroup);
0481     d->iconShowResolutionBox->setWhatsThis(i18n("Set this option to show the image size in pixels "
0482                                                 "below the image thumbnail."));
0483 */
0484 
0485     d->iconShowFormatBox      = new QCheckBox(i18n("Show image Format"), iconViewGroup);
0486     d->iconShowFormatBox->setWhatsThis(i18n("Set this option to show image format over image thumbnail."));
0487 
0488     d->iconShowCoordinatesBox = new QCheckBox(i18n("Show Geolocation Indicator"), iconViewGroup);
0489     d->iconShowCoordinatesBox->setWhatsThis(i18n("Set this option to indicate if image has geolocation information."));
0490 
0491     d->iconShowTagsBox        = new QCheckBox(i18n("Show digiKam &tags"), iconViewGroup);
0492     d->iconShowTagsBox->setWhatsThis(i18n("Set this option to show the digiKam tags "
0493                                           "below the image thumbnail."));
0494 
0495     d->iconShowRatingBox      = new QCheckBox(i18n("Show item &rating"), iconViewGroup);
0496     d->iconShowRatingBox->setWhatsThis(i18n("Set this option to show the item rating "
0497                                             "below the image thumbnail."));
0498 
0499     d->iconShowOverlaysBox    = new QCheckBox(i18n("Show rotation overlay buttons"), iconViewGroup);
0500     d->iconShowOverlaysBox->setWhatsThis(i18n("Set this option to show overlay buttons on "
0501                                               "the image thumbnail for image rotation."));
0502 
0503     QLabel* const leftClickLabel = new QLabel(i18n("Thumbnail click action:"), iconViewGroup);
0504     d->leftClickActionComboBox   = new QComboBox(iconViewGroup);
0505     d->leftClickActionComboBox->addItem(i18n("Show embedded preview"),         ImportSettings::ShowPreview);
0506     d->leftClickActionComboBox->addItem(i18n("Start image editor"),            ImportSettings::StartEditor);
0507     d->leftClickActionComboBox->addItem(i18n("Open With Default Application"), ImportSettings::OpenDefault);
0508     d->leftClickActionComboBox->setToolTip(i18n("Choose what should happen when you click on a thumbnail."));
0509 
0510     d->iconViewFontSelect = new DFontSelect(i18n("Icon View font:"), panel);
0511     d->iconViewFontSelect->setToolTip(i18n("Select here the font used to display text in Icon Views."));
0512 
0513     grid2->addWidget(d->iconShowNameBox,          0, 0, 1, 1);
0514     grid2->addWidget(d->iconShowSizeBox,          1, 0, 1, 1);
0515     grid2->addWidget(d->iconShowDateBox,          2, 0, 1, 1);
0516     grid2->addWidget(d->iconShowFormatBox,        3, 0, 1, 1);
0517 /*
0518     TODO
0519     grid2->addWidget(d->iconShowResolutionBox,    4, 0, 1, 1);
0520 */
0521     grid2->addWidget(d->iconShowTagsBox,          0, 1, 1, 1);
0522     grid2->addWidget(d->iconShowRatingBox,        1, 1, 1, 1);
0523     grid2->addWidget(d->iconShowOverlaysBox,      2, 1, 1, 1);
0524     grid2->addWidget(d->iconShowCoordinatesBox,   3, 1, 1, 1);
0525     grid2->addWidget(leftClickLabel,              5, 0, 1, 1);
0526     grid2->addWidget(d->leftClickActionComboBox,  5, 1, 1, 1);
0527     grid2->addWidget(d->iconViewFontSelect,       6, 0, 1, 2);
0528     grid2->setContentsMargins(spacing, spacing, spacing, spacing);
0529     grid2->setSpacing(spacing);
0530 
0531     // --------------------------------------------------------
0532 
0533     QGroupBox* const interfaceOptionsGroup = new QGroupBox(i18n("Preview Options"), panel4);
0534     QGridLayout* const grid3               = new QGridLayout(interfaceOptionsGroup);
0535 
0536     d->previewLoadFullImageSize  = new QCheckBox(i18n("Embedded preview loads full-sized images"), interfaceOptionsGroup);
0537     d->previewLoadFullImageSize->setWhatsThis(i18n("<p>Set this option to load images at their full size "
0538                                                    "for preview, rather than at a reduced size. As this option "
0539                                                    "will make it take longer to load images, only use it if you have "
0540                                                    "a fast computer.</p>"
0541                                                    "<p><b>Note:</b> for Raw images, a half size version of the Raw data "
0542                                                    "is used instead of the embedded JPEG preview.</p>"));
0543 
0544     d->previewItemsWhileDownload = new QCheckBox(i18n("Preview each item while downloading it"), interfaceOptionsGroup);
0545     d->previewItemsWhileDownload->setWhatsThis(i18n("<p>Set this option to preview each item while downloading.</p>"));
0546 
0547     d->previewShowIcons          = new QCheckBox(i18n("Show icons and text over preview"), interfaceOptionsGroup);
0548     d->previewShowIcons->setWhatsThis(i18n("Uncheck this if you do not want to see icons and text in the image preview."));
0549 
0550     grid3->setContentsMargins(spacing, spacing, spacing, spacing);
0551     grid3->setSpacing(spacing);
0552     grid3->addWidget(d->previewLoadFullImageSize,  0, 0, 1, 2);
0553     grid3->addWidget(d->previewItemsWhileDownload, 1, 0, 1, 2);
0554     grid3->addWidget(d->previewShowIcons,          2, 0, 1, 2);
0555 
0556     // --------------------------------------------------------
0557 
0558     d->fullScreenSettings = new FullScreenSettings(FS_IMPORTUI, panel4);
0559 
0560     layout2->setContentsMargins(QMargins());
0561     layout2->setSpacing(spacing);
0562     layout2->addWidget(iconViewGroup);
0563     layout2->addWidget(interfaceOptionsGroup);
0564     layout2->addWidget(d->fullScreenSettings);
0565     layout2->addStretch();
0566 
0567     d->tab->insertTab(ImportWindow, panel4, i18nc("@title:tab import tool GUI settings", "Import Window"));
0568 
0569     // -------------------------------------------------------------
0570 
0571     adjustSize();
0572 
0573     // -------------------------------------------------------------
0574 
0575     connect(d->listView, SIGNAL(itemSelectionChanged()),
0576             this, SLOT(slotSelectionChanged()));
0577 
0578     connect(d->addButton, SIGNAL(clicked()),
0579             this, SLOT(slotAddCamera()));
0580 
0581     connect(d->removeButton, SIGNAL(clicked()),
0582             this, SLOT(slotRemoveCamera()));
0583 
0584     connect(d->editButton, SIGNAL(clicked()),
0585             this, SLOT(slotEditCamera()));
0586 
0587     connect(d->autoDetectButton, SIGNAL(clicked()),
0588             this, SLOT(slotAutoDetectCamera()));
0589 
0590     connect(d->useDefaultTargetAlbum, SIGNAL(toggled(bool)),
0591             d->target1AlbumSelector, SLOT(setEnabled(bool)));
0592 
0593     connect(d->previewItemsWhileDownload, SIGNAL(clicked()),
0594             this, SLOT(slotPreviewItemsClicked()));
0595 
0596     connect(d->previewLoadFullImageSize, SIGNAL(clicked()),
0597             this, SLOT(slotPreviewFullImageSizeClicked()));
0598 
0599     // -------------------------------------------------------------
0600 
0601     connect(d->importListView, SIGNAL(itemSelectionChanged()),
0602             this, SLOT(slotImportSelectionChanged()));
0603 
0604     connect(d->importAddButton, SIGNAL(clicked()),
0605             this, SLOT(slotAddFilter()));
0606 
0607     connect(d->importRemoveButton, SIGNAL(clicked()),
0608             this, SLOT(slotRemoveFilter()));
0609 
0610     connect(d->importEditButton, SIGNAL(clicked()),
0611             this, SLOT(slotEditFilter()));
0612 
0613     // -------------------------------------------------------------
0614 
0615     connect(d->useFileMetadata, SIGNAL(toggled(bool)),
0616             this, SIGNAL(signalUseFileMetadataChanged(bool)));
0617 
0618     // -------------------------------------------------------------
0619 
0620     readSettings();
0621 }
0622 
0623 SetupCamera::~SetupCamera()
0624 {
0625     delete d;
0626 }
0627 
0628 void SetupCamera::setActiveTab(CameraTab tab)
0629 {
0630     d->tab->setCurrentIndex(tab);
0631 }
0632 
0633 SetupCamera::CameraTab SetupCamera::activeTab() const
0634 {
0635     return (CameraTab)d->tab->currentIndex();
0636 }
0637 
0638 bool SetupCamera::useFileMetadata()
0639 {
0640     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0641     KConfigGroup group        = config->group(d->configGroupName);
0642 
0643     return (group.readEntry(d->configUseFileMetadata, false));
0644 }
0645 
0646 void SetupCamera::readSettings()
0647 {
0648     // Populate cameras --------------------------------------
0649 
0650     CameraList* const clist = CameraList::defaultList();
0651 
0652     if (clist)
0653     {
0654         QList<CameraType*>* const cl = clist->cameraList();
0655 
0656         Q_FOREACH (CameraType* const ctype, *cl)
0657         {
0658             new SetupCameraItem(d->listView, ctype);
0659         }
0660     }
0661 
0662     // -------------------------------------------------------
0663 
0664     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0665     KConfigGroup group        = config->group(d->configGroupName);
0666 
0667     d->useFileMetadata->setChecked(useFileMetadata());
0668     d->turnHighQualityThumbs->setChecked(group.readEntry(d->configTrunHighQualityThumbs, false));
0669     d->useDefaultTargetAlbum->setChecked(group.readEntry(d->configUseDefaultTargetAlbum, false));
0670     PAlbum* const album = AlbumManager::instance()->findPAlbum(group.readEntry(d->configDefaultTargetAlbumId, 0));
0671     d->target1AlbumSelector->setCurrentAlbum(album);
0672     d->target1AlbumSelector->setEnabled(d->useDefaultTargetAlbum->isChecked());
0673     d->conflictButtonGroup->button(group.readEntry(d->configFileSaveConflictRule, (int)DIFFNAME))->setChecked(true);
0674 
0675     d->fullScreenSettings->readSettings(group);
0676 
0677     // -------------------------------------------------------
0678 
0679     KConfigGroup importGroup = config->group(d->importFiltersConfigGroupName);
0680 
0681     for (int i = 0 ; true ; ++i)
0682     {
0683         QString filter = importGroup.readEntry(QString::fromUtf8("Filter%1").arg(i), QString());
0684 
0685         if (filter.isEmpty())
0686         {
0687             break;
0688         }
0689 
0690         Filter* const f = new Filter;
0691         f->fromString(filter);
0692         d->filters.append(f);
0693     }
0694 
0695     ImportFilterComboBox::defaultFilters(&d->filters);
0696 
0697     Q_FOREACH (Filter* const f, d->filters)
0698     {
0699         new QListWidgetItem(f->name, d->importListView);
0700     }
0701 
0702     d->importListView->sortItems();
0703 
0704     d->ignoreNamesEdit->setText(importGroup.readEntry(QLatin1String("IgnoreNames"), ImportFilterComboBox::defaultIgnoreNames));
0705     d->ignoreExtensionsEdit->setText(importGroup.readEntry(QLatin1String("IgnoreExtensions"), ImportFilterComboBox::defaultIgnoreExtensions));
0706 
0707     ImportSettings* const settings = ImportSettings::instance();
0708 
0709     if (!settings)
0710     {
0711         return;
0712     }
0713 
0714     d->iconShowNameBox->setChecked(settings->getIconShowName());
0715     d->iconShowTagsBox->setChecked(settings->getIconShowTags());
0716     d->iconShowSizeBox->setChecked(settings->getIconShowSize());
0717     d->iconShowDateBox->setChecked(settings->getIconShowDate());
0718 /*
0719     TODO
0720     d->iconShowResolutionBox->setChecked(settings->getIconShowResolution());
0721 */
0722     d->iconShowOverlaysBox->setChecked(settings->getIconShowOverlays());
0723     d->iconShowRatingBox->setChecked(settings->getIconShowRating());
0724     d->iconShowFormatBox->setChecked(settings->getIconShowImageFormat());
0725     d->iconShowCoordinatesBox->setChecked(settings->getIconShowCoordinates());
0726     d->iconViewFontSelect->setFont(settings->getIconViewFont());
0727 
0728     d->leftClickActionComboBox->setCurrentIndex(settings->getItemLeftClickAction());
0729 
0730     d->previewLoadFullImageSize->setChecked(settings->getPreviewLoadFullImageSize());
0731     d->previewItemsWhileDownload->setChecked(settings->getPreviewItemsWhileDownload());
0732     d->previewShowIcons->setChecked(settings->getPreviewShowIcons());
0733 }
0734 
0735 void SetupCamera::applySettings()
0736 {
0737     // Save camera devices -----------------------------------
0738 
0739     CameraList* const clist = CameraList::defaultList();
0740 
0741     if (clist)
0742     {
0743         clist->clear();
0744 
0745         QTreeWidgetItemIterator it(d->listView);
0746 
0747         while (*it)
0748         {
0749             SetupCameraItem* const item = dynamic_cast<SetupCameraItem*>(*it);
0750 
0751             if (item)
0752             {
0753                 CameraType* const ctype = item->cameraType();
0754 
0755                 if (ctype)
0756                 {
0757                     clist->insert(new CameraType(*ctype));
0758                 }
0759             }
0760 
0761             ++it;
0762         }
0763 
0764         clist->save();
0765     }
0766 
0767     // -------------------------------------------------------
0768 
0769     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0770     KConfigGroup group        = config->group(d->configGroupName);
0771 
0772     group.writeEntry(d->configUseFileMetadata,  d->useFileMetadata->isChecked());
0773     group.writeEntry(d->configTrunHighQualityThumbs, d->turnHighQualityThumbs->isChecked());
0774     group.writeEntry(d->configUseDefaultTargetAlbum, d->useDefaultTargetAlbum->isChecked());
0775     PAlbum* const album = d->target1AlbumSelector->currentAlbum();
0776     group.writeEntry(d->configDefaultTargetAlbumId, album ? album->id() : 0);
0777     group.writeEntry(d->configFileSaveConflictRule, d->conflictButtonGroup->checkedId());
0778 
0779     d->fullScreenSettings->saveSettings(group);
0780 
0781     group.sync();
0782 
0783     // -------------------------------------------------------
0784 
0785     KConfigGroup importGroup = config->group(d->importFiltersConfigGroupName);
0786 
0787     importGroup.deleteGroup();
0788 
0789     for (int i = 0 ; i < d->filters.count() ; ++i)
0790     {
0791         importGroup.writeEntry(QString::fromUtf8("Filter%1").arg(i), d->filters[i]->toString());
0792     }
0793 
0794     importGroup.writeEntry(QLatin1String("IgnoreNames"), d->ignoreNamesEdit->text());
0795     importGroup.writeEntry(QLatin1String("IgnoreExtensions"), d->ignoreExtensionsEdit->text());
0796     importGroup.sync();
0797 
0798     ImportSettings* const settings = ImportSettings::instance();
0799 
0800     if (!settings)
0801     {
0802         return;
0803     }
0804 
0805     settings->setIconShowName(d->iconShowNameBox->isChecked());
0806     settings->setIconShowTags(d->iconShowTagsBox->isChecked());
0807     settings->setIconShowSize(d->iconShowSizeBox->isChecked());
0808     settings->setIconShowDate(d->iconShowDateBox->isChecked());
0809 /*
0810     TODO
0811     settings->setIconShowResolution(d->iconShowResolutionBox->isChecked());
0812 */
0813     settings->setIconShowOverlays(d->iconShowOverlaysBox->isChecked());
0814     settings->setIconShowRating(d->iconShowRatingBox->isChecked());
0815     settings->setIconShowImageFormat(d->iconShowFormatBox->isChecked());
0816     settings->setIconShowCoordinates(d->iconShowCoordinatesBox->isChecked());
0817     settings->setIconViewFont(d->iconViewFontSelect->font());
0818 
0819     settings->setItemLeftClickAction(d->leftClickActionComboBox->currentIndex());
0820     settings->setPreviewLoadFullImageSize(d->previewLoadFullImageSize->isChecked());
0821     settings->setPreviewItemsWhileDownload(d->previewItemsWhileDownload->isChecked());
0822     settings->setPreviewShowIcons(d->previewShowIcons->isChecked());
0823     settings->saveSettings();
0824 }
0825 
0826 bool SetupCamera::checkSettings()
0827 {
0828     if (d->useDefaultTargetAlbum->isChecked() && !d->target1AlbumSelector->currentAlbum())
0829     {
0830         d->tab->setCurrentIndex(1);
0831         QMessageBox::information(this, qApp->applicationName(), i18n("No default target album have been selected to process download "
0832                                                                      "from camera device. Please select one."));
0833         return false;
0834     }
0835 
0836     return true;
0837 }
0838 
0839 void SetupCamera::slotSelectionChanged()
0840 {
0841     QTreeWidgetItem* const item = d->listView->currentItem();
0842 
0843     if (!item)
0844     {
0845         d->removeButton->setEnabled(false);
0846         d->editButton->setEnabled(false);
0847         return;
0848     }
0849 
0850     d->removeButton->setEnabled(true);
0851     d->editButton->setEnabled(true);
0852 }
0853 
0854 void SetupCamera::slotAddCamera()
0855 {
0856     CameraSelection* const select = new CameraSelection;
0857 
0858     connect(select, SIGNAL(signalOkClicked(QString,QString,QString,QString)),
0859             this,   SLOT(slotAddedCamera(QString,QString,QString,QString)));
0860 
0861     select->show();
0862 }
0863 
0864 void SetupCamera::slotAddedCamera(const QString& title, const QString& model,
0865                                   const QString& port,  const QString& path)
0866 {
0867     CameraType ctype(title, model, port, path, 1);
0868     new SetupCameraItem(d->listView, &ctype);
0869 }
0870 
0871 void SetupCamera::slotRemoveCamera()
0872 {
0873     SetupCameraItem* const item = dynamic_cast<SetupCameraItem*>(d->listView->currentItem());
0874 
0875     delete item;
0876 }
0877 
0878 void SetupCamera::slotEditCamera()
0879 {
0880     SetupCameraItem* const item = dynamic_cast<SetupCameraItem*>(d->listView->currentItem());
0881 
0882     if (!item)
0883     {
0884         return;
0885     }
0886 
0887     CameraType* const ctype = item->cameraType();
0888 
0889     if (!ctype)
0890     {
0891         return;
0892     }
0893 
0894     CameraSelection* const select = new CameraSelection;
0895     select->setCamera(ctype->title(), ctype->model(), ctype->port(), ctype->path());
0896 
0897     connect(select, SIGNAL(signalOkClicked(QString,QString,QString,QString)),
0898             this,   SLOT(slotEditedCamera(QString,QString,QString,QString)));
0899 
0900     select->show();
0901 }
0902 
0903 void SetupCamera::slotEditedCamera(const QString& title, const QString& model,
0904                                    const QString& port, const QString& path)
0905 {
0906     SetupCameraItem* const item = dynamic_cast<SetupCameraItem*>(d->listView->currentItem());
0907 
0908     if (!item)
0909     {
0910         return;
0911     }
0912 
0913     CameraType ctype(title, model, port, path, 1);
0914     item->setCameraType(&ctype);
0915 }
0916 
0917 void SetupCamera::slotAutoDetectCamera()
0918 {
0919     DBusyDlg* const dlg                  = new DBusyDlg(i18n("Device detection under progress, please wait..."), this);
0920     CameraAutoDetectThread* const thread = new CameraAutoDetectThread(this);
0921     dlg->setBusyThread(thread);
0922     dlg->exec();
0923 
0924     QString model = thread->model();
0925     QString port  = thread->port();
0926     int ret       = thread->result();
0927 
0928     if (ret != 0)
0929     {
0930         QMessageBox::critical(this, qApp->applicationName(), i18n("Failed to auto-detect camera.\n"
0931                                                                   "Please check if your camera is turned on "
0932                                                                   "and retry or try setting it manually."));
0933         return;
0934     }
0935 
0936     // NOTE: See note in digikam/digikam/cameralist.cpp
0937 
0938     if (port.startsWith(QLatin1String("usb:")))
0939     {
0940         port = QLatin1String("usb:");
0941     }
0942 
0943     if (!d->listView->findItems(model, Qt::MatchExactly, 1).isEmpty())
0944     {
0945         QMessageBox::information(this, qApp->applicationName(), i18n("Camera '%1' (%2) is already in list.", model, port));
0946     }
0947     else
0948     {
0949         QMessageBox::information(this, qApp->applicationName(), i18n("Found camera '%1' (%2) and added it to the list.", model, port));
0950         slotAddedCamera(model, model, port, QLatin1String("/"));
0951     }
0952 }
0953 
0954 void SetupCamera::slotImportSelectionChanged()
0955 {
0956     QListWidgetItem* const item = d->importListView->currentItem();
0957 
0958     d->importRemoveButton->setEnabled(item);
0959     d->importEditButton->setEnabled(item);
0960 }
0961 
0962 void SetupCamera::slotAddFilter()
0963 {
0964     Filter filter;
0965     filter.name                   = i18n("Untitled");
0966     QPointer<ImportFilterDlg> dlg = new ImportFilterDlg(this);
0967     dlg->setData(filter);
0968 
0969     if (dlg->exec() == QDialog::Accepted)
0970     {
0971         Filter* const f = new Filter;
0972         dlg->getData(f);
0973         d->filters.append(f);
0974         new QListWidgetItem(f->name, d->importListView);
0975     }
0976 
0977     delete dlg;
0978 
0979     slotImportSelectionChanged();
0980 }
0981 
0982 void SetupCamera::slotRemoveFilter()
0983 {
0984     QListWidgetItem* const item = d->importListView->currentItem();
0985     int current                 = d->importListView->currentRow();
0986 
0987     for (int i = 0 ; i < d->filters.count() ; ++i)
0988     {
0989         if (d->filters.at(i)->name == item->text())
0990         {
0991             delete d->filters.takeAt(i);
0992             delete d->importListView->takeItem(current);
0993             slotImportSelectionChanged();
0994             break;
0995         }
0996     }
0997 }
0998 
0999 void SetupCamera::slotEditFilter()
1000 {
1001     QListWidgetItem* const item = d->importListView->currentItem();
1002 
1003     for (int i = 0 ; i < d->filters.count() ; ++i)
1004     {
1005         if (d->filters.at(i)->name == item->text())
1006         {
1007             Filter filter                 = *d->filters.at(i);
1008             QPointer<ImportFilterDlg> dlg = new ImportFilterDlg(this);
1009             dlg->setData(filter);
1010 
1011             if (dlg->exec() == QDialog::Accepted)
1012             {
1013                 Filter* const f = d->filters.at(i);
1014                 dlg->getData(f);
1015                 item->setText(f->name);
1016             }
1017 
1018             delete dlg;
1019             break;
1020         }
1021     }
1022 }
1023 
1024 void SetupCamera::slotPreviewItemsClicked()
1025 {
1026     if (d->previewItemsWhileDownload->isChecked() && d->previewLoadFullImageSize->isChecked())
1027     {
1028         QMessageBox::information(this, qApp->applicationName(),
1029                                  i18n("In order to enable this feature, the full-sized preview will be disabled."));
1030 
1031         d->previewLoadFullImageSize->setChecked(false);
1032     }
1033 }
1034 
1035 void SetupCamera::slotPreviewFullImageSizeClicked()
1036 {
1037     if (d->previewItemsWhileDownload->isChecked() && d->previewLoadFullImageSize)
1038     {
1039         QMessageBox::information(this, qApp->applicationName(),
1040                                  i18n("If the full-sized preview is enabled it will affect the speed of previewing each item while download."));
1041 
1042         d->previewItemsWhileDownload->setChecked(false);
1043     }
1044 }
1045 
1046 } // namespace Digikam
1047 
1048 #include "moc_setupcamera.cpp"