diff --git a/core/dplugins/generic/webservices/yandexfotki/yfalbum.cpp b/core/dplugins/generic/webservices/yandexfotki/yfalbum.cpp index fdf1106bba..c76e545c3d 100644 --- a/core/dplugins/generic/webservices/yandexfotki/yfalbum.cpp +++ b/core/dplugins/generic/webservices/yandexfotki/yfalbum.cpp @@ -1,117 +1,118 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-11-18 * Description : a tool to export items to YandexFotki web service * * Copyright (C) 2010 by Roman Tsisyk * Copyright (C) 2010-2020 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #include "yfalbum.h" namespace DigikamGenericYFPlugin { YandexFotkiAlbum::YandexFotkiAlbum() { - // nothing + // nothing to do } YandexFotkiAlbum::YandexFotkiAlbum(const QString& urn, const QString& author, const QString& title, const QString& summary, const QString& apiEditUrl, const QString& apiSelfUrl, const QString& apiPhotosUrl, const QDateTime& publishedDate, const QDateTime& editedDate, const QDateTime& updatedDate, const QString& password) : m_urn(urn), m_author(author), m_title(title), m_summary(summary), m_apiEditUrl(apiEditUrl), m_apiSelfUrl(apiSelfUrl), m_apiPhotosUrl(apiPhotosUrl), m_publishedDate(publishedDate), m_editedDate(editedDate), m_updatedDate(updatedDate), m_password(password) { - // nothing + // nothing to do } YandexFotkiAlbum::YandexFotkiAlbum(const YandexFotkiAlbum& other) : m_urn(other.urn()), m_author(other.author()), m_title(other.title()), m_summary(other.summary()), m_apiEditUrl(other.m_apiEditUrl), m_apiSelfUrl(other.m_apiSelfUrl), m_apiPhotosUrl(other.m_apiPhotosUrl), m_publishedDate(other.publishedDate()), m_editedDate(other.editedDate()), m_updatedDate(other.updatedDate()), m_password(other.m_password) { - //nothing + // nothing to do } YandexFotkiAlbum::~YandexFotkiAlbum() { } YandexFotkiAlbum& YandexFotkiAlbum::operator=(const YandexFotkiAlbum& other) { m_urn = other.urn(); m_author = other.author(); m_title = other.title(); m_summary = other.summary(); m_apiEditUrl = other.m_apiEditUrl; m_apiSelfUrl = other.m_apiSelfUrl; m_apiPhotosUrl = other.m_apiPhotosUrl; m_publishedDate = other.publishedDate(); m_editedDate = other.editedDate(); m_updatedDate = other.updatedDate(); m_password = other.m_password; return *this; } QDebug operator<<(QDebug d, const YandexFotkiAlbum& a) { d.nospace() << "YandexFotkiAlbum(\n"; - d.space() << "urn:" << a.urn() << ",\n"; - d.space() << "author:" << a.author() << ",\n"; - d.space() << "title:" << a.title() << ",\n"; - d.space() << "summary:" << a.summary() << ",\n"; - d.space() << "apiEditUrl:" << a.m_apiEditUrl << ",\n"; - d.space() << "apiSelfUrl:" << a.m_apiSelfUrl << ",\n"; - d.space() << "apiPhotoUrl:" << a.m_apiPhotosUrl << ",\n"; - d.space() << "publishedDate:" << a.publishedDate() << ",\n"; - d.space() << "editedDate:" << a.editedDate() << ",\n"; - d.space() << "updatedDate:" << a.updatedDate() << ",\n"; - d.space() << "password:" << !a.m_password.isNull() << "" << a.m_password << "\n"; + d.space() << "urn:" << a.urn() << ",\n"; + d.space() << "author:" << a.author() << ",\n"; + d.space() << "title:" << a.title() << ",\n"; + d.space() << "summary:" << a.summary() << ",\n"; + d.space() << "apiEditUrl:" << a.m_apiEditUrl << ",\n"; + d.space() << "apiSelfUrl:" << a.m_apiSelfUrl << ",\n"; + d.space() << "apiPhotoUrl:" << a.m_apiPhotosUrl << ",\n"; + d.space() << "publishedDate:" << a.publishedDate() << ",\n"; + d.space() << "editedDate:" << a.editedDate() << ",\n"; + d.space() << "updatedDate:" << a.updatedDate() << ",\n"; + d.space() << "password:" << !a.m_password.isNull() << "" << a.m_password << "\n"; d.nospace() << ")"; + return d; } } // namespace DigikamGenericYFPlugin diff --git a/core/dplugins/generic/webservices/yandexfotki/yfnewalbumdlg.cpp b/core/dplugins/generic/webservices/yandexfotki/yfnewalbumdlg.cpp index 53a3ca4d24..28ae6f542a 100644 --- a/core/dplugins/generic/webservices/yandexfotki/yfnewalbumdlg.cpp +++ b/core/dplugins/generic/webservices/yandexfotki/yfnewalbumdlg.cpp @@ -1,123 +1,123 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2011-02-19 * Description : a tool to export items to YandexFotki web service * * Copyright (C) 2011 by Roman Tsisyk * Copyright (C) 2011-2020 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #include "yfnewalbumdlg.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include // Local includes #include "yfalbum.h" #include "digikam_debug.h" namespace DigikamGenericYFPlugin { class Q_DECL_HIDDEN YFNewAlbumDlg::Private { public: explicit Private() + : passwordEdit(nullptr) { - passwordEdit = nullptr; } QLineEdit* passwordEdit; YandexFotkiAlbum album; }; YFNewAlbumDlg::YFNewAlbumDlg(QWidget* const parent, YandexFotkiAlbum& album) : WSNewAlbumDialog(parent, QLatin1String("Yandex.Fotki")), d(new Private) { - d->album = album; + d->album = album; hideLocation(); hideDateTime(); QGroupBox* const albumBox = new QGroupBox(QString(), this); d->passwordEdit = new QLineEdit(); d->passwordEdit->setWhatsThis(i18n("Password for the album (optional).")); QFormLayout* const albumBoxLayout = new QFormLayout; albumBoxLayout->addRow(i18n("Password:"), d->passwordEdit); albumBox->setLayout(albumBoxLayout); addToMainLayout(albumBox); connect(getButtonBox(), SIGNAL(accepted()), this, SLOT(slotOkClicked())); } YFNewAlbumDlg::~YFNewAlbumDlg() { delete d; } YandexFotkiAlbum& YFNewAlbumDlg::album() const { return d->album; } void YFNewAlbumDlg::slotOkClicked() { if (getTitleEdit()->text().isEmpty()) { QMessageBox::critical(this, i18n("Error"), i18n("Title cannot be empty.")); return; } d->album.setTitle(getTitleEdit()->text()); d->album.setSummary(getDescEdit()->toPlainText()); if (d->passwordEdit->text().isEmpty()) { d->album.setPassword(QString()); // force null string } else { d->album.setPassword(d->passwordEdit->text()); } accept(); } } // namespace DigikamGenericYFPlugin diff --git a/core/dplugins/generic/webservices/yandexfotki/yfphoto.cpp b/core/dplugins/generic/webservices/yandexfotki/yfphoto.cpp index aae6ae8aee..3dddf8303f 100644 --- a/core/dplugins/generic/webservices/yandexfotki/yfphoto.cpp +++ b/core/dplugins/generic/webservices/yandexfotki/yfphoto.cpp @@ -1,139 +1,139 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-11-18 * Description : a tool to export items to YandexFotki web service * * Copyright (C) 2010 by Roman Tsisyk * Copyright (C) 2010-2020 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #include "yfphoto.h" namespace DigikamGenericYFPlugin { YFPhoto::YFPhoto() : m_access(ACCESS_PUBLIC), m_hideOriginal(false), m_disableComments(false), m_adult(false) { } YFPhoto::~YFPhoto() { } YFPhoto::YFPhoto(const QString& urn, const QString& author, const QString& title, const QString& summary, const QString& apiEditUrl, const QString& apiSelfUrl, const QString& apiMediaUrl, const QString& apiAlbumUrl, const QDateTime& publishedDate, const QDateTime& editedDate, const QDateTime& updatedDate, const QDateTime& createdDate, Access access, bool hideOriginal, bool disableComments, bool adult, const QString& remoteUrl) : m_urn(urn), m_author(author), m_title(title), m_summary(summary), m_apiEditUrl(apiEditUrl), m_apiSelfUrl(apiSelfUrl), m_apiMediaUrl(apiMediaUrl), m_apiAlbumUrl(apiAlbumUrl), m_publishedDate(publishedDate), m_editedDate(editedDate), m_updatedDate(updatedDate), m_createdDate(createdDate), m_access(access), m_hideOriginal(hideOriginal), m_disableComments(disableComments), m_adult(adult), m_remoteUrl(remoteUrl) { - // nothing + // nothing to do } YFPhoto::YFPhoto(const YFPhoto& other) : m_urn(other.urn()), m_author(other.author()), m_title(other.title()), m_summary(other.summary()), m_apiEditUrl(other.m_apiEditUrl), m_apiSelfUrl(other.m_apiSelfUrl), m_apiMediaUrl(other.m_apiMediaUrl), m_apiAlbumUrl(other.m_apiAlbumUrl), m_publishedDate(other.publishedDate()), m_editedDate(other.editedDate()), m_updatedDate(other.updatedDate()), m_createdDate(other.createdDate()), m_access(other.access()), m_hideOriginal(other.isHideOriginal()), m_disableComments(other.isDisableComments()), m_adult(other.isAdult()), m_remoteUrl(other.remoteUrl()), m_localUrl(other.localUrl()), m_originalUrl(other.originalUrl()) { - //nothing + // nothing to do } QDebug operator<<(QDebug d, const YFPhoto& p) { d.nospace() << "YFPhoto(\n"; - d.space() << "urn:" << p.urn() << ",\n"; - d.space() << "author:" << p.author() << ",\n"; - d.space() << "title:" << p.title() << ",\n"; - d.space() << "summary:" << p.summary() << ",\n"; - d.space() << "apiEditUrl:" << p.m_apiEditUrl << ",\n"; - d.space() << "apiSelfUrl:" << p.m_apiSelfUrl << ",\n"; - d.space() << "apiMediaUrl:" << p.m_apiMediaUrl << ",\n"; - d.space() << "apiAlbumUrl:" << p.m_apiAlbumUrl << ",\n"; - d.space() << "publishedDate:" << p.publishedDate() << ",\n"; - d.space() << "editedDate:" << p.editedDate() << ",\n"; - d.space() << "updatedDate:" << p.updatedDate() << ",\n"; - d.space() << "createdDate:" << p.createdDate() << ",\n"; - d.space() << "access:" << p.access() << ",\n"; - d.space() << "hideOriginal:" << p.isHideOriginal() << ",\n"; + d.space() << "urn:" << p.urn() << ",\n"; + d.space() << "author:" << p.author() << ",\n"; + d.space() << "title:" << p.title() << ",\n"; + d.space() << "summary:" << p.summary() << ",\n"; + d.space() << "apiEditUrl:" << p.m_apiEditUrl << ",\n"; + d.space() << "apiSelfUrl:" << p.m_apiSelfUrl << ",\n"; + d.space() << "apiMediaUrl:" << p.m_apiMediaUrl << ",\n"; + d.space() << "apiAlbumUrl:" << p.m_apiAlbumUrl << ",\n"; + d.space() << "publishedDate:" << p.publishedDate() << ",\n"; + d.space() << "editedDate:" << p.editedDate() << ",\n"; + d.space() << "updatedDate:" << p.updatedDate() << ",\n"; + d.space() << "createdDate:" << p.createdDate() << ",\n"; + d.space() << "access:" << p.access() << ",\n"; + d.space() << "hideOriginal:" << p.isHideOriginal() << ",\n"; d.space() << "disableComments:" << p.isDisableComments() << ",\n"; - d.space() << "adult:" << p.isAdult() << ",\n"; - d.space() << "remoteUrl:" << p.remoteUrl() << ",\n"; - d.space() << "localUrl:" << p.localUrl() << ",\n"; - d.space() << "originalUrl:" << p.originalUrl() << ",\n"; - d.space() << "tags:" << "\n"; + d.space() << "adult:" << p.isAdult() << ",\n"; + d.space() << "remoteUrl:" << p.remoteUrl() << ",\n"; + d.space() << "localUrl:" << p.localUrl() << ",\n"; + d.space() << "originalUrl:" << p.originalUrl() << ",\n"; + d.space() << "tags:" << "\n"; foreach (const QString& t, p.tags) { d.space() << t << ","; } d.space() << "\n"; - d.nospace() << ")"; + return d; } } // namespace DigikamGenericYFPlugin diff --git a/core/dplugins/generic/webservices/yandexfotki/yfplugin.h b/core/dplugins/generic/webservices/yandexfotki/yfplugin.h index 0cfcb7ea59..dd1038081e 100644 --- a/core/dplugins/generic/webservices/yandexfotki/yfplugin.h +++ b/core/dplugins/generic/webservices/yandexfotki/yfplugin.h @@ -1,71 +1,71 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2018-07-30 * Description : a plugin to export to YandexFotki web-service. * * Copyright (C) 2018-2020 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_YF_PLUGIN_H #define DIGIKAM_YF_PLUGIN_H // Local includes #include "dplugingeneric.h" #define DPLUGIN_IID "org.kde.digikam.plugin.generic.YandexFotki" using namespace Digikam; namespace DigikamGenericYFPlugin { class YFWindow; class YFPlugin : public DPluginGeneric { Q_OBJECT Q_PLUGIN_METADATA(IID DPLUGIN_IID) Q_INTERFACES(Digikam::DPluginGeneric) public: explicit YFPlugin(QObject* const parent = nullptr); ~YFPlugin(); QString name() const override; QString iid() const override; QIcon icon() const override; QString details() const override; QString description() const override; QList authors() const override; - void setup(QObject* const) override; - void cleanUp() override; + void setup(QObject* const) override; + void cleanUp() override; private Q_SLOTS: void slotYandexFotki(); private: QPointer m_toolDlg; }; } // namespace DigikamGenericYFPlugin #endif // DIGIKAM_YF_PLUGIN_H diff --git a/core/dplugins/generic/webservices/yandexfotki/yfwidget.cpp b/core/dplugins/generic/webservices/yandexfotki/yfwidget.cpp index f033e568ce..874ec29d6f 100644 --- a/core/dplugins/generic/webservices/yandexfotki/yfwidget.cpp +++ b/core/dplugins/generic/webservices/yandexfotki/yfwidget.cpp @@ -1,159 +1,159 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2008-09-12 * Description : a tool to export items to YandexFotki web service * * Copyright (C) 2015 by Shourya Singh Gupta * Copyright (C) 2015-2020 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #include "yfwidget.h" // Qt includes #include #include #include #include #include #include #include #include #include #include // KDE includes #include //local includes #include "yfphoto.h" #include "yfalbum.h" namespace DigikamGenericYFPlugin { class Q_DECL_HIDDEN YFWidget::Private { public: explicit Private() + : accessCombo(nullptr), + hideOriginalCheck(nullptr), + disableCommentsCheck(nullptr), + adultCheck(nullptr), + policyGroup(nullptr) { - accessCombo = nullptr; - hideOriginalCheck = nullptr; - disableCommentsCheck = nullptr; - adultCheck = nullptr; - policyGroup = nullptr; } - // upload settings + /// upload settings QComboBox* accessCombo; QCheckBox* hideOriginalCheck; QCheckBox* disableCommentsCheck; QCheckBox* adultCheck; QButtonGroup* policyGroup; }; YFWidget::YFWidget(QWidget* const parent, DInfoInterface* const iface, const QString& toolName) : WSSettingsWidget(parent, iface, toolName), d(new Private) { QGroupBox* const optionsBox = getOptionsBox(); QGridLayout* const optionsBoxLayout = getOptionsBoxLayout(); QSpacerItem* const spacer1 = new QSpacerItem(1, 10, QSizePolicy::Expanding, QSizePolicy::Minimum); QSpacerItem* const spacer2 = new QSpacerItem(1, 10, QSizePolicy::Expanding, QSizePolicy::Minimum); QLabel* const policyLabel = new QLabel(i18n("Update policy:"), optionsBox); QRadioButton* const policyRadio1 = new QRadioButton(i18n("Update metadata"), optionsBox); policyRadio1->setWhatsThis(i18n("Update metadata of remote file and merge remote tags with local")); QRadioButton* const policyRadio3 = new QRadioButton(i18n("Skip photo"), optionsBox); policyRadio3->setWhatsThis(i18n("Simple skip photo")); QRadioButton* const policyRadio4 = new QRadioButton(i18n("Upload as new"), optionsBox); policyRadio4->setWhatsThis(i18n("Add photo as new")); QLabel* const accessLabel = new QLabel(i18n("Privacy settings:"), optionsBox); d->accessCombo = new QComboBox(optionsBox); d->accessCombo->addItem(QIcon::fromTheme(QLatin1String("folder")), i18n("Public access"), YFPhoto::ACCESS_PUBLIC); d->accessCombo->addItem(QIcon::fromTheme(QLatin1String("folder-red")), i18n("Friends access"), YFPhoto::ACCESS_FRIENDS); d->accessCombo->addItem(QIcon::fromTheme(QLatin1String("folder-locked")), i18n("Private access"), YFPhoto::ACCESS_PRIVATE); d->hideOriginalCheck = new QCheckBox(i18n("Hide original photo"), optionsBox); d->disableCommentsCheck = new QCheckBox(i18n("Disable comments"), optionsBox); d->adultCheck = new QCheckBox(i18n("Adult content"), optionsBox); d->policyGroup = new QButtonGroup(optionsBox); d->policyGroup->addButton(policyRadio1, POLICY_UPDATE_MERGE); d->policyGroup->addButton(policyRadio3, POLICY_SKIP); d->policyGroup->addButton(policyRadio4, POLICY_ADDNEW); - optionsBoxLayout->addItem(spacer1, 3, 0, 1, 5); - optionsBoxLayout->addWidget(accessLabel, 4, 0, 1, 5); + optionsBoxLayout->addItem(spacer1, 3, 0, 1, 5); + optionsBoxLayout->addWidget(accessLabel, 4, 0, 1, 5); optionsBoxLayout->addWidget(d->accessCombo, 5, 1, 1, 4); optionsBoxLayout->addWidget(d->adultCheck, 6, 1, 1, 4); optionsBoxLayout->addWidget(d->hideOriginalCheck, 7, 1, 1, 4); optionsBoxLayout->addWidget(d->disableCommentsCheck, 8, 1, 1, 4); - optionsBoxLayout->addItem(spacer2, 9, 0, 1, 5); - optionsBoxLayout->addWidget(policyLabel, 10, 0, 1, 5); - optionsBoxLayout->addWidget(policyRadio1, 11, 1, 1, 4); - optionsBoxLayout->addWidget(policyRadio3, 13, 1, 1, 4); - optionsBoxLayout->addWidget(policyRadio4, 14, 1, 1, 4); + optionsBoxLayout->addItem(spacer2, 9, 0, 1, 5); + optionsBoxLayout->addWidget(policyLabel, 10, 0, 1, 5); + optionsBoxLayout->addWidget(policyRadio1, 11, 1, 1, 4); + optionsBoxLayout->addWidget(policyRadio3, 13, 1, 1, 4); + optionsBoxLayout->addWidget(policyRadio4, 14, 1, 1, 4); getUploadBox()->hide(); getSizeBox()->hide(); } YFWidget::~YFWidget() { delete d; } void YFWidget::updateLabels(const QString& /*name*/, const QString& /*url*/) { } QComboBox* YFWidget::accessCB() const { return d->accessCombo; } QCheckBox* YFWidget::hideOriginalCB() const { return d->hideOriginalCheck; } QCheckBox* YFWidget::disableCommentsCB() const { return d->disableCommentsCheck; } QCheckBox* YFWidget::adultCB() const { return d->adultCheck; } QButtonGroup* YFWidget::policyGB() const { return d->policyGroup; } } // namespace DigikamGenericYFPlugin diff --git a/core/dplugins/generic/webservices/yandexfotki/yfwindow.cpp b/core/dplugins/generic/webservices/yandexfotki/yfwindow.cpp index 49ce94d2a1..a827420e2a 100644 --- a/core/dplugins/generic/webservices/yandexfotki/yfwindow.cpp +++ b/core/dplugins/generic/webservices/yandexfotki/yfwindow.cpp @@ -1,841 +1,854 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-11-15 * Description : a tool to export items to YandexFotki web service * * Copyright (C) 2010 by Roman Tsisyk * Copyright (C) 2005-2008 by Vardhman Jain * Copyright (C) 2008-2020 by Gilles Caulier * Copyright (C) 2009 by Luka Renko * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * ============================================================ */ #include "yfwindow.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include #include // Local includes #include "digikam_version.h" #include "ditemslist.h" #include "yftalker.h" #include "yfnewalbumdlg.h" #include "digikam_debug.h" #include "wstoolutils.h" #include "wslogindialog.h" #include "yfwidget.h" #include "previewloadthread.h" #include "dprogresswdg.h" #include "dmetadata.h" namespace DigikamGenericYFPlugin { class Q_DECL_HIDDEN YFWindow::Private { public: explicit Private() + : import(false), + widget(nullptr), + loginLabel(nullptr), + headerLabel(nullptr), + changeUserButton(nullptr), + albumsBox(nullptr), + newAlbumButton(nullptr), + reloadAlbumsButton(nullptr), + albumsCombo(nullptr), + accessCombo(nullptr), + hideOriginalCheck(nullptr), + disableCommentsCheck(nullptr), + adultCheck(nullptr), + resizeCheck(nullptr), + dimensionSpin(nullptr), + imageQualitySpin(nullptr), + policyGroup(nullptr), + imgList(nullptr), + progressBar(nullptr), + iface(nullptr) { - import = false; - widget = nullptr; - loginLabel = nullptr; - headerLabel = nullptr; - changeUserButton = nullptr; - albumsBox = nullptr; - newAlbumButton = nullptr; - reloadAlbumsButton = nullptr; - albumsCombo = nullptr; - accessCombo = nullptr; - hideOriginalCheck = nullptr; - disableCommentsCheck = nullptr; - adultCheck = nullptr; - resizeCheck = nullptr; - dimensionSpin = nullptr; - imageQualitySpin = nullptr; - policyGroup = nullptr; - imgList = nullptr; - progressBar = nullptr; - iface = nullptr; } bool import; YFWidget* widget; - // User interface + /// User interface QLabel* loginLabel; QLabel* headerLabel; QPushButton* changeUserButton; - // albums + /// albums QGroupBox* albumsBox; QPushButton* newAlbumButton; QPushButton* reloadAlbumsButton; QComboBox* albumsCombo; - // upload settings + /// upload settings QComboBox* accessCombo; QCheckBox* hideOriginalCheck; QCheckBox* disableCommentsCheck; QCheckBox* adultCheck; QCheckBox* resizeCheck; QSpinBox* dimensionSpin; QSpinBox* imageQualitySpin; QButtonGroup* policyGroup; - DItemsList* imgList; + DItemsList* imgList; DProgressWdg* progressBar; DInfoInterface* iface; - // Backend + /// Backend QString tmpDir; YFTalker talker; QStack transferQueue; DMetadata meta; - // XMP id const for images + /// XMP id const for images static const char* XMP_SERVICE_ID; }; /* * This tag added to our images after uploading to Fotki web service */ const char* YFWindow::Private::XMP_SERVICE_ID = "Xmp.digiKam.yandexGPhotoId"; YFWindow::YFWindow(DInfoInterface* const iface, QWidget* const /*parent*/, bool import) : WSToolDialog(nullptr, QLatin1String("YandexFotki Dialog")), d(new Private) { d->iface = iface; d->import = import; d->tmpDir = WSToolUtils::makeTemporaryDir("yandexfotki").absolutePath() + QLatin1Char('/'); d->widget = new YFWidget(this, d->iface, QLatin1String("Yandex.Fotki")); d->loginLabel = d->widget->getUserNameLabel(); d->headerLabel = d->widget->getHeaderLbl(); d->changeUserButton = d->widget->getChangeUserBtn(); d->newAlbumButton = d->widget->getNewAlbmBtn(); d->reloadAlbumsButton = d->widget->getReloadBtn(); d->albumsCombo = d->widget->getAlbumsCoB(); d->resizeCheck = d->widget->getResizeCheckBox(); d->dimensionSpin = d->widget->getDimensionSpB(); d->imageQualitySpin = d->widget->getImgQualitySpB(); d->imgList = d->widget->imagesList(); d->progressBar = d->widget->progressBar(); d->accessCombo = d->widget->accessCB(); d->hideOriginalCheck = d->widget->hideOriginalCB(); d->disableCommentsCheck = d->widget->disableCommentsCB(); d->adultCheck = d->widget->adultCB(); d->policyGroup = d->widget->policyGB(); d->albumsBox = d->widget->getAlbumBox(); connect(d->changeUserButton, SIGNAL(clicked()), this, SLOT(slotChangeUserClicked())); connect(d->newAlbumButton, SIGNAL(clicked()), this, SLOT(slotNewAlbumRequest()) ); connect(d->reloadAlbumsButton, SIGNAL(clicked()), this, SLOT(slotReloadAlbumsRequest()) ); setMainWidget(d->widget); d->widget->setMinimumSize(800, 600); // -- UI slots ----------------------------------------------------------------------- connect(startButton(), &QPushButton::clicked, this, &YFWindow::slotStartTransfer); connect(this, &WSToolDialog::cancelClicked, this, &YFWindow::slotCancelClicked); connect(this, &QDialog::finished, this, &YFWindow::slotFinished); // -- Talker slots ------------------------------------------------------------------- connect(&d->talker, SIGNAL(signalError()), this, SLOT(slotError())); connect(&d->talker, SIGNAL(signalGetSessionDone()), this, SLOT(slotGetSessionDone())); connect(&d->talker, SIGNAL(signalGetTokenDone()), this, SLOT(slotGetTokenDone())); connect(&d->talker, SIGNAL(signalGetServiceDone()), this, SLOT(slotGetServiceDone())); connect(&d->talker, SIGNAL(signalListAlbumsDone(QList)), this, SLOT(slotListAlbumsDone(QList))); connect(&d->talker, SIGNAL(signalListPhotosDone(QList)), this, SLOT(slotListPhotosDone(QList))); connect(&d->talker, SIGNAL(signalUpdatePhotoDone(YFPhoto&)), this, SLOT(slotUpdatePhotoDone(YFPhoto&))); connect(&d->talker, SIGNAL(signalUpdateAlbumDone()), this, SLOT(slotUpdateAlbumDone())); // read settings from file readSettings(); } YFWindow::~YFWindow() { reset(); WSToolUtils::removeTemporaryDir("yandexfotki"); delete d; } void YFWindow::reactivate() { d->imgList->loadImagesFromCurrentSelection(); reset(); authenticate(false); show(); } void YFWindow::reset() { d->talker.reset(); updateControls(true); updateLabels(); } void YFWindow::updateControls(bool val) { if (val) { if (d->talker.isAuthenticated()) { d->albumsBox->setEnabled(true); startButton()->setEnabled(true); } else { d->albumsBox->setEnabled(false); startButton()->setEnabled(false); } d->changeUserButton->setEnabled(true); setCursor(Qt::ArrowCursor); setRejectButtonMode(QDialogButtonBox::Close); } else { setCursor(Qt::WaitCursor); d->albumsBox->setEnabled(false); d->changeUserButton->setEnabled(false); startButton()->setEnabled(false); setRejectButtonMode(QDialogButtonBox::Cancel); } } void YFWindow::updateLabels() { QString urltext; QString logintext; if (d->talker.isAuthenticated()) { logintext = d->talker.login(); urltext = YFTalker::USERPAGE_URL.arg(d->talker.login()); d->albumsBox->setEnabled(true); } else { logintext = i18n("Unauthorized"); urltext = YFTalker::USERPAGE_DEFAULT_URL; d->albumsCombo->clear(); } d->loginLabel->setText(QString::fromLatin1("%1").arg(logintext)); d->headerLabel->setText(QString::fromLatin1( "

