File indexing completed on 2025-01-19 03:52:56
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2019-03-27 0007 * Description : a tool to export items to a local storage 0008 * 0009 * SPDX-FileCopyrightText: 2006-2009 by Johannes Wienke <languitar at semipol dot de> 0010 * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2019-2020 by Maik Qualmann <metzpinguin at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "fcexportwidget.h" 0018 0019 // Qt includes 0020 0021 #include <QApplication> 0022 #include <QRadioButton> 0023 #include <QButtonGroup> 0024 #include <QVBoxLayout> 0025 #include <QCheckBox> 0026 #include <QGroupBox> 0027 #include <QComboBox> 0028 #include <QSpinBox> 0029 #include <QLabel> 0030 0031 // KDE includes 0032 0033 #include <klocalizedstring.h> 0034 0035 // Local includes 0036 0037 #include "digikam_debug.h" 0038 #include "dfileselector.h" 0039 #include "wstoolutils.h" 0040 #include "dlayoutbox.h" 0041 #include "fctask.h" 0042 #include "metaenginesettings.h" 0043 0044 namespace DigikamGenericFileCopyPlugin 0045 { 0046 0047 class Q_DECL_HIDDEN FCExportWidget::Private 0048 { 0049 public: 0050 0051 explicit Private() 0052 : iface (nullptr), 0053 selector (nullptr), 0054 imageList (nullptr), 0055 sidecars (nullptr), 0056 writeMetadataToFile (nullptr), 0057 overwrite (nullptr), 0058 albumPath (nullptr), 0059 targetButtonGroup (nullptr), 0060 fileCopyButton (nullptr), 0061 symLinkButton (nullptr), 0062 relativeButton (nullptr), 0063 imageChangeGroupBox (nullptr), 0064 changeImagesProp (nullptr), 0065 removeMetadataProp (nullptr), 0066 imageCompression (nullptr), 0067 imageResize (nullptr), 0068 imageFormat (nullptr) 0069 { 0070 } 0071 0072 DInfoInterface* iface; 0073 DFileSelector* selector; 0074 DItemsList* imageList; 0075 0076 QCheckBox* sidecars; 0077 QCheckBox* writeMetadataToFile; 0078 QCheckBox* overwrite; 0079 QCheckBox* albumPath; 0080 0081 QButtonGroup* targetButtonGroup; 0082 QRadioButton* fileCopyButton; 0083 QRadioButton* symLinkButton; 0084 QRadioButton* relativeButton; 0085 0086 QUrl targetUrl; 0087 0088 QGroupBox* imageChangeGroupBox; 0089 QCheckBox* changeImagesProp; 0090 QCheckBox* removeMetadataProp; 0091 0092 QSpinBox* imageCompression; 0093 QSpinBox* imageResize; 0094 QComboBox* imageFormat; 0095 }; 0096 0097 FCExportWidget::FCExportWidget(DInfoInterface* const iface, QWidget* const parent) 0098 : QWidget(parent), 0099 d (new Private) 0100 { 0101 d->iface = iface; 0102 0103 // setup local target selection 0104 0105 const int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0106 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)); 0107 0108 DHBox* const hbox = new DHBox(this); 0109 QLabel* const locationLabel = new QLabel(hbox); 0110 locationLabel->setText(i18n("Target location: ")); 0111 d->selector = new DFileSelector(hbox); 0112 d->selector->setFileDlgMode(QFileDialog::Directory); 0113 d->selector->setFileDlgOptions(QFileDialog::ShowDirsOnly); 0114 d->selector->setFileDlgTitle(i18nc("@title:window", "Target Folder")); 0115 d->selector->setWhatsThis(i18n("Sets the target address to copy the items to.")); 0116 0117 QLabel* const targetLabel = new QLabel(i18n("Target file behavior:"), this); 0118 d->targetButtonGroup = new QButtonGroup(this); 0119 d->fileCopyButton = new QRadioButton(i18n("Copy files"), this); 0120 d->symLinkButton = new QRadioButton(i18n("Create symlinks"), this); 0121 d->relativeButton = new QRadioButton(i18n("Create relative symlinks"), this); 0122 0123 d->sidecars = new QCheckBox(i18n("Include the sidecar of the items"), this); 0124 d->writeMetadataToFile = new QCheckBox(i18n("Write sidecar metadata to the items"), this); 0125 d->overwrite = new QCheckBox(i18n("Overwrite existing items in the target"), this); 0126 d->albumPath = new QCheckBox(i18n("Use the album path of the items in the target"), this); 0127 0128 if (!d->iface->supportAlbums()) 0129 { 0130 d->albumPath->hide(); 0131 } 0132 0133 if (MetaEngineSettings::instance()->settings().metadataWritingMode != MetaEngine::WRITE_TO_SIDECAR_ONLY) 0134 { 0135 d->writeMetadataToFile->hide(); 0136 } 0137 0138 d->targetButtonGroup->addButton(d->fileCopyButton, FCContainer::CopyFile); 0139 d->targetButtonGroup->addButton(d->symLinkButton, FCContainer::FullSymLink); 0140 d->targetButtonGroup->addButton(d->relativeButton, FCContainer::RelativeSymLink); 0141 d->targetButtonGroup->setExclusive(true); 0142 d->fileCopyButton->setChecked(true); 0143 0144 //--------------------------------------------- 0145 0146 d->changeImagesProp = new QCheckBox(i18n("Adjust image properties"), this); 0147 d->changeImagesProp->setChecked(false); 0148 d->changeImagesProp->setWhatsThis(i18n("If you enable this option, " 0149 "all images to be sent can be " 0150 "resized and recompressed.")); 0151 0152 //--------------------------------------------- 0153 0154 d->imageChangeGroupBox = new QGroupBox(i18n("Image Properties"), this); 0155 0156 d->imageResize = new QSpinBox(d->imageChangeGroupBox); 0157 d->imageResize->setRange(300, 6000); 0158 d->imageResize->setSingleStep(1); 0159 d->imageResize->setValue(1024); 0160 d->imageResize->setSuffix(i18n(" px")); 0161 d->imageResize->setWhatsThis(i18n("Select the length of the images that are to be sent. " 0162 "The aspect ratio is preserved.")); 0163 d->imageChangeGroupBox->setEnabled(false); 0164 0165 QLabel* const labelImageResize = new QLabel(i18n("Image Length:"), d->imageChangeGroupBox); 0166 labelImageResize->setBuddy(d->imageResize); 0167 0168 //--------------------------------------------- 0169 0170 QLabel* const labelImageFormat = new QLabel(d->imageChangeGroupBox); 0171 labelImageFormat->setWordWrap(false); 0172 labelImageFormat->setText(i18n("Image Format:")); 0173 0174 d->imageFormat = new QComboBox(d->imageChangeGroupBox); 0175 d->imageFormat->setEditable(false); 0176 d->imageFormat->setWhatsThis(i18n("Select your preferred format to convert image.")); 0177 d->imageFormat->addItem(i18nc("Image format: JPEG", "Jpeg"), FCContainer::JPEG); 0178 d->imageFormat->addItem(i18nc("Image format: PNG", "Png"), FCContainer::PNG); 0179 labelImageFormat->setBuddy(d->imageFormat); 0180 0181 //--------------------------------------------- 0182 0183 d->imageCompression = new QSpinBox(d->imageChangeGroupBox); 0184 d->imageCompression->setRange(1, 100); 0185 d->imageCompression->setSingleStep(1); 0186 d->imageCompression->setValue(75); 0187 d->imageCompression->setWhatsThis(i18n("<p>The new compression value of JPEG images to be sent:</p>" 0188 "<p><b>1</b>: very high compression<br/>" 0189 "<b>25</b>: high compression<br/>" 0190 "<b>50</b>: medium compression<br/>" 0191 "<b>75</b>: low compression (default value)<br/>" 0192 "<b>100</b>: no compression</p>")); 0193 0194 QLabel* const labelImageCompression = new QLabel(i18n("Image quality:"), d->imageChangeGroupBox); 0195 labelImageCompression->setBuddy(d->imageCompression); 0196 0197 //--------------------------------------------- 0198 0199 d->removeMetadataProp = new QCheckBox(i18n("Remove all metadata"), d->imageChangeGroupBox); 0200 d->removeMetadataProp->setWhatsThis(i18n("If you enable this option, all metadata " 0201 "as Exif, Iptc, and Xmp will be removed.")); 0202 0203 //--------------------------------------------- 0204 0205 QGridLayout* const grid2 = new QGridLayout(d->imageChangeGroupBox); 0206 grid2->addWidget(labelImageResize, 0, 0, 1, 1); 0207 grid2->addWidget(d->imageResize, 0, 1, 1, 2); 0208 grid2->addWidget(labelImageFormat, 1, 0, 1, 1); 0209 grid2->addWidget(d->imageFormat, 1, 1, 1, 2); 0210 grid2->addWidget(labelImageCompression, 2, 0, 1, 1); 0211 grid2->addWidget(d->imageCompression, 2, 1, 1, 2); 0212 grid2->addWidget(d->removeMetadataProp, 3, 0, 1, 2); 0213 grid2->setColumnStretch(2, 10); 0214 grid2->setSpacing(spacing); 0215 grid2->setAlignment(Qt::AlignTop); 0216 0217 //--------------------------------------------- 0218 0219 // setup image list 0220 d->imageList = new DItemsList(this); 0221 d->imageList->setObjectName(QLatin1String("FCExport ImagesList")); 0222 d->imageList->setIface(d->iface); 0223 d->imageList->loadImagesFromCurrentSelection(); 0224 d->imageList->setAllowRAW(true); 0225 d->imageList->listView()->setWhatsThis(i18n("This is the list of items to copy " 0226 "to the specified target.")); 0227 0228 // layout dialog 0229 QVBoxLayout* const layout = new QVBoxLayout(this); 0230 0231 layout->addWidget(hbox); 0232 layout->addWidget(targetLabel); 0233 layout->addWidget(d->fileCopyButton); 0234 layout->addWidget(d->symLinkButton); 0235 layout->addWidget(d->relativeButton); 0236 layout->addWidget(d->sidecars); 0237 layout->addWidget(d->writeMetadataToFile); 0238 layout->addWidget(d->overwrite); 0239 layout->addWidget(d->albumPath); 0240 layout->addWidget(d->imageList); 0241 layout->addWidget(d->changeImagesProp); 0242 layout->addWidget(d->imageChangeGroupBox); 0243 layout->setSpacing(spacing); 0244 layout->setContentsMargins(QMargins()); 0245 0246 // ------------------------------------------------------------------------ 0247 0248 connect(d->selector->lineEdit(), SIGNAL(textEdited(QString)), 0249 this, SLOT(slotLabelUrlChanged())); 0250 0251 connect(d->selector, SIGNAL(signalUrlSelected(QUrl)), 0252 this, SLOT(slotLabelUrlChanged())); 0253 0254 connect(d->fileCopyButton, SIGNAL(toggled(bool)), 0255 this, SLOT(slotFileCopyButtonChanged(bool))); 0256 0257 connect(d->changeImagesProp, SIGNAL(toggled(bool)), 0258 d->imageChangeGroupBox, SLOT(setEnabled(bool))); 0259 0260 } 0261 0262 FCExportWidget::~FCExportWidget() 0263 { 0264 delete d; 0265 } 0266 0267 DItemsList* FCExportWidget::imagesList() const 0268 { 0269 return d->imageList; 0270 } 0271 0272 QUrl FCExportWidget::targetUrl() const 0273 { 0274 return d->targetUrl; 0275 } 0276 0277 FCContainer FCExportWidget::getSettings() const 0278 { 0279 FCContainer settings; 0280 0281 settings.iface = d->iface; 0282 settings.destUrl = d->targetUrl; 0283 settings.behavior = d->targetButtonGroup->checkedId(); 0284 settings.imageFormat = d->imageFormat->currentIndex(); 0285 settings.imageResize = d->imageResize->value(); 0286 settings.imageCompression = d->imageCompression->value(); 0287 settings.sidecars = d->sidecars->isChecked(); 0288 settings.writeMetadataToFile = d->writeMetadataToFile->isChecked(); 0289 settings.overwrite = d->overwrite->isChecked(); 0290 settings.albumPath = d->albumPath->isChecked(); 0291 settings.removeMetadata = d->removeMetadataProp->isChecked(); 0292 settings.changeImageProperties = d->changeImagesProp->isChecked(); 0293 0294 return settings; 0295 } 0296 0297 void FCExportWidget::setSettings(const FCContainer& settings) 0298 { 0299 d->targetUrl = settings.destUrl; 0300 d->selector->setFileDlgPath(d->targetUrl.toLocalFile()); 0301 QAbstractButton* const button = d->targetButtonGroup->button(settings.behavior); 0302 0303 if (button) 0304 { 0305 button->setChecked(true); 0306 } 0307 0308 d->imageFormat->setCurrentIndex(settings.imageFormat); 0309 d->imageResize->setValue(settings.imageResize); 0310 d->imageCompression->setValue(settings.imageCompression); 0311 d->sidecars->setChecked(settings.sidecars); 0312 d->writeMetadataToFile->setChecked(settings.writeMetadataToFile); 0313 d->overwrite->setChecked(settings.overwrite); 0314 d->albumPath->setChecked(settings.albumPath); 0315 d->removeMetadataProp->setChecked(settings.removeMetadata); 0316 d->changeImagesProp->setChecked(settings.changeImageProperties); 0317 } 0318 0319 void FCExportWidget::slotLabelUrlChanged() 0320 { 0321 d->targetUrl = QUrl::fromLocalFile(d->selector->fileDlgPath()); 0322 0323 Q_EMIT signalTargetUrlChanged(d->targetUrl); 0324 } 0325 0326 void FCExportWidget::slotFileCopyButtonChanged(bool enabled) 0327 { 0328 if (!enabled) 0329 { 0330 d->changeImagesProp->setChecked(false); 0331 } 0332 0333 d->changeImagesProp->setEnabled(enabled); 0334 0335 // The changeImagesProp is by default and on each change unchecked 0336 0337 d->imageChangeGroupBox->setEnabled(false); 0338 } 0339 0340 } // namespace DigikamGenericFileCopyPlugin 0341 0342 #include "moc_fcexportwidget.cpp"