" "%2" "%3" "%4" "

") .arg(urltext) .arg(i18nc("Yandex.Fotki", "Y")) .arg(i18nc("Yandex.Fotki", "andex.")) .arg(i18nc("Yandex.Fotki", "Fotki"))); } void YFWindow::readSettings() { KConfig config; KConfigGroup grp = config.group("YandexFotki Settings"); d->talker.setLogin(grp.readEntry("login", "")); + // don't store tokens in plaintext //d->talker.setToken(grp.readEntry("token", "")); if (grp.readEntry("Resize", false)) { d->resizeCheck->setChecked(true); d->dimensionSpin->setEnabled(true); d->imageQualitySpin->setEnabled(true); } else { d->resizeCheck->setChecked(false); d->dimensionSpin->setEnabled(false); d->imageQualitySpin->setEnabled(false); } d->dimensionSpin->setValue(grp.readEntry("Maximum Width", 1600)); d->imageQualitySpin->setValue(grp.readEntry("Image Quality", 85)); d->policyGroup->button(grp.readEntry("Sync policy", 0))->setChecked(true); } void YFWindow::writeSettings() { KConfig config; KConfigGroup grp = config.group("YandexFotki Settings"); grp.writeEntry("token", d->talker.token()); + // don't store tokens in plaintext //grp.writeEntry("login", d->talker.login()); grp.writeEntry("Resize", d->resizeCheck->isChecked()); grp.writeEntry("Maximum Width", d->dimensionSpin->value()); grp.writeEntry("Image Quality", d->imageQualitySpin->value()); grp.writeEntry("Sync policy", d->policyGroup->checkedId()); } void YFWindow::slotChangeUserClicked() { // force authenticate window authenticate(true); } void YFWindow::closeEvent(QCloseEvent* e) { if (!e) { return; } slotFinished(); e->accept(); } void YFWindow::slotFinished() { writeSettings(); reset(); } void YFWindow::slotCancelClicked() { d->talker.cancel(); updateControls(true); } /* void YFWindow::cancelProcessing() { d->talker.cancel(); d->transferQueue.clear(); d->imgList->processed(false); progressBar()->hide(); } */ void YFWindow::authenticate(bool forceAuthWindow) { // update credentials + if (forceAuthWindow || d->talker.login().isNull() || d->talker.password().isNull()) { WSLoginDialog* const dlg = new WSLoginDialog(this, QLatin1String("Yandex.Fotki"), d->talker.login(), QString()); if (dlg->exec() == QDialog::Accepted) { d->talker.setLogin(dlg->login()); d->talker.setPassword(dlg->password()); } else { // don't change anything return; } delete dlg; } /* else { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Checking old token..."; d->talker.checkToken(); return; } */ // if new credentials non-empty, authenticate + if (!d->talker.login().isEmpty() && !d->talker.password().isEmpty()) { // cancel all tasks first + reset(); // start authentication chain + updateControls(false); d->talker.getService(); } else { // we don't have valid credentials, so cancel all transfers and reset reset(); } /* progressBar()->show(); progressBar()->setFormat(""); */ } void YFWindow::slotListPhotosDone(const QList & photosList) { if (d->import) { slotListPhotosDoneForDownload(photosList); } else { slotListPhotosDoneForUpload(photosList); } } void YFWindow::slotListPhotosDoneForDownload(const QList & photosList) { Q_UNUSED(photosList); updateControls(true); } void YFWindow::slotListPhotosDoneForUpload(const QList & photosList) { updateControls(true); QMap dups; int i = 0; foreach (const YFPhoto& photo, photosList) { dups.insert(photo.urn(), i); i++; } YFWidget::UpdatePolicy policy = static_cast(d->policyGroup->checkedId()); const YFPhoto::Access access = static_cast( d->accessCombo->itemData(d->accessCombo->currentIndex()).toInt()); qCDebug(DIGIKAM_WEBSERVICES_LOG) << ""; qCDebug(DIGIKAM_WEBSERVICES_LOG) << "----"; d->transferQueue.clear(); foreach (const QUrl& url, d->imgList->imageUrls(true)) { DItemInfo info(d->iface->itemInfo(url)); // check if photo alredy uploaded int oldPhotoId = -1; if (d->meta.load(url.toLocalFile())) { QString localId = d->meta.getXmpTagString(d->XMP_SERVICE_ID); oldPhotoId = dups.value(localId, -1); } // get tags QStringList tags = info.tagsPath(); bool updateFile = true; QSet oldtags; if (oldPhotoId != -1) { if (policy == YFWidget::UpdatePolicy::POLICY_SKIP) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "SKIP: " << url; continue; } // old photo copy + d->transferQueue.push(photosList[oldPhotoId]); if (policy == YFWidget::UpdatePolicy::POLICY_UPDATE_MERGE) { foreach (const QString& t, d->transferQueue.top().tags) { oldtags.insert(t); } } if (policy != YFWidget::UpdatePolicy::POLICY_ADDNEW) { updateFile = false; } } else { // empty photo + d->transferQueue.push(YFPhoto()); } YFPhoto& photo = d->transferQueue.top(); + // TODO: updateFile is not used + photo.setOriginalUrl(url.toLocalFile()); photo.setTitle(info.name()); photo.setSummary(info.comment()); photo.setAccess(access); photo.setHideOriginal(d->hideOriginalCheck->isChecked()); photo.setDisableComments(d->disableCommentsCheck->isChecked()); // adult flag can't be removed, API restrictions + if (!photo.isAdult()) + { photo.setAdult(d->adultCheck->isChecked()); + } foreach (const QString& t, tags) { if (!oldtags.contains(t)) { photo.tags.append(t); } } if (updateFile) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "METADATA + IMAGE: " << url; } else { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "METADATA: " << url; } } if (d->transferQueue.isEmpty()) { return; // nothing to do } qCDebug(DIGIKAM_WEBSERVICES_LOG) << "----"; qCDebug(DIGIKAM_WEBSERVICES_LOG) << ""; updateControls(false); updateNextPhoto(); } void YFWindow::updateNextPhoto() { // select only one image from stack while (!d->transferQueue.isEmpty()) { YFPhoto& photo = d->transferQueue.top(); if (!photo.originalUrl().isNull()) { QImage image = PreviewLoadThread::loadHighQualitySynchronously(photo.originalUrl()).copyQImage(); if (image.isNull()) { image.load(photo.originalUrl()); } photo.setLocalUrl(d->tmpDir + QFileInfo(photo.originalUrl()) .baseName() .trimmed() + QLatin1String(".jpg")); bool prepared = false; if (!image.isNull()) { // get temporary file name // rescale image if requested int maxDim = d->dimensionSpin->value(); if (d->resizeCheck->isChecked() && (image.width() > maxDim || image.height() > maxDim)) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Resizing to " << maxDim; image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, Qt::SmoothTransformation); } // copy meta data to temporary image if (image.save(photo.localUrl(), "JPEG", d->imageQualitySpin->value())) { if (d->meta.load(photo.originalUrl())) { d->meta.setItemDimensions(image.size()); d->meta.setItemOrientation(MetaEngine::ORIENTATION_NORMAL); d->meta.setMetadataWritingMode((int)DMetadata::WRITE_TO_FILE_ONLY); d->meta.save(photo.localUrl(), true); prepared = true; } } } if (!prepared) { if (QMessageBox::question(this, i18n("Processing Failed"), i18n("Failed to prepare image %1\n" "Do you want to continue?", photo.originalUrl())) != QMessageBox::Yes) { // stop uploading d->transferQueue.clear(); continue; } else { d->transferQueue.pop(); continue; } } } const YandexFotkiAlbum& album = d->talker.albums().at(d->albumsCombo->currentIndex()); qCDebug(DIGIKAM_WEBSERVICES_LOG) << photo.originalUrl(); d->talker.updatePhoto(photo, album); return; } updateControls(true); QMessageBox::information(this, QString(), i18n("Images have been uploaded")); return; } void YFWindow::slotNewAlbumRequest() { YandexFotkiAlbum album; QPointer dlg = new YFNewAlbumDlg(this, album); if (dlg->exec() == QDialog::Accepted) { updateControls(false); d->talker.updateAlbum(album); } delete dlg; } void YFWindow::slotReloadAlbumsRequest() { updateControls(false); d->talker.listAlbums(); } void YFWindow::slotStartTransfer() { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotStartTransfer invoked"; if (d->albumsCombo->currentIndex() == -1 || d->albumsCombo->count() == 0) { QMessageBox::information(this, QString(), i18n("Please select album first")); return; } // TODO: import support if (!d->import) { // list photos of the album, then start upload const YandexFotkiAlbum& album = d->talker.albums().at(d->albumsCombo->currentIndex()); qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Album selected" << album; updateControls(false); d->talker.listPhotos(album); } } void YFWindow::slotError() { switch (d->talker.state()) { case YFTalker::STATE_GETSESSION_ERROR: QMessageBox::critical(this, QString(), i18n("Session error")); break; case YFTalker::STATE_GETTOKEN_ERROR: QMessageBox::critical(this, QString(), i18n("Token error")); break; case YFTalker::STATE_INVALID_CREDENTIALS: QMessageBox::critical(this, QString(), i18n("Invalid credentials")); // authenticate(true); break; case YFTalker::STATE_GETSERVICE_ERROR: QMessageBox::critical(this, QString(), i18n("Cannot get service document")); break; /* case YFTalker::STATE_CHECKTOKEN_INVALID: // remove old expired token qCDebug(DIGIKAM_WEBSERVICES_LOG) << "CheckToken invalid"; d->talker.setToken(QString()); // don't say anything, simple show new auth window authenticate(true); break; */ case YFTalker::STATE_LISTALBUMS_ERROR: d->albumsCombo->clear(); QMessageBox::critical(this, QString(), i18n("Cannot list albums")); break; case YFTalker::STATE_LISTPHOTOS_ERROR: QMessageBox::critical(this, QString(), i18n("Cannot list photos")); break; case YFTalker::STATE_UPDATEALBUM_ERROR: QMessageBox::critical(this, QString(), i18n("Cannot update album info")); break; case YFTalker::STATE_UPDATEPHOTO_FILE_ERROR: case YFTalker::STATE_UPDATEPHOTO_INFO_ERROR: qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UpdatePhotoError"; if (QMessageBox::question(this, i18n("Uploading Failed"), i18n("Failed to upload image %1\n" "Do you want to continue?", d->transferQueue.top().originalUrl())) != QMessageBox::Yes) { // clear upload stack d->transferQueue.clear(); } else { // cancel current operation d->talker.cancel(); // remove only bad image d->transferQueue.pop(); // and try next updateNextPhoto(); return; } break; default: qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Unhandled error" << d->talker.state(); QMessageBox::critical(this, QString(), i18n("Unknown error")); } // cancel current operation d->talker.cancel(); updateControls(true); } void YFWindow::slotGetServiceDone() { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "GetService Done"; d->talker.getSession(); } void YFWindow::slotGetSessionDone() { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "GetSession Done"; d->talker.getToken(); } void YFWindow::slotGetTokenDone() { updateLabels(); slotReloadAlbumsRequest(); } void YFWindow::slotListAlbumsDone(const QList& albumsList) { d->albumsCombo->clear(); foreach (const YandexFotkiAlbum& album, albumsList) { QString albumIcon; if (album.isProtected()) { albumIcon = QLatin1String("folder-locked"); } else { albumIcon = QLatin1String("folder-image"); } d->albumsCombo->addItem(QIcon::fromTheme(albumIcon), album.toString()); } d->albumsCombo->setEnabled(true); updateControls(true); } void YFWindow::slotUpdatePhotoDone(YFPhoto& photo) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "photoUploaded" << photo; if (d->meta.supportXmp() && d->meta.canWriteXmp(photo.originalUrl()) && d->meta.load(photo.originalUrl())) { // ignore errors here if (d->meta.setXmpTagString(d->XMP_SERVICE_ID, photo.urn()) && d->meta.save(photo.originalUrl())) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "MARK: " << photo.originalUrl(); } } d->transferQueue.pop(); updateNextPhoto(); } void YFWindow::slotUpdateAlbumDone() { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Album created"; d->albumsCombo->clear(); d->talker.listAlbums(); } } // namespace DigikamGenericYFPlugin