diff --git a/common/libkipiplugins/widgets/kpimageslist.cpp b/common/libkipiplugins/widgets/kpimageslist.cpp index 9424ba8f5..ae9b6da72 100644 --- a/common/libkipiplugins/widgets/kpimageslist.cpp +++ b/common/libkipiplugins/widgets/kpimageslist.cpp @@ -1,1347 +1,1325 @@ /* ============================================================ * * This file is a part of kipi-plugins project * http://www.digikam.org * * Date : 2008-05-21 * Description : widget to display an imagelist * * Copyright (C) 2006-2017 by Gilles Caulier * Copyright (C) 2008-2010 by Andi Clemens * Copyright (C) 2009-2010 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 "kpimageslist.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include // Libkipi includes #include #include #include // Local includes #include "kpimageinfo.h" #include "kpimagedialog.h" #include "kipiplugins_debug.h" #include "kputil.h" using namespace KIPIPlugins; namespace KIPIPlugins { const int DEFAULTSIZE = 48; class KPImagesListViewItem::Private { public: Private() { rating = -1; view = 0; state = Waiting; hasThumb = false; } bool hasThumb; // True if thumbnails is a real photo thumbs int rating; // Image Rating from Kipi host. QString comments; // Image comments from Kipi host. QStringList tags; // List of keywords from Kipi host. QUrl url; // Image url provided by Kipi host. QPixmap thumb; // Image thumbnail. KPImagesListView* view; State state; }; KPImagesListViewItem::KPImagesListViewItem(KPImagesListView* const view, const QUrl& url) : QTreeWidgetItem(view), d(new Private) { setUrl(url); setRating(-1); setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable); d->view = view; int iconSize = d->view->iconSize().width(); setThumb(QIcon::fromTheme(QString::fromLatin1("image-x-generic")).pixmap(iconSize, iconSize, QIcon::Disabled), false); qCDebug(KIPIPLUGINS_LOG) << "Creating new ImageListViewItem with url " << d->url << " for list view " << d->view; } KPImagesListViewItem::~KPImagesListViewItem() { delete d; } bool KPImagesListViewItem::hasValidThumbnail() const { return d->hasThumb; } void KPImagesListViewItem::updateInformation() { if (d->view->iface()) { KPImageInfo info(d->url); setComments(info.description()); setTags(QStringList()); if (d->view->iface()->hasFeature(HostSupportsTags)) { setTags(info.keywords()); } if (d->view->iface()->hasFeature(HostSupportsRating)) { setRating(info.rating()); } } } void KPImagesListViewItem::setUrl(const QUrl& url) { d->url = url; setText(KPImagesListView::Filename, d->url.fileName()); } QUrl KPImagesListViewItem::url() const { return d->url; } void KPImagesListViewItem::setComments(const QString& comments) { d->comments = comments; } QString KPImagesListViewItem::comments() const { return d->comments; } void KPImagesListViewItem::setTags(const QStringList& tags) { d->tags = tags; } QStringList KPImagesListViewItem::tags() const { return d->tags; } void KPImagesListViewItem::setRating(int rating) { d->rating = rating; } int KPImagesListViewItem::rating() const { return d->rating; } void KPImagesListViewItem::setPixmap(const QPixmap& pix) { QIcon icon = QIcon(pix); // We make sure the preview icon stays the same regardless of the role icon.addPixmap(pix, QIcon::Selected, QIcon::On); icon.addPixmap(pix, QIcon::Selected, QIcon::Off); icon.addPixmap(pix, QIcon::Active, QIcon::On); icon.addPixmap(pix, QIcon::Active, QIcon::Off); icon.addPixmap(pix, QIcon::Normal, QIcon::On); icon.addPixmap(pix, QIcon::Normal, QIcon::Off); setIcon(KPImagesListView::Thumbnail, icon); } void KPImagesListViewItem::setThumb(const QPixmap& pix, bool hasThumb) { if (hasThumb) { qCDebug(KIPIPLUGINS_LOG) << "Received new thumbnail for url " << d->url << " for view " << d->view; } if (!d->view) { qCCritical(KIPIPLUGINS_LOG) << "This item doesn't have a tree view. " << "This should never happen!"; return; } int iconSize = qMax(d->view->iconSize().width(), d->view->iconSize().height()); QPixmap pixmap(iconSize + 2, iconSize + 2); pixmap.fill(Qt::transparent); QPainter p(&pixmap); p.drawPixmap((pixmap.width() / 2) - (pix.width() / 2), (pixmap.height() / 2) - (pix.height() / 2), pix); d->thumb = pixmap; setPixmap(d->thumb); d->hasThumb = hasThumb; } void KPImagesListViewItem::setProgressAnimation(const QPixmap& pix) { QPixmap overlay = d->thumb; QPixmap mask(overlay.size()); mask.fill(QColor(128, 128, 128, 192)); QPainter p(&overlay); p.drawPixmap(0, 0, mask); p.drawPixmap((overlay.width() / 2) - (pix.width() / 2), (overlay.height() / 2) - (pix.height() / 2), pix); setPixmap(overlay); } void KPImagesListViewItem::setProcessedIcon(const QIcon& icon) { setIcon(KPImagesListView::Filename, icon); // reset thumbnail back to no animation pix setPixmap(d->thumb); } void KPImagesListViewItem::setState(State state) { d->state = state; } KPImagesListViewItem::State KPImagesListViewItem::state() const { return d->state; } KPImagesListView* KPImagesListViewItem::view() const { return d->view; } // --------------------------------------------------------------------------- KPImagesListView::KPImagesListView(KPImagesList* const parent) : QTreeWidget(parent) { setup(DEFAULTSIZE); } KPImagesListView::KPImagesListView(int iconSize, KPImagesList* const parent) : QTreeWidget(parent) { setup(iconSize); } KPImagesListView::~KPImagesListView() { } void KPImagesListView::setup(int iconSize) { m_iconSize = iconSize; setIconSize(QSize(m_iconSize, m_iconSize)); setAlternatingRowColors(true); setSelectionMode(QAbstractItemView::ExtendedSelection); enableDragAndDrop(true); setSortingEnabled(false); setAllColumnsShowFocus(true); setRootIsDecorated(false); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setColumnCount(8); setHeaderLabels(QStringList() << i18n("Thumbnail") << i18n("File Name") << i18n("User1") << i18n("User2") << i18n("User3") << i18n("User4") << i18n("User5") << i18n("User6")); hideColumn(User1); hideColumn(User2); hideColumn(User3); hideColumn(User4); hideColumn(User5); hideColumn(User6); header()->setSectionResizeMode(User1, QHeaderView::Interactive); header()->setSectionResizeMode(User2, QHeaderView::Interactive); header()->setSectionResizeMode(User3, QHeaderView::Interactive); header()->setSectionResizeMode(User4, QHeaderView::Interactive); header()->setSectionResizeMode(User5, QHeaderView::Interactive); header()->setSectionResizeMode(User6, QHeaderView::Stretch); connect(this, &KPImagesListView::itemClicked, this, &KPImagesListView::slotItemClicked); } void KPImagesListView::enableDragAndDrop(const bool enable) { setDragEnabled(enable); viewport()->setAcceptDrops(enable); setDragDropMode(enable ? QAbstractItemView::InternalMove : QAbstractItemView::NoDragDrop); setDragDropOverwriteMode(enable); setDropIndicatorShown(enable); } void KPImagesListView::drawRow(QPainter* p, const QStyleOptionViewItem& opt, const QModelIndex& index) const { KPImagesListViewItem* const item = dynamic_cast(itemFromIndex(index)); if (item && !item->hasValidThumbnail()) { KPImagesList* const view = dynamic_cast(parent()); if (view) { view->updateThumbnail(item->url()); } } QTreeWidget::drawRow(p, opt, index); } void KPImagesListView::slotItemClicked(QTreeWidgetItem* item, int column) { Q_UNUSED(column) if (!item) { return; } emit signalItemClicked(item); } void KPImagesListView::setColumnLabel(ColumnType column, const QString& label) { headerItem()->setText(column, label); } void KPImagesListView::setColumnEnabled(ColumnType column, bool enable) { if (enable) { showColumn(column); } else { hideColumn(column); } } void KPImagesListView::setColumn(ColumnType column, const QString& label, bool enable) { setColumnLabel(column, label); setColumnEnabled(column, enable); } KPImagesListViewItem* KPImagesListView::findItem(const QUrl& url) { QTreeWidgetItemIterator it(this); while (*it) { KPImagesListViewItem* const lvItem = dynamic_cast(*it); if (lvItem && lvItem->url() == url) { return lvItem; } ++it; } return 0; } QModelIndex KPImagesListView::indexFromItem(KPImagesListViewItem* item, int column) const { return QTreeWidget::indexFromItem(item, column); } void KPImagesListView::contextMenuEvent(QContextMenuEvent* e) { QTreeWidget::contextMenuEvent(e); emit signalContextMenuRequested(); } void KPImagesListView::dragEnterEvent(QDragEnterEvent* e) { QTreeWidget::dragEnterEvent(e); if (e->mimeData()->hasUrls()) { e->acceptProposedAction(); } } void KPImagesListView::dragMoveEvent(QDragMoveEvent* e) { QTreeWidget::dragMoveEvent(e); if (e->mimeData()->hasUrls()) { e->acceptProposedAction(); } } void KPImagesListView::dropEvent(QDropEvent* e) { QTreeWidget::dropEvent(e); QList list = e->mimeData()->urls(); QList urls; foreach(const QUrl& url, list) { QFileInfo fi(url.toLocalFile()); if (fi.isFile() && fi.exists()) { urls.append(url); } } if (!urls.isEmpty()) { emit signalAddedDropedItems(urls); } } Interface* KPImagesListView::iface() const { KPImagesList* const p = dynamic_cast(parent()); if (p) { return p->iface(); } return 0; } // --------------------------------------------------------------------------- CtrlButton::CtrlButton(const QIcon& icon, QWidget* const parent) : QPushButton(parent) { const int btnSize = 32; setMinimumSize(btnSize, btnSize); setMaximumSize(btnSize, btnSize); setIcon(icon); } CtrlButton::~CtrlButton() { } // --------------------------------------------------------------------------- class KPImagesList::Private { public: Private() { listView = 0; iface = 0; addButton = 0; removeButton = 0; moveUpButton = 0; moveDownButton = 0; clearButton = 0; loadButton = 0; saveButton = 0; iconSize = DEFAULTSIZE; allowRAW = true; controlButtonsEnabled = true; allowDuplicate = false; progressCount = 0; progressTimer = 0; progressPix = KPWorkingPixmap(); PluginLoader* const pl = PluginLoader::instance(); if (pl) { iface = pl->interface(); } } bool allowRAW; bool allowDuplicate; bool controlButtonsEnabled; int iconSize; CtrlButton* addButton; CtrlButton* removeButton; CtrlButton* moveUpButton; CtrlButton* moveDownButton; CtrlButton* clearButton; CtrlButton* loadButton; CtrlButton* saveButton; QList processItems; KPWorkingPixmap progressPix; int progressCount; QTimer* progressTimer; KPImagesListView* listView; Interface* iface; }; KPImagesList::KPImagesList(QWidget* const parent, int iconSize) : QWidget(parent), d(new Private) { if (iconSize != -1) // default = ICONSIZE { setIconSize(iconSize); } // -------------------------------------------------------- d->listView = new KPImagesListView(d->iconSize, this); d->listView->setSelectionMode(QAbstractItemView::ExtendedSelection); // -------------------------------------------------------- d->addButton = new CtrlButton(QIcon::fromTheme(QString::fromLatin1("list-add")).pixmap(16, 16), this); d->removeButton = new CtrlButton(QIcon::fromTheme(QString::fromLatin1("list-remove")).pixmap(16, 16), this); d->moveUpButton = new CtrlButton(QIcon::fromTheme(QString::fromLatin1("go-up")).pixmap(16, 16), this); d->moveDownButton = new CtrlButton(QIcon::fromTheme(QString::fromLatin1("go-down")).pixmap(16, 16), this); d->clearButton = new CtrlButton(QIcon::fromTheme(QString::fromLatin1("edit-clear")).pixmap(16, 16), this); d->loadButton = new CtrlButton(QIcon::fromTheme(QString::fromLatin1("document-open")).pixmap(16, 16), this); d->saveButton = new CtrlButton(QIcon::fromTheme(QString::fromLatin1("document-save")).pixmap(16, 16), this); d->addButton->setToolTip(i18n("Add new images to the list")); d->removeButton->setToolTip(i18n("Remove selected images from the list")); d->moveUpButton->setToolTip(i18n("Move current selected image up in the list")); d->moveDownButton->setToolTip(i18n("Move current selected image down in the list")); d->clearButton->setToolTip(i18n("Clear the list.")); d->loadButton->setToolTip(i18n("Load a saved list.")); d->saveButton->setToolTip(i18n("Save the list.")); d->progressTimer = new QTimer(this); // -------------------------------------------------------- setControlButtons(Add | Remove | MoveUp | MoveDown | Clear | Save | Load ); // add all buttons (default) setControlButtonsPlacement(ControlButtonsRight); // buttons on the right (default) enableDragAndDrop(true); // enable drag and drop (default) // -------------------------------------------------------- connect(d->listView, &KPImagesListView::signalAddedDropedItems, this, &KPImagesList::slotAddImages); if (d->iface) { connect(d->iface, &Interface::gotThumbnail, this, &KPImagesList::slotThumbnail); } connect(d->listView, &KPImagesListView::signalItemClicked, this, &KPImagesList::signalItemClicked); connect(d->listView, &KPImagesListView::signalContextMenuRequested, this, &KPImagesList::signalContextMenuRequested); // queue this connection because itemSelectionChanged is emitted // while items are deleted, and accessing selectedItems at that // time causes a crash ... connect(d->listView, &KPImagesListView::itemSelectionChanged, this, &KPImagesList::slotImageListChanged, Qt::QueuedConnection); connect(this, &KPImagesList::signalImageListChanged, this, &KPImagesList::slotImageListChanged); // -------------------------------------------------------- connect(d->addButton, &CtrlButton::clicked, this, &KPImagesList::slotAddItems); connect(d->removeButton, &CtrlButton::clicked, this, &KPImagesList::slotRemoveItems); connect(d->moveUpButton, &CtrlButton::clicked, this, &KPImagesList::slotMoveUpItems); connect(d->moveDownButton, &CtrlButton::clicked, this, &KPImagesList::slotMoveDownItems); connect(d->clearButton, &CtrlButton::clicked, this, &KPImagesList::slotClearItems); connect(d->loadButton, &CtrlButton::clicked, this, &KPImagesList::slotLoadItems); connect(d->saveButton, &CtrlButton::clicked, this, &KPImagesList::slotSaveItems); connect(d->progressTimer, &QTimer::timeout, this, &KPImagesList::slotProgressTimerDone); // -------------------------------------------------------- emit signalImageListChanged(); } void KPImagesList::enableControlButtons(bool enable) { d->controlButtonsEnabled = enable; slotImageListChanged(); } void KPImagesList::enableDragAndDrop(const bool enable) { d->listView->enableDragAndDrop(enable); } void KPImagesList::setControlButtonsPlacement(ControlButtonPlacement placement) { delete layout(); const int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); QGridLayout* const mainLayout = new QGridLayout; mainLayout->addWidget(d->listView, 1, 1, 1, 1); mainLayout->setRowStretch(1, 10); mainLayout->setColumnStretch(1, 10); mainLayout->setContentsMargins(spacing, spacing, spacing, spacing); mainLayout->setSpacing(spacing); // -------------------------------------------------------- QHBoxLayout* const hBtnLayout = new QHBoxLayout; hBtnLayout->addStretch(10); hBtnLayout->addWidget(d->moveUpButton); hBtnLayout->addWidget(d->moveDownButton); hBtnLayout->addWidget(d->addButton); hBtnLayout->addWidget(d->removeButton); hBtnLayout->addWidget(d->loadButton); hBtnLayout->addWidget(d->saveButton); hBtnLayout->addWidget(d->clearButton); hBtnLayout->addStretch(10); // -------------------------------------------------------- QVBoxLayout* const vBtnLayout = new QVBoxLayout; vBtnLayout->addStretch(10); vBtnLayout->addWidget(d->moveUpButton); vBtnLayout->addWidget(d->moveDownButton); vBtnLayout->addWidget(d->addButton); vBtnLayout->addWidget(d->removeButton); vBtnLayout->addWidget(d->loadButton); vBtnLayout->addWidget(d->saveButton); vBtnLayout->addWidget(d->clearButton); vBtnLayout->addStretch(10); // -------------------------------------------------------- switch (placement) { case ControlButtonsAbove: mainLayout->addLayout(hBtnLayout, 0, 1, 1, 1); delete vBtnLayout; break; case ControlButtonsBelow: mainLayout->addLayout(hBtnLayout, 2, 1, 1, 1); delete vBtnLayout; break; case ControlButtonsLeft: mainLayout->addLayout(vBtnLayout, 1, 0, 1, 1); delete hBtnLayout; break; case ControlButtonsRight: mainLayout->addLayout(vBtnLayout, 1, 2, 1, 1); delete hBtnLayout; break; case NoControlButtons: default: { delete vBtnLayout; delete hBtnLayout; // set all buttons invisible setControlButtons(0x0); break; } } setLayout(mainLayout); } void KPImagesList::setControlButtons(ControlButtons buttonMask) { d->addButton->setVisible(buttonMask & Add); d->removeButton->setVisible(buttonMask & Remove); d->moveUpButton->setVisible(buttonMask & MoveUp); d->moveDownButton->setVisible(buttonMask & MoveDown); d->clearButton->setVisible(buttonMask & Clear); d->loadButton->setVisible(buttonMask & Load); d->saveButton->setVisible(buttonMask & Save); } KPImagesList::~KPImagesList() { delete d; } void KPImagesList::setAllowDuplicate(bool allow) { d->allowDuplicate = allow; } void KPImagesList::setAllowRAW(bool allow) { d->allowRAW = allow; } void KPImagesList::setIconSize(int size) { if (size < 16) { d->iconSize = 16; } else if (size > 128) { d->iconSize = 128; } else { d->iconSize = size; } } int KPImagesList::iconSize() const { return d->iconSize; } void KPImagesList::loadImagesFromCurrentSelection() { - bool selection = checkSelection(); - - if (selection == true) + if (!d->iface) { - if (!d->iface) - { - return; - } + return; + } - ImageCollection images = d->iface->currentSelection(); + ImageCollection selection = d->iface->currentSelection(); - if (images.isValid()) + if (!selection.images().isEmpty()) + { + if (selection.isValid()) { - slotAddImages(images.images()); + slotAddImages(selection.images()); } } else { loadImagesFromCurrentAlbum(); } } void KPImagesList::loadImagesFromCurrentAlbum() { if (!d->iface) { return; } ImageCollection images = d->iface->currentAlbum(); if (images.isValid()) { slotAddImages(images.images()); } } -bool KPImagesList::checkSelection() -{ - if (!d->iface) - { - return false; - } - - ImageCollection images = d->iface->currentSelection(); - bool check_empty = images.images().empty(); - - if (check_empty == true) - { - return false; - } - else - { - return true; - } -} - bool KPImagesList::isRawFile(const QUrl& url) const { QString rawFilesExt = d->iface->rawFiles(); QFileInfo fileInfo(url.toLocalFile()); return (rawFilesExt.toUpper().contains(fileInfo.suffix().toUpper())); } void KPImagesList::slotAddImages(const QList& list) { if (list.count() == 0) { return; } QList urls; bool raw = false; for (QList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) { QUrl imageUrl = *it; // Check if the new item already exist in the list. bool found = false; QTreeWidgetItemIterator iter(d->listView); while (*iter) { KPImagesListViewItem* const item = dynamic_cast(*iter); if (item && item->url() == imageUrl) { found = true; } ++iter; } if (d->allowDuplicate || !found) { // if RAW files are not allowed, skip the image if (!d->allowRAW && isRawFile(imageUrl)) { raw = true; continue; } new KPImagesListViewItem(listView(), imageUrl); urls.append(imageUrl); } } emit signalAddItems(urls); emit signalImageListChanged(); emit signalFoundRAWImages(raw); } void KPImagesList::slotAddItems() { KPImageDialog dlg(this, false); QList urls = dlg.urls(); if (!urls.isEmpty()) { slotAddImages(urls); } // emit signalImageListChanged(); } void KPImagesList::slotRemoveItems() { QList selectedItemsList = d->listView->selectedItems(); QList urls; for (QList::const_iterator it = selectedItemsList.constBegin(); it != selectedItemsList.constEnd(); ++it) { KPImagesListViewItem* const item = dynamic_cast(*it); if (item) { emit signalRemovingItem(item); urls.append(item->url()); if (d->processItems.contains(item->url())) { d->processItems.removeAll(item->url()); } d->listView->removeItemWidget(*it, 0); delete *it; } } emit signalRemovedItems(urls); emit signalImageListChanged(); } void KPImagesList::slotMoveUpItems() { // move above item down, then we don't have to fix the focus QModelIndex curIndex = listView()->currentIndex(); if (!curIndex.isValid()) { return; } QModelIndex aboveIndex = listView()->indexAbove(curIndex); if (!aboveIndex.isValid()) { return; } QTreeWidgetItem* const temp = listView()->takeTopLevelItem(aboveIndex.row()); listView()->insertTopLevelItem(curIndex.row(), temp); // this is a quick fix. We loose the extra tags in flickr upload, but at list we don't get a crash KPImagesListViewItem* const uw = dynamic_cast(temp); if (uw) uw->updateItemWidgets(); emit signalImageListChanged(); emit signalMoveUpItem(); } void KPImagesList::slotMoveDownItems() { // move below item up, then we don't have to fix the focus QModelIndex curIndex = listView()->currentIndex(); if (!curIndex.isValid()) { return; } QModelIndex belowIndex = listView()->indexBelow(curIndex); if (!belowIndex.isValid()) { return; } QTreeWidgetItem* const temp = listView()->takeTopLevelItem(belowIndex.row()); listView()->insertTopLevelItem(curIndex.row(), temp); // This is a quick fix. We can loose extra tags in uploader, but at least we don't get a crash KPImagesListViewItem* const uw = dynamic_cast(temp); if (uw) uw->updateItemWidgets(); emit signalImageListChanged(); emit signalMoveDownItem(); } void KPImagesList::slotClearItems() { listView()->selectAll(); slotRemoveItems(); listView()->clear(); } void KPImagesList::slotLoadItems() { QUrl loadLevelsFile; loadLevelsFile = QFileDialog::getOpenFileUrl(this, i18n("Select the image file list to load"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)), i18n("All Files (*)")); if ( loadLevelsFile.isEmpty() ) { qCDebug(KIPIPLUGINS_LOG) << "empty url"; return; } QFile file(loadLevelsFile.toLocalFile()); qCDebug(KIPIPLUGINS_LOG) << "file path " << loadLevelsFile.toLocalFile(); if (!file.open(QIODevice::ReadOnly)) { qCDebug(KIPIPLUGINS_LOG) << "Cannot open file"; return; } QXmlStreamReader xmlReader; xmlReader.setDevice(&file); while (!xmlReader.atEnd()) { if (xmlReader.isStartElement() && xmlReader.name() == QString::fromLatin1("Image")) { // get all attributes and its value of a tag in attrs variable. QXmlStreamAttributes attrs = xmlReader.attributes(); // get value of each attribute from QXmlStreamAttributes QStringRef url = attrs.value(QString::fromLatin1("url")); if (url.isEmpty()) { xmlReader.readNext(); continue; } QList urls; urls.append(QUrl(url.toString())); if (!urls.isEmpty()) { //allow plugins to append a new file slotAddImages(urls); // read plugin Image custom attributes and children element emit signalXMLLoadImageElement(xmlReader); } } else if (xmlReader.isStartElement() && xmlReader.name() != QString::fromLatin1("Images")) { // unmanaged start element (it should be plugins one) emit signalXMLCustomElements(xmlReader); } else if (xmlReader.isEndElement() && xmlReader.name() == QString::fromLatin1("Images")) { // if EndElement is Images return return; } xmlReader.readNext(); } } void KPImagesList::slotSaveItems() { QUrl saveLevelsFile; saveLevelsFile = QFileDialog::getSaveFileUrl(this, i18n("Select the image file list to save"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)), i18n("All Files (*)")); qCDebug(KIPIPLUGINS_LOG) << "file url " << saveLevelsFile.toDisplayString(); if (saveLevelsFile.isEmpty()) { qCDebug(KIPIPLUGINS_LOG) << "empty url"; return; } QFile file(saveLevelsFile.toLocalFile()); if (!file.open(QIODevice::WriteOnly)) { qCDebug(KIPIPLUGINS_LOG) << "Cannot open target file"; return; } QXmlStreamWriter xmlWriter; xmlWriter.setDevice(&file); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeStartElement(QString::fromLatin1("Images")); QTreeWidgetItemIterator it(listView()); while (*it) { KPImagesListViewItem* const lvItem = dynamic_cast(*it); if (lvItem) { xmlWriter.writeStartElement(QString::fromLatin1("Image")); xmlWriter.writeAttribute(QString::fromLatin1("url"), lvItem->url().toDisplayString()); // emit xmlWriter, item? emit signalXMLSaveItem(xmlWriter, lvItem); xmlWriter.writeEndElement(); // Image } ++it; } emit signalXMLCustomElements(xmlWriter); xmlWriter.writeEndElement(); // Images xmlWriter.writeEndDocument(); // end document } void KPImagesList::removeItemByUrl(const QUrl& url) { bool found; do { found = false; QTreeWidgetItemIterator it(d->listView); while (*it) { KPImagesListViewItem* const item = dynamic_cast(*it); if (item && item->url() == url) { emit signalRemovingItem(item); if (d->processItems.contains(item->url())) { d->processItems.removeAll(item->url()); } delete item; found = true; break; } ++it; } } while (found); emit signalImageListChanged(); } QList KPImagesList::imageUrls(bool onlyUnprocessed) const { QList list; QTreeWidgetItemIterator it(d->listView); while (*it) { KPImagesListViewItem* const item = dynamic_cast(*it); if (item) { if ((onlyUnprocessed == false) || (item->state() != KPImagesListViewItem::Success)) { list.append(item->url()); } } ++it; } return list; } void KPImagesList::slotProgressTimerDone() { if (!d->processItems.isEmpty()) { foreach(const QUrl& url, d->processItems) { KPImagesListViewItem* const item = listView()->findItem(url); if (item) item->setProgressAnimation(d->progressPix.frameAt(d->progressCount)); } d->progressCount++; if (d->progressCount == 8) { d->progressCount = 0; } d->progressTimer->start(300); } } void KPImagesList::processing(const QUrl& url) { KPImagesListViewItem* const item = listView()->findItem(url); if (item) { d->processItems.append(url); d->listView->setCurrentItem(item, true); d->listView->scrollToItem(item); d->progressTimer->start(300); } } void KPImagesList::processed(const QUrl& url, bool success) { KPImagesListViewItem* const item = listView()->findItem(url); if (item) { d->processItems.removeAll(url); item->setProcessedIcon(QIcon::fromTheme(success ? QString::fromLatin1("dialog-ok-apply") : QString::fromLatin1("dialog-cancel")).pixmap(16, 16)); item->setState(success ? KPImagesListViewItem::Success : KPImagesListViewItem::Failed); if (d->processItems.isEmpty()) d->progressTimer->stop(); } } void KPImagesList::cancelProcess() { foreach(const QUrl& url, d->processItems) { processed(url, false); } } void KPImagesList::clearProcessedStatus() { QTreeWidgetItemIterator it(d->listView); while (*it) { KPImagesListViewItem* const lvItem = dynamic_cast(*it); if (lvItem) { lvItem->setProcessedIcon(QIcon()); } ++it; } } KPImagesListView* KPImagesList::listView() const { return d->listView; } Interface* KPImagesList::iface() const { return d->iface; } void KPImagesList::slotImageListChanged() { const QList selectedItemsList = d->listView->selectedItems(); const bool haveImages = !(imageUrls().isEmpty()) && d->controlButtonsEnabled; const bool haveSelectedImages = !(selectedItemsList.isEmpty()) && d->controlButtonsEnabled; const bool haveOnlyOneSelectedImage = (selectedItemsList.count() == 1) && d->controlButtonsEnabled; d->removeButton->setEnabled(haveSelectedImages); d->moveUpButton->setEnabled(haveOnlyOneSelectedImage); d->moveDownButton->setEnabled(haveOnlyOneSelectedImage); d->clearButton->setEnabled(haveImages); // All buttons are enabled / disabled now, but the "Add" button should always be // enabled, if the buttons are not explicitly disabled with enableControlButtons() d->addButton->setEnabled(d->controlButtonsEnabled); // TODO: should they be enabled by default now? d->loadButton->setEnabled(d->controlButtonsEnabled); d->saveButton->setEnabled(d->controlButtonsEnabled); } void KPImagesList::updateThumbnail(const QUrl& url) { if (d->iface) { qCDebug(KIPIPLUGINS_LOG) << "Request to update thumbnail for " << url; d->iface->thumbnails(QList() << url, DEFAULTSIZE); } else { qCDebug(KIPIPLUGINS_LOG) << "No KIPI interface available : thumbnails will not generated."; } } void KPImagesList::slotThumbnail(const QUrl& url, const QPixmap& pix) { qCDebug(KIPIPLUGINS_LOG) << "KIPI host send thumb (" << pix.size() << ") for " << url; QTreeWidgetItemIterator it(d->listView); while (*it) { KPImagesListViewItem* const item = dynamic_cast(*it); if (item && item->url() == url) { if (!pix.isNull()) { qCDebug(KIPIPLUGINS_LOG) << "Update thumb in list for " << url; item->setThumb(pix.scaled(d->iconSize, d->iconSize, Qt::KeepAspectRatio)); } if (!d->allowDuplicate) return; } ++it; } } KPImagesListViewItem* KPImagesListView::getCurrentItem() const { QTreeWidgetItem* const currentTreeItem = currentItem(); if (!currentTreeItem) { return 0; } return dynamic_cast(currentTreeItem); } QUrl KPImagesList::getCurrentUrl() const { KPImagesListViewItem* const currentItem = d->listView->getCurrentItem(); if (!currentItem) { return QUrl(); } return currentItem->url(); } } // namespace KIPIPlugins diff --git a/common/libkipiplugins/widgets/kpimageslist.h b/common/libkipiplugins/widgets/kpimageslist.h index 615b0d658..9dfb67097 100644 --- a/common/libkipiplugins/widgets/kpimageslist.h +++ b/common/libkipiplugins/widgets/kpimageslist.h @@ -1,307 +1,303 @@ /* ============================================================ * * This file is a part of kipi-plugins project * http://www.digikam.org * * Date : 2008-05-21 * Description : widget to display an imagelist * * Copyright (C) 2006-2017 by Gilles Caulier * Copyright (C) 2008-2010 by Andi Clemens * Copyright (C) 2009-2010 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. * * ============================================================ */ #ifndef KPIMAGESLIST_H #define KPIMAGESLIST_H // Qt includes #include #include #include #include #include #include #include #include // Local includes #include "kipiplugins_export.h" namespace KIPI { class Interface; } using namespace KIPI; namespace KIPIPlugins { class KPImagesList; class KPImagesListView; class KIPIPLUGINS_EXPORT KPImagesListViewItem : public QTreeWidgetItem { public: enum State { Waiting, Success, Failed }; public: explicit KPImagesListViewItem(KPImagesListView* const view, const QUrl& url); ~KPImagesListViewItem(); bool hasValidThumbnail() const; void setUrl(const QUrl& url); QUrl url() const; void setComments(const QString& comments); QString comments() const; void setTags(const QStringList& tags); QStringList tags() const; void setRating(int rating); int rating() const; void setThumb(const QPixmap& pix, bool hasThumb=true); void setProgressAnimation(const QPixmap& pix); void setProcessedIcon(const QIcon& icon); void setState(State state); State state() const; void updateInformation(); // implement this, if you have special item widgets, e.g. an edit line // they will be set automatically when adding items, changing order, etc. virtual void updateItemWidgets() {}; protected: KPImagesListView* view() const; private: void setPixmap(const QPixmap& pix); private: class Private; Private* const d; }; // ------------------------------------------------------------------------- class KIPIPLUGINS_EXPORT KPImagesListView : public QTreeWidget { Q_OBJECT public: enum ColumnType { Thumbnail = 0, Filename, User1, User2, User3, User4, User5, User6 }; explicit KPImagesListView(KPImagesList* const parent = 0); explicit KPImagesListView(int iconSize, KPImagesList* const parent = 0); ~KPImagesListView(); void setColumnLabel(ColumnType column, const QString& label); void setColumnEnabled(ColumnType column, bool enable); void setColumn(ColumnType column, const QString& label, bool enable); KPImagesListViewItem* findItem(const QUrl& url); QModelIndex indexFromItem(KPImagesListViewItem* item, int column = 0) const; KPImagesListViewItem* getCurrentItem() const; Interface* iface() const; Q_SIGNALS: void signalAddedDropedItems(const QList&); void signalItemClicked(QTreeWidgetItem*); void signalContextMenuRequested(); private Q_SLOTS: void slotItemClicked(QTreeWidgetItem* item, int column); public: void enableDragAndDrop(const bool enable = true); private: void dragEnterEvent(QDragEnterEvent* e); void dragMoveEvent(QDragMoveEvent* e); void dropEvent(QDropEvent* e); void contextMenuEvent(QContextMenuEvent * e); void setup(int iconSize); void drawRow(QPainter* p, const QStyleOptionViewItem& opt, const QModelIndex& index) const; private: int m_iconSize; }; // ------------------------------------------------------------------------- class CtrlButton : public QPushButton { Q_OBJECT public: explicit CtrlButton(const QIcon& icon, QWidget* parent = 0); virtual ~CtrlButton(); }; // ------------------------------------------------------------------------- class KIPIPLUGINS_EXPORT KPImagesList : public QWidget { Q_OBJECT public: enum ControlButtonPlacement { NoControlButtons = 0, ControlButtonsLeft, ControlButtonsRight, ControlButtonsAbove, ControlButtonsBelow }; enum ControlButton { Add = 0x1, Remove = 0x2, MoveUp = 0x4, MoveDown = 0x8, Clear = 0x10, Load = 0x20, Save = 0x40 }; Q_DECLARE_FLAGS(ControlButtons, ControlButton) public: explicit KPImagesList(QWidget* const parent = 0, int iconSize = -1); virtual ~KPImagesList(); void setAllowRAW(bool allow); void setAllowDuplicate(bool allow); void loadImagesFromCurrentSelection(); /** A function to load all the images from the album if no image has been selected by user. */ void loadImagesFromCurrentAlbum(); - /** a function to check whether an image has been selected or not. - */ - bool checkSelection(); - int iconSize() const; KPImagesListView* listView() const; Interface* iface() const; void processing(const QUrl& url); void processed(const QUrl& url, bool success); void cancelProcess(); void clearProcessedStatus(); void setControlButtons(ControlButtons buttonMask); void setControlButtonsPlacement(ControlButtonPlacement placement); void enableControlButtons(bool enable = true); void enableDragAndDrop(const bool enable = true); void updateThumbnail(const QUrl& url); virtual QList imageUrls(bool onlyUnprocessed = false) const; virtual void removeItemByUrl(const QUrl& url); QUrl getCurrentUrl() const; Q_SIGNALS: void signalAddItems(const QList&); void signalMoveUpItem(); void signalMoveDownItem(); void signalRemovedItems(const QList&); void signalRemovingItem(KIPIPlugins::KPImagesListViewItem*); void signalImageListChanged(); void signalFoundRAWImages(bool); void signalItemClicked(QTreeWidgetItem*); void signalContextMenuRequested(); void signalXMLSaveItem(QXmlStreamWriter&, KIPIPlugins::KPImagesListViewItem*); void signalXMLLoadImageElement(QXmlStreamReader&); void signalXMLCustomElements(QXmlStreamWriter&); void signalXMLCustomElements(QXmlStreamReader&); public Q_SLOTS: virtual void slotAddImages(const QList& list); virtual void slotRemoveItems(); protected Q_SLOTS: void slotProgressTimerDone(); virtual void slotAddItems(); virtual void slotMoveUpItems(); virtual void slotMoveDownItems(); virtual void slotClearItems(); virtual void slotLoadItems(); virtual void slotSaveItems(); virtual void slotThumbnail(const QUrl& url, const QPixmap& pix); virtual void slotImageListChanged(); private: void setIconSize(int size); bool isRawFile(const QUrl& url) const; private: class Private; Private* const d; }; } // namespace KIPIPlugins Q_DECLARE_OPERATORS_FOR_FLAGS(KIPIPlugins::KPImagesList::ControlButtons) #endif // KPIMAGESLIST_H diff --git a/common/libkipiplugins/widgets/kpsettingswidget.cpp b/common/libkipiplugins/widgets/kpsettingswidget.cpp index 00fde0fd4..2f7eb4b34 100644 --- a/common/libkipiplugins/widgets/kpsettingswidget.cpp +++ b/common/libkipiplugins/widgets/kpsettingswidget.cpp @@ -1,440 +1,439 @@ /* ============================================================ * * This file is a part of kipi-plugins project * http://www.digikam.org * * Date : 2015-07-28 * Description : Common widgets shared by plugins * * Copyright (C) 2013 by Pankaj Kumar * Copyright (C) 2015 by Shourya Singh Gupta * * 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 "kpsettingswidget.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include // LibKIPI includes #include #include #include namespace KIPIPlugins { class KPSettingsWidget::Private { public: Private(QWidget* const widget, KIPI::Interface* const iface, const QString& pluginName) { m_pluginName = pluginName; mainLayout = new QHBoxLayout(widget); m_imgList = new KPImagesList(widget); settingsScrollArea = new QScrollArea(widget); m_settingsBox = new QWidget(settingsScrollArea); m_settingsBoxLayout = new QVBoxLayout(m_settingsBox); m_headerLbl = new QLabel(widget); m_accountBox = new QGroupBox(i18n("Account"),m_settingsBox); m_accountBoxLayout = new QGridLayout(m_accountBox); m_userNameDisplayLbl = new QLabel(m_accountBox); m_changeUserBtn = new QPushButton(m_accountBox); m_albBox = new QGroupBox(i18n("Album"),m_settingsBox); m_albumsBoxLayout = new QGridLayout(m_albBox); m_albumsCoB = new QComboBox(m_albBox); m_newAlbumBtn = new QPushButton(m_accountBox); m_reloadAlbumsBtn = new QPushButton(m_accountBox); m_sizeBox = new QGroupBox(i18n("Max Dimension"), m_settingsBox); m_sizeBoxLayout = new QVBoxLayout(m_sizeBox); m_dlDimensionCoB = new QComboBox(m_sizeBox); m_uploadBox = new QGroupBox(i18n("Destination"), m_settingsBox); m_uploadWidget = iface->uploadWidget(m_uploadBox); m_uploadBoxLayout = new QVBoxLayout(m_uploadBox); m_optionsBox = new QGroupBox(i18n("Options"),m_settingsBox); m_optionsBoxLayout = new QGridLayout(m_optionsBox); m_originalChB = new QCheckBox(m_optionsBox); m_resizeChB = new QCheckBox(m_optionsBox); m_dimensionSpB = new QSpinBox(m_optionsBox); m_imageQualitySpB = new QSpinBox(m_optionsBox); m_progressBar = new KPProgressWidget(m_settingsBox); } KPImagesList* m_imgList; KIPI::UploadWidget* m_uploadWidget; QString m_pluginName; QLabel* m_headerLbl; QLabel* m_userNameDisplayLbl; QPushButton* m_changeUserBtn; QComboBox* m_dlDimensionCoB; QScrollArea* settingsScrollArea; QComboBox* m_albumsCoB; QPushButton* m_newAlbumBtn; QPushButton* m_reloadAlbumsBtn; QCheckBox* m_originalChB; QCheckBox* m_resizeChB; QSpinBox* m_dimensionSpB; QSpinBox* m_imageQualitySpB; QHBoxLayout* mainLayout; QWidget* m_settingsBox; QVBoxLayout* m_settingsBoxLayout; QGroupBox* m_albBox; QGridLayout* m_albumsBoxLayout; QGroupBox* m_optionsBox; QGridLayout* m_optionsBoxLayout; QGroupBox* m_uploadBox; QVBoxLayout* m_uploadBoxLayout; QGroupBox* m_sizeBox; QVBoxLayout* m_sizeBoxLayout; QGroupBox* m_accountBox; QGridLayout* m_accountBoxLayout; KPProgressWidget* m_progressBar; }; KPSettingsWidget::KPSettingsWidget(QWidget* const parent, KIPI::Interface* const iface, const QString& pluginName) : QWidget(parent), d(new Private(this,iface,pluginName)) { d->m_pluginName = pluginName; setObjectName(d->m_pluginName + QString::fromLatin1(" Widget")); //---------------------------------------------------------- const int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); d->m_imgList->setControlButtonsPlacement(KPImagesList::ControlButtonsBelow); d->m_imgList->setAllowRAW(true); - d->m_imgList->loadImagesFromCurrentSelection(); d->m_imgList->listView()->setWhatsThis(i18n("This is the list of images to upload to your %1 account.",d->m_pluginName)); d->settingsScrollArea->setMinimumSize(400,500); d->settingsScrollArea->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); d->settingsScrollArea->setWidget(d->m_settingsBox); d->settingsScrollArea->setWidgetResizable(true); d->settingsScrollArea->setFrameShadow(QFrame::Plain); d->m_headerLbl->setWhatsThis(i18n("This is a clickable link to open %1 in a browser.",d->m_pluginName)); d->m_headerLbl->setOpenExternalLinks(true); d->m_headerLbl->setFocusPolicy(Qt::NoFocus); //------------------------------------------------------------ d->m_accountBox->setWhatsThis(i18n("This is the %1 account that is currently logged in.",d->m_pluginName)); QLabel* const userNameLbl = new QLabel(i18nc("account settings","Name:"),d->m_accountBox); d->m_changeUserBtn->setText(i18n("Change Account")); d->m_changeUserBtn->setIcon(QIcon::fromTheme(QString::fromLatin1("system-switch-user")).pixmap(16)); d->m_changeUserBtn->setToolTip(i18n("Change %1 account for transfer",d->m_pluginName)); d->m_accountBoxLayout->addWidget(userNameLbl, 0, 0, 1, 2); d->m_accountBoxLayout->addWidget(d->m_userNameDisplayLbl, 0, 2, 1, 2); d->m_accountBoxLayout->addWidget(d->m_changeUserBtn, 1, 0, 1, 4); d->m_accountBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing); d->m_accountBoxLayout->setSpacing(spacing); //------------------------------------------------------------- d->m_albBox->setWhatsThis(i18n("This is the %1 folder to/from which selected photos will be uploaded/downloaded.",d->m_pluginName)); QLabel* const albLbl = new QLabel(i18n("Album:"),d->m_albBox); d->m_albumsCoB->setEditable(false); d->m_newAlbumBtn->setText(i18n("New Album")); d->m_newAlbumBtn->setIcon(QIcon::fromTheme(QString::fromLatin1("list-add")).pixmap(16)); d->m_newAlbumBtn->setToolTip(i18n("Create new %1 folder",d->m_pluginName)); d->m_reloadAlbumsBtn->setText(i18nc("album list","Reload")); d->m_reloadAlbumsBtn->setIcon(QIcon::fromTheme(QString::fromLatin1("view-refresh")).pixmap(16)); d->m_reloadAlbumsBtn->setToolTip(i18n("Reload album list")); d->m_albumsBoxLayout->addWidget(albLbl, 0, 0, 1, 1); d->m_albumsBoxLayout->addWidget(d->m_albumsCoB, 0, 1, 1, 4); d->m_albumsBoxLayout->addWidget(d->m_newAlbumBtn, 1, 3, 1, 1); d->m_albumsBoxLayout->addWidget(d->m_reloadAlbumsBtn, 1, 4, 1, 1); //---------------------------------------------------------- d->m_sizeBox->setWhatsThis(i18n("This is the maximum dimension of the images. Images larger than this will be scaled down.")); d->m_dlDimensionCoB->addItem(i18n("Original Size"), QString::fromLatin1("d")); d->m_dlDimensionCoB->addItem(i18n("1600 px"), QString::fromLatin1("1600")); d->m_dlDimensionCoB->addItem(i18n("1440 px"), QString::fromLatin1("1440")); d->m_dlDimensionCoB->addItem(i18n("1280 px"), QString::fromLatin1("1280")); d->m_dlDimensionCoB->addItem(i18n("1152 px"), QString::fromLatin1("1152")); d->m_dlDimensionCoB->addItem(i18n("1024 px"), QString::fromLatin1("1024")); d->m_dlDimensionCoB->setCurrentIndex(0); d->m_sizeBoxLayout->addWidget(d->m_dlDimensionCoB); // ------------------------------------------------------------------------ d->m_uploadBox->setWhatsThis(i18n("This is the location where %1 images will be downloaded.",d->m_pluginName)); d->m_uploadBoxLayout->addWidget(d->m_uploadWidget); //----------------------------------------------------------- d->m_optionsBox->setWhatsThis(i18n("These are the options that would be applied to photos before upload.")); d->m_originalChB->setText(i18n("Upload original image file")); d->m_originalChB->setChecked(false); d->m_originalChB->hide(); d->m_resizeChB->setText(i18n("Resize photos before uploading")); d->m_resizeChB->setChecked(false); d->m_dimensionSpB->setMinimum(0); d->m_dimensionSpB->setMaximum(5000); d->m_dimensionSpB->setSingleStep(10); d->m_dimensionSpB->setValue(1600); d->m_dimensionSpB->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); d->m_dimensionSpB->setEnabled(false); QLabel* const dimensionLbl = new QLabel(i18n("Maximum Dimension:"),d->m_optionsBox); d->m_imageQualitySpB->setMinimum(0); d->m_imageQualitySpB->setMaximum(100); d->m_imageQualitySpB->setSingleStep(1); d->m_imageQualitySpB->setValue(90); d->m_imageQualitySpB->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); d->m_imageQualitySpB->setEnabled(false); QLabel* const imageQualityLbl = new QLabel(i18n("JPEG Quality:"),d->m_optionsBox); d->m_optionsBoxLayout->addWidget(d->m_originalChB, 0, 0, 1, 5); d->m_optionsBoxLayout->addWidget(d->m_resizeChB, 1, 0, 1, 5); d->m_optionsBoxLayout->addWidget(imageQualityLbl, 2, 1, 1, 1); d->m_optionsBoxLayout->addWidget(d->m_imageQualitySpB, 2, 2, 1, 1); d->m_optionsBoxLayout->addWidget(dimensionLbl, 3, 1, 1, 1); d->m_optionsBoxLayout->addWidget(d->m_dimensionSpB, 3, 2, 1, 1); d->m_optionsBoxLayout->setRowStretch(4, 10); d->m_optionsBoxLayout->setSpacing(spacing); d->m_optionsBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing); d->m_progressBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); d->m_progressBar->hide(); //------------------------------------------------------ d->m_settingsBoxLayout->addWidget(d->m_headerLbl); d->m_settingsBoxLayout->addWidget(d->m_accountBox); d->m_settingsBoxLayout->addWidget(d->m_albBox); d->m_settingsBoxLayout->addWidget(d->m_sizeBox); d->m_settingsBoxLayout->addWidget(d->m_uploadBox); d->m_settingsBoxLayout->addWidget(d->m_optionsBox); d->m_settingsBoxLayout->addWidget(d->m_progressBar); d->m_settingsBoxLayout->setSpacing(spacing); d->m_settingsBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing); //-------------------------------------------------------- d->mainLayout->addWidget(d->m_imgList); d->mainLayout->addWidget(d->settingsScrollArea); d->mainLayout->setContentsMargins(QMargins()); d->mainLayout->setSpacing(spacing); //------------------------------------------------------- connect(d->m_originalChB, SIGNAL(toggled(bool)), this, SLOT(slotResizeChecked())); connect(d->m_resizeChB, SIGNAL(toggled(bool)), this, SLOT(slotResizeChecked())); } KPSettingsWidget::~KPSettingsWidget() { delete d; } QString KPSettingsWidget::getDestinationPath() const { return d->m_uploadWidget->selectedImageCollection().uploadUrl().toLocalFile(); } KPImagesList* KPSettingsWidget::imagesList() const { return d->m_imgList; } void KPSettingsWidget::slotResizeChecked() { d->m_resizeChB->setEnabled(!d->m_originalChB->isChecked()); d->m_dimensionSpB->setEnabled(d->m_resizeChB->isChecked() && !d->m_originalChB->isChecked()); d->m_imageQualitySpB->setEnabled(d->m_resizeChB->isChecked() && !d->m_originalChB->isChecked()); } KPProgressWidget* KPSettingsWidget::progressBar() const { return d->m_progressBar; } void KPSettingsWidget::addWidgetToSettingsBox(QWidget* const widget) { d->m_settingsBoxLayout->addWidget(widget); d->m_settingsBoxLayout->removeWidget(d->m_progressBar); // NOTE: This is important because progress bar always has to be at the end of settings box layout. So we remove it and then add it back. d->m_settingsBoxLayout->addWidget(d->m_progressBar); } void KPSettingsWidget::replaceImageList(QWidget* const imgList) { d->m_imgList->hide(); d->mainLayout->removeWidget(d->m_imgList); d->mainLayout->insertWidget(0, imgList); } QWidget* KPSettingsWidget::getSettingsBox() const { return d->m_settingsBox; } QVBoxLayout* KPSettingsWidget::getSettingsBoxLayout() const { return d->m_settingsBoxLayout; } QGroupBox* KPSettingsWidget::getAlbumBox() const { return d->m_albBox; } QGridLayout* KPSettingsWidget::getAlbumBoxLayout() const { return d->m_albumsBoxLayout; } QGroupBox* KPSettingsWidget::getOptionsBox() const { return d->m_optionsBox; } QGridLayout* KPSettingsWidget::getOptionsBoxLayout() const { return d->m_optionsBoxLayout; } QGroupBox* KPSettingsWidget::getUploadBox() const { return d->m_uploadBox; } QVBoxLayout* KPSettingsWidget::getUploadBoxLayout() const { return d->m_uploadBoxLayout; } QGroupBox* KPSettingsWidget::getSizeBox() const { return d->m_sizeBox; } QVBoxLayout* KPSettingsWidget::getSizeBoxLayout() const { return d->m_sizeBoxLayout; } QGroupBox* KPSettingsWidget::getAccountBox() const { return d->m_accountBox; } QGridLayout* KPSettingsWidget::getAccountBoxLayout() const { return d->m_accountBoxLayout; } QLabel* KPSettingsWidget::getHeaderLbl() const { return d->m_headerLbl; } QLabel* KPSettingsWidget::getUserNameLabel() const { return d->m_userNameDisplayLbl; } QPushButton* KPSettingsWidget::getChangeUserBtn() const { return d->m_changeUserBtn; } QComboBox* KPSettingsWidget::getDimensionCoB() const { return d->m_dlDimensionCoB; } QPushButton* KPSettingsWidget::getNewAlbmBtn() const { return d->m_newAlbumBtn; } QPushButton* KPSettingsWidget::getReloadBtn() const { return d->m_reloadAlbumsBtn; } QCheckBox* KPSettingsWidget::getOriginalCheckBox() const { return d->m_originalChB; } QCheckBox* KPSettingsWidget::getResizeCheckBox() const { return d->m_resizeChB; } QSpinBox* KPSettingsWidget::getDimensionSpB() const { return d->m_dimensionSpB; } QSpinBox* KPSettingsWidget::getImgQualitySpB() const { return d->m_imageQualitySpB; } QComboBox* KPSettingsWidget::getAlbumsCoB() const { return d->m_albumsCoB; } } // namespace KIPIPlugins diff --git a/flickr/flickrwidget.cpp b/flickr/flickrwidget.cpp index 4c4df5e37..95c057829 100644 --- a/flickr/flickrwidget.cpp +++ b/flickr/flickrwidget.cpp @@ -1,531 +1,530 @@ /* ============================================================ * * This file is a part of kipi-plugins project * http://www.digikam.org * * Date : 2005-07-07 * Description : a kipi plugin to export images to Flickr web service * * Copyright (C) 2005-2008 by Vardhman Jain * Copyright (C) 2008-2017 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 "flickrwidget.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include // LibKIPI includes #include // Local includes #include "comboboxdelegate.h" #include "comboboxintermediate.h" #include "flickrlist.h" namespace KIPIFlickrPlugin { FlickrWidget::FlickrWidget(QWidget* const parent, KIPI::Interface* const iface, const QString& serviceName) : KPSettingsWidget(parent,iface,serviceName) { m_serviceName = serviceName; //Adding Remove Account button m_removeAccount = new QPushButton(getAccountBox()); m_removeAccount->setText(i18n("Remove Account")); getAccountBoxLayout()->addWidget(m_removeAccount, 2,0,1,4); // -- The image list -------------------------------------------------- m_imglst = new FlickrList(this, (serviceName == QString::fromLatin1("23"))); // For figuring out the width of the permission columns. QHeaderView* const hdr = m_imglst->listView()->header(); QFontMetrics hdrFont = QFontMetrics(hdr->font()); int permColWidth = hdrFont.width(i18nc("photo permissions", "Public")); m_imglst->setAllowRAW(true); - m_imglst->loadImagesFromCurrentSelection(); m_imglst->listView()->setWhatsThis(i18n("This is the list of images to upload to your Flickr account.")); m_imglst->listView()->setColumn(static_cast(FlickrList::PUBLIC), i18nc("photo permissions", "Public"), true); // Handle extra tags per image. m_imglst->listView()->setColumn(static_cast(FlickrList::TAGS), i18n("Extra tags"), true); if (serviceName != QString::fromLatin1("23")) { int tmpWidth; if ((tmpWidth = hdrFont.width(i18nc("photo permissions", "Family"))) > permColWidth) { permColWidth = tmpWidth; } if ((tmpWidth = hdrFont.width(i18nc("photo permissions", "Friends"))) > permColWidth) { permColWidth = tmpWidth; } m_imglst->listView()->setColumn(static_cast(FlickrList::FAMILY), i18nc("photo permissions", "Family"), true); m_imglst->listView()->setColumn(static_cast(FlickrList::FRIENDS), i18nc("photo permissions", "Friends"), true); hdr->setSectionResizeMode(FlickrList::FAMILY, QHeaderView::Interactive); hdr->setSectionResizeMode(FlickrList::FRIENDS, QHeaderView::Interactive); hdr->resizeSection(FlickrList::FAMILY, permColWidth); hdr->resizeSection(FlickrList::FRIENDS, permColWidth); m_imglst->listView()->setColumn(static_cast(FlickrList::SAFETYLEVEL), i18n("Safety level"), true); m_imglst->listView()->setColumn(static_cast(FlickrList::CONTENTTYPE), i18n("Content type"), true); QMap safetyLevelItems; QMap contentTypeItems; safetyLevelItems[FlickrList::SAFE] = i18nc("photo safety level", "Safe"); safetyLevelItems[FlickrList::MODERATE] = i18nc("photo safety level", "Moderate"); safetyLevelItems[FlickrList::RESTRICTED] = i18nc("photo safety level", "Restricted"); contentTypeItems[FlickrList::PHOTO] = i18nc("photo content type", "Photo"); contentTypeItems[FlickrList::SCREENSHOT] = i18nc("photo content type", "Screenshot"); contentTypeItems[FlickrList::OTHER] = i18nc("photo content type", "Other"); ComboBoxDelegate* const safetyLevelDelegate = new ComboBoxDelegate(m_imglst, safetyLevelItems); ComboBoxDelegate* const contentTypeDelegate = new ComboBoxDelegate(m_imglst, contentTypeItems); m_imglst->listView()->setItemDelegateForColumn(static_cast(FlickrList::SAFETYLEVEL), safetyLevelDelegate); m_imglst->listView()->setItemDelegateForColumn(static_cast(FlickrList::CONTENTTYPE), contentTypeDelegate); } hdr->setSectionResizeMode(FlickrList::PUBLIC, QHeaderView::Interactive); hdr->resizeSection(FlickrList::PUBLIC, permColWidth); // -- Show upload original image CheckBox---------------------------------- getOriginalCheckBox()->show(); // -- Layout for the tags ------------------------------------------------- QGroupBox* const tagsBox = new QGroupBox(i18n("Tag options"), getSettingsBox()); QGridLayout* const tagsBoxLayout = new QGridLayout(tagsBox); m_exportHostTagsCheckBox = new QCheckBox(tagsBox); m_exportHostTagsCheckBox->setText(i18n("Use Host Application Tags")); m_extendedTagsButton = new QPushButton(i18n("More tag options")); m_extendedTagsButton->setCheckable(true); // Initialize this button to checked, so extended options are shown. // FlickrWindow::readSettings can change this, but if checked is false it // cannot uncheck and subsequently hide the extended options (the toggled // signal won't be emitted). m_extendedTagsButton->setChecked(true); m_extendedTagsButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); m_extendedTagsBox = new QGroupBox(QString::fromLatin1(""), getSettingsBox()); m_extendedTagsBox->setFlat(true); QGridLayout* extendedTagsLayout = new QGridLayout(m_extendedTagsBox); QLabel* const tagsLabel = new QLabel(i18n("Added Tags: "), m_extendedTagsBox); m_tagsLineEdit = new QLineEdit(m_extendedTagsBox); m_tagsLineEdit->setToolTip(i18n("Enter new tags here, separated by commas.")); m_addExtraTagsCheckBox = new QCheckBox(m_extendedTagsBox); m_addExtraTagsCheckBox->setText(i18n("Add tags per image")); m_addExtraTagsCheckBox->setToolTip(i18n("If checked, you can set extra tags for " "each image in the File List tab")); m_addExtraTagsCheckBox->setChecked(true); m_stripSpaceTagsCheckBox = new QCheckBox(m_extendedTagsBox); m_stripSpaceTagsCheckBox->setText(i18n("Strip Spaces From Tags")); extendedTagsLayout->addWidget(tagsLabel, 0, 0); extendedTagsLayout->addWidget(m_tagsLineEdit, 0, 1); extendedTagsLayout->addWidget(m_stripSpaceTagsCheckBox, 1, 0, 1, 2); extendedTagsLayout->addWidget(m_addExtraTagsCheckBox, 2, 0, 1, 2); tagsBoxLayout->addWidget(m_exportHostTagsCheckBox, 0, 0); tagsBoxLayout->addWidget(m_extendedTagsButton, 0, 1); tagsBoxLayout->addWidget(m_extendedTagsBox, 1, 0, 1, 2); // -- Layout for the publication options ---------------------------------- QGroupBox* const publicationBox = new QGroupBox(i18n("Publication Options"), getSettingsBox()); QGridLayout* const publicationBoxLayout = new QGridLayout; publicationBox->setLayout(publicationBoxLayout); m_publicCheckBox = new QCheckBox(publicationBox); m_publicCheckBox->setText(i18nc("As in accessible for people", "Public (anyone can see them)")); m_familyCheckBox = new QCheckBox(publicationBox); m_familyCheckBox->setText(i18n("Visible to Family")); m_friendsCheckBox = new QCheckBox(publicationBox); m_friendsCheckBox->setText(i18n("Visible to Friends")); // Extended publication settings m_extendedPublicationButton = new QPushButton(i18n("More publication options")); m_extendedPublicationButton->setCheckable(true); // Initialize this button to checked, so extended options are shown. // FlickrWindow::readSettings can change this, but if checked is false it // cannot uncheck and subsequently hide the extended options (the toggled // signal won't be emitted). m_extendedPublicationButton->setChecked(true); m_extendedPublicationButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); m_extendedPublicationBox = new QGroupBox(QString::fromLatin1(""), publicationBox); m_extendedPublicationBox->setFlat(true); QGridLayout* const extendedSettingsLayout = new QGridLayout(m_extendedPublicationBox); QLabel* const imageSafetyLabel = new QLabel(i18n("Safety level:")); m_safetyLevelComboBox = new ComboBoxIntermediate(); m_safetyLevelComboBox->addItem(i18n("Safe"), QVariant(FlickrList::SAFE)); m_safetyLevelComboBox->addItem(i18n("Moderate"), QVariant(FlickrList::MODERATE)); m_safetyLevelComboBox->addItem(i18n("Restricted"), QVariant(FlickrList::RESTRICTED)); QLabel* const imageTypeLabel = new QLabel(i18n("Content type:")); m_contentTypeComboBox = new ComboBoxIntermediate(); m_contentTypeComboBox->addItem(i18nc("photo content type", "Photo"), QVariant(FlickrList::PHOTO)); m_contentTypeComboBox->addItem(i18nc("photo content type", "Screenshot"), QVariant(FlickrList::SCREENSHOT)); m_contentTypeComboBox->addItem(i18nc("photo content type", "Other"), QVariant(FlickrList::OTHER)); extendedSettingsLayout->addWidget(imageSafetyLabel, 1, 0, Qt::AlignLeft); extendedSettingsLayout->addWidget(m_safetyLevelComboBox, 1, 1, Qt::AlignLeft); extendedSettingsLayout->addWidget(imageTypeLabel, 0, 0, Qt::AlignLeft); extendedSettingsLayout->addWidget(m_contentTypeComboBox, 0, 1, Qt::AlignLeft); extendedSettingsLayout->setColumnStretch(0, 0); extendedSettingsLayout->setColumnStretch(1, 1); publicationBoxLayout->addWidget(m_publicCheckBox, 0, 0); publicationBoxLayout->addWidget(m_familyCheckBox, 1, 0); publicationBoxLayout->addWidget(m_friendsCheckBox, 2, 0); publicationBoxLayout->addWidget(m_extendedPublicationButton, 2, 1); publicationBoxLayout->addWidget(m_extendedPublicationBox, 3, 0, 1, 2); // -- Add these extra widgets to settings box ------------------------------------------------- addWidgetToSettingsBox(publicationBox); addWidgetToSettingsBox(tagsBox); //hiding widgets not required. getUploadBox()->hide(); getSizeBox()->hide(); //Removing KPImageLists inherited from KPSettingsWidget and replacing it with more specific FlickrList replaceImageList(m_imglst); updateLabels(); connect(m_imglst, SIGNAL(signalPermissionChanged(FlickrList::FieldType,Qt::CheckState)), this, SLOT(slotPermissionChanged(FlickrList::FieldType,Qt::CheckState))); connect(m_publicCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotMainPublicToggled(int))); connect(m_extendedTagsButton, SIGNAL(toggled(bool)), this, SLOT(slotExtendedTagsToggled(bool))); connect(m_addExtraTagsCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotAddExtraTagsToggled(bool))); // Zooomr doesn't support explicit Photosets. if (serviceName == QString::fromLatin1("Zooomr")) { getAlbumBox()->hide(); } // 23HQ doesn't support the Family and Friends concept. if (serviceName != QString::fromLatin1("23")) { connect(m_familyCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotMainFamilyToggled(int))); connect(m_friendsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotMainFriendsToggled(int))); } else { m_familyCheckBox->hide(); m_friendsCheckBox->hide(); } // 23HQ and Zooomr don't support the Safety Level and Content Type concept. if ((serviceName != QString::fromLatin1("23")) && (serviceName != QString::fromLatin1("Zooomr"))) { connect(m_safetyLevelComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotMainSafetyLevelChanged(int))); connect(m_contentTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotMainContentTypeChanged(int))); connect(m_extendedPublicationButton, SIGNAL(toggled(bool)), this, SLOT(slotExtendedPublicationToggled(bool))); connect(m_imglst, SIGNAL(signalSafetyLevelChanged(FlickrList::SafetyLevel)), this, SLOT(slotSafetyLevelChanged(FlickrList::SafetyLevel))); connect(m_imglst, SIGNAL(signalContentTypeChanged(FlickrList::ContentType)), this, SLOT(slotContentTypeChanged(FlickrList::ContentType))); } else { m_extendedPublicationBox->hide(); m_extendedPublicationButton->hide(); m_imglst->listView()->setColumnEnabled(static_cast(FlickrList::SAFETYLEVEL), false); m_imglst->listView()->setColumnEnabled(static_cast(FlickrList::CONTENTTYPE), false); } } FlickrWidget::~FlickrWidget() { } void FlickrWidget::updateLabels(const QString& /*name*/, const QString& /*url*/) { if (m_serviceName == QString::fromLatin1("23")) getHeaderLbl()->setText(i18n("

" "23" " Export" "

")); else if (m_serviceName == QString::fromLatin1("Zooomr")) getHeaderLbl()->setText(i18n("

" "zooomr" " Export" "

")); else getHeaderLbl()->setText(i18n("

" "flick" "r" " Export" "

")); } void FlickrWidget::slotPermissionChanged(FlickrList::FieldType checkbox, Qt::CheckState state) { /* Slot for handling the signal from the FlickrList that the general * permissions have changed, considering the clicks in the checkboxes next * to each image. In response, the main permission checkboxes should be set * to the proper state. * The checkbox variable determines which of the checkboxes should be * changed. */ // Select the proper checkbox. QCheckBox* currBox = 0; if (checkbox == FlickrList::PUBLIC) { currBox = m_publicCheckBox; } else if (checkbox == FlickrList::FAMILY) { currBox = m_familyCheckBox; } else { currBox = m_friendsCheckBox; } // If the checkbox should be set in the intermediate state, the tristate // property of the checkbox should be manually set to true, otherwise, it // has to be set to false so that the user cannot select it. currBox->setCheckState(state); if ((state == Qt::Checked) || (state == Qt::Unchecked)) { currBox->setTristate(false); } else { currBox->setTristate(true); } } void FlickrWidget::slotSafetyLevelChanged(FlickrList::SafetyLevel safetyLevel) { /* Called when the general safety level of the FlickrList has changed, * considering the individual comboboxes next to the photos. Used to set the * main safety level combobox appropriately. */ if (safetyLevel == FlickrList::MIXEDLEVELS) { m_safetyLevelComboBox->setIntermediate(true); } else { int index = m_safetyLevelComboBox->findData(QVariant(static_cast(safetyLevel))); m_safetyLevelComboBox->setCurrentIndex(index); } } void FlickrWidget::slotContentTypeChanged(FlickrList::ContentType contentType) { /* Called when the general content type of the FlickrList has changed, * considering the individual comboboxes next to the photos. Used to set the * main content type combobox appropriately. */ if (contentType == FlickrList::MIXEDTYPES) { m_contentTypeComboBox->setIntermediate(true); } else { int index = m_contentTypeComboBox->findData(QVariant(static_cast(contentType))); m_contentTypeComboBox->setCurrentIndex(index); } } void FlickrWidget::slotMainPublicToggled(int state) { mainPermissionToggled(FlickrList::PUBLIC, static_cast(state)); } void FlickrWidget::slotMainFamilyToggled(int state) { mainPermissionToggled(FlickrList::FAMILY, static_cast(state)); } void FlickrWidget::slotMainFriendsToggled(int state) { mainPermissionToggled(FlickrList::FRIENDS, static_cast(state)); } void FlickrWidget::mainPermissionToggled(FlickrList::FieldType checkbox, Qt::CheckState state) { /* Callback for when one of the main permission checkboxes is toggled. * checkbox specifies which of the checkboxes is toggled. */ if (state != Qt::PartiallyChecked) { // Set the states for the image list. if (checkbox == FlickrList::PUBLIC) { m_imglst->setPublic(state); } else if (checkbox == FlickrList::FAMILY) { m_imglst->setFamily(state); } else if (checkbox == FlickrList::FRIENDS) { m_imglst->setFriends(state); } // Dis- or enable the family and friends checkboxes if the public // checkbox is clicked. if (checkbox == 0) { if (state == Qt::Checked) { m_familyCheckBox->setEnabled(false); m_friendsCheckBox->setEnabled(false); } else if (state == Qt::Unchecked) { m_familyCheckBox->setEnabled(true); m_friendsCheckBox->setEnabled(true); } } // Set the main checkbox tristate state to false, so that the user // cannot select the intermediate state. if (checkbox == FlickrList::PUBLIC) { m_publicCheckBox->setTristate(false); } else if (checkbox == FlickrList::FAMILY) { m_familyCheckBox->setTristate(false); } else if (checkbox == FlickrList::FRIENDS) { m_friendsCheckBox->setTristate(false); } } } void FlickrWidget::slotMainSafetyLevelChanged(int index) { int currValue = (m_safetyLevelComboBox->itemData(index)).value(); // int currValue = qVariantValue(m_safetyLevelComboBox->itemData(index)); m_imglst->setSafetyLevels(static_cast(currValue)); } void FlickrWidget::slotMainContentTypeChanged(int index) { int currValue = (m_contentTypeComboBox->itemData(index)).value(); // int currValue = qVariantValue(m_contentTypeComboBox->itemData(index)); m_imglst->setContentTypes(static_cast(currValue)); } void FlickrWidget::slotExtendedPublicationToggled(bool status) { // Show or hide the extended settings when the extended settings button // is toggled. m_extendedPublicationBox->setVisible(status); m_imglst->listView()->setColumnHidden(FlickrList::SAFETYLEVEL, !status); m_imglst->listView()->setColumnHidden(FlickrList::CONTENTTYPE, !status); if (status) { m_extendedPublicationButton->setText(i18n("Fewer publication options")); } else { m_extendedPublicationButton->setText(i18n("More publication options")); } } void FlickrWidget::slotExtendedTagsToggled(bool status) { // Show or hide the extended tag settings when the extended tag option // button is toggled. m_extendedTagsBox->setVisible(status); if (!status) { m_imglst->listView()->setColumnHidden(FlickrList::TAGS, true); m_extendedTagsButton->setText(i18n("More tag options")); } else { m_imglst->listView()->setColumnHidden(FlickrList::TAGS, !m_addExtraTagsCheckBox->isChecked()); m_extendedTagsButton->setText(i18n("Fewer tag options")); } } void FlickrWidget::slotAddExtraTagsToggled(bool status) { if (m_extendedTagsButton->isChecked()) { m_imglst->listView()->setColumnHidden(FlickrList::TAGS, !status); } } // void FlickrWidget::showEvent(QShowEvent*) // { // slotOriginalChecked(); // } } // namespace KIPIFlickrPlugin diff --git a/remotestorage/KioExportWidget.cpp b/remotestorage/KioExportWidget.cpp index e1359a8b7..64ffcd015 100644 --- a/remotestorage/KioExportWidget.cpp +++ b/remotestorage/KioExportWidget.cpp @@ -1,179 +1,178 @@ /* ============================================================ * * This file is a part of kipi-plugins project * http://www.digikam.org * * Date : 2009-09-28 * Description : a tool to export image to a KIO accessible * location * * Copyright (C) 2006-2009 by Johannes Wienke * * 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 "KioExportWidget.h" // Qt includes #include #include #include // KDE includes #include #include // Local includes #include "kipiplugins_debug.h" #include "kpimageslist.h" #include "kputil.h" namespace KIPIRemoteStoragePlugin { KioExportWidget::KioExportWidget(QWidget* const parent) : QWidget(parent) { // setup remote target selection KPHBox* const hbox = new KPHBox(this); QLabel* const label = new QLabel(hbox); m_targetLabel = new KUrlComboRequester(hbox); m_targetDialog = 0; if (m_targetLabel->button()) m_targetLabel->button()->hide(); m_targetLabel->comboBox()->setEditable(true); label->setText(i18n("Target location: ")); m_targetLabel->setWhatsThis(i18n("Sets the target address to upload the images to. " "This can be any address as used in Dolphin or Konqueror, " "e.g. ftp://my.server.org/sub/folder.")); m_targetSearchButton = new QPushButton(i18n("Select target location..."), this); m_targetSearchButton->setIcon(QIcon::fromTheme(QString::fromLatin1("folder-remote"))); // setup image list m_imageList = new KPImagesList(this); m_imageList->setAllowRAW(true); m_imageList->listView()->setWhatsThis(i18n("This is the list of images to upload " "to the specified target.")); - m_imageList->loadImagesFromCurrentSelection(); // layout dialog QVBoxLayout* const layout = new QVBoxLayout(this); layout->addWidget(hbox); layout->addWidget(m_targetSearchButton); layout->addWidget(m_imageList); layout->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing)); layout->setContentsMargins(QMargins()); // ------------------------------------------------------------------------ connect(m_targetSearchButton, SIGNAL(clicked(bool)), this, SLOT(slotShowTargetDialogClicked(bool))); connect(m_targetLabel, SIGNAL(textChanged(QString)), this, SLOT(slotLabelUrlChanged())); // ------------------------------------------------------------------------ updateTargetLabel(); } KioExportWidget::~KioExportWidget() { } QUrl KioExportWidget::targetUrl() const { return m_targetUrl; } QList KioExportWidget::history() const { QList urls; for (int i = 0 ; i <= m_targetLabel->comboBox()->count() ; i++) urls << QUrl(m_targetLabel->comboBox()->itemText(i)); return urls; } void KioExportWidget::setHistory(const QList& urls) { m_targetLabel->comboBox()->clear(); foreach (QUrl url, urls) m_targetLabel->comboBox()->addUrl(url); } void KioExportWidget::setTargetUrl(const QUrl& url) { m_targetUrl = url; updateTargetLabel(); } void KioExportWidget::slotShowTargetDialogClicked(bool checked) { Q_UNUSED(checked); bool isPlasma = QString::fromLatin1(qgetenv("XDG_CURRENT_DESKTOP")).toUpper().contains(QLatin1String("KDE")); m_targetDialog = new QFileDialog(this, i18n("Select target..."), m_targetUrl.toString(), i18n("All Files (*)")); m_targetDialog->setAcceptMode(QFileDialog::AcceptSave); m_targetDialog->setFileMode(QFileDialog::DirectoryOnly); m_targetDialog->setOption(QFileDialog::DontUseNativeDialog, !isPlasma); if (m_targetDialog->exec() == QDialog::Accepted) { m_targetUrl = m_targetDialog->selectedUrls().isEmpty() ? QUrl() : m_targetDialog->selectedUrls().at(0); updateTargetLabel(); emit signalTargetUrlChanged(m_targetUrl); } delete m_targetDialog; } void KioExportWidget::updateTargetLabel() { qCDebug(KIPIPLUGINS_LOG) << "Call for url " << m_targetUrl.toDisplayString() << ", valid = " << m_targetUrl.isValid(); QString urlString = i18n(""); if (m_targetUrl.isValid()) { urlString = m_targetUrl.toDisplayString(); m_targetLabel->setUrl(QUrl(urlString)); } } KPImagesList* KioExportWidget::imagesList() const { return m_imageList; } void KioExportWidget::slotLabelUrlChanged() { m_targetUrl = m_targetLabel->url(); emit signalTargetUrlChanged(m_targetUrl); } } // namespace KIPIRemoteStoragePlugin diff --git a/smug/smugwidget.cpp b/smug/smugwidget.cpp index f8e68ccfc..5c6598fa6 100644 --- a/smug/smugwidget.cpp +++ b/smug/smugwidget.cpp @@ -1,346 +1,345 @@ /* ============================================================ * * This file is a part of kipi-plugins project * http://www.digikam.org * * Date : 2008-12-01 * Description : a kipi plugin to import/export images to/from SmugMug web service * * Copyright (C) 2008-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 "smugwidget.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include // Libkipi includes #include #include #include // Local includes #include "kpimageslist.h" #include "kpprogresswidget.h" namespace KIPISmugPlugin { SmugWidget::SmugWidget(QWidget* const parent, KIPI::Interface* const iface, bool import) : QWidget(parent) { setObjectName(QString::fromLatin1("SmugWidget")); const int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); QHBoxLayout* const mainLayout = new QHBoxLayout(this); // ------------------------------------------------------------------- m_imgList = new KIPIPlugins::KPImagesList(this); m_imgList->setControlButtonsPlacement(KIPIPlugins::KPImagesList::ControlButtonsBelow); m_imgList->setAllowRAW(true); - m_imgList->loadImagesFromCurrentSelection(); m_imgList->listView()->setWhatsThis(i18n("This is the list of images to upload to your SmugMug account.")); QWidget* const settingsBox = new QWidget(this); QVBoxLayout* const settingsBoxLayout = new QVBoxLayout(settingsBox); m_headerLbl = new QLabel(settingsBox); m_headerLbl->setWhatsThis(i18n("This is a clickable link to open the SmugMug home page in a web browser.")); m_headerLbl->setOpenExternalLinks(true); m_headerLbl->setFocusPolicy(Qt::NoFocus); // ------------------------------------------------------------------------ QGroupBox* const accountBox = new QGroupBox(i18n("Account"), settingsBox); accountBox->setWhatsThis(i18n("This is the SmugMug account that will be used to authenticate.")); QGridLayout* const accountBoxLayout = new QGridLayout(accountBox); m_anonymousRBtn = new QRadioButton(i18nc("smug account login", "Anonymous"), accountBox); m_anonymousRBtn->setWhatsThis(i18n("Login as anonymous to SmugMug web service.")); m_accountRBtn = new QRadioButton(i18n("SmugMug Account"), accountBox); m_accountRBtn->setWhatsThis(i18n("Login to SmugMug web service using email and password.")); m_userNameLbl = new QLabel(i18nc("smug account settings", "Name:"), accountBox); m_userName = new QLabel(accountBox); m_emailLbl = new QLabel(i18nc("smug account settings", "Email:"), accountBox); m_email = new QLabel(accountBox); m_changeUserBtn = new QPushButton(accountBox); m_changeUserBtn->setText(i18n("Change Account")); m_changeUserBtn->setIcon(QIcon::fromTheme(QString::fromLatin1("system-switch-user"))); m_changeUserBtn->setToolTip(i18n("Change SmugMug Account used to authenticate")); accountBoxLayout->addWidget(m_anonymousRBtn, 0, 0, 1, 2); accountBoxLayout->addWidget(m_accountRBtn, 1, 0, 1, 2); accountBoxLayout->addWidget(m_userNameLbl, 2, 0, 1, 1); accountBoxLayout->addWidget(m_userName, 2, 1, 1, 1); accountBoxLayout->addWidget(m_emailLbl, 3, 0, 1, 1); accountBoxLayout->addWidget(m_email, 3, 1, 1, 1); accountBoxLayout->addWidget(m_changeUserBtn, 4, 1, 1, 1); accountBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing); accountBoxLayout->setSpacing(spacing); // ------------------------------------------------------------------------ QGroupBox* const albumsBox = new QGroupBox(i18n("Album"), settingsBox); albumsBox->setWhatsThis(i18n("This is the SmugMug album that will be used for transfer.")); QGridLayout* const albumsBoxLayout = new QGridLayout(albumsBox); m_albumsCoB = new QComboBox(albumsBox); m_albumsCoB->setEditable(false); m_nickNameLbl = new QLabel(i18n("Nickname:"), albumsBox); m_nickNameEdt = new QLineEdit(albumsBox); m_nickNameEdt->setWhatsThis(i18n("Nickname of SmugMug user to list albums.")); m_sitePasswordLbl = new QLabel(i18n("Site Password:"), albumsBox); m_sitePasswordEdt = new QLineEdit(albumsBox); m_sitePasswordEdt->setWhatsThis(i18n("Site-wide password for specified SmugMug nick/user.")); m_albumPasswordLbl = new QLabel(i18n("Album Password:"), albumsBox); m_albumPasswordEdt = new QLineEdit(albumsBox); m_albumPasswordEdt->setWhatsThis(i18n("Password for SmugMug album.")); m_newAlbumBtn = new QPushButton(accountBox); m_newAlbumBtn->setText(i18n("New Album")); m_newAlbumBtn->setIcon(QIcon::fromTheme(QString::fromLatin1("list-add"))); m_newAlbumBtn->setToolTip(i18n("Create new SmugMug album")); m_reloadAlbumsBtn = new QPushButton(accountBox); m_reloadAlbumsBtn->setText(i18nc("reload album list", "Reload")); m_reloadAlbumsBtn->setIcon(QIcon::fromTheme(QString::fromLatin1("view-refresh"))); m_reloadAlbumsBtn->setToolTip(i18n("Reload album list")); albumsBoxLayout->addWidget(m_albumsCoB, 0, 0, 1, 5); albumsBoxLayout->addWidget(m_nickNameLbl, 1, 0, 1, 1); albumsBoxLayout->addWidget(m_nickNameEdt, 1, 1, 1, 3); albumsBoxLayout->addWidget(m_newAlbumBtn, 1, 3, 1, 1); albumsBoxLayout->addWidget(m_reloadAlbumsBtn, 1, 4, 1, 1); albumsBoxLayout->addWidget(m_sitePasswordLbl, 2, 0, 1, 1); albumsBoxLayout->addWidget(m_sitePasswordEdt, 2, 1, 1, 4); albumsBoxLayout->addWidget(m_albumPasswordLbl, 3, 0, 1, 1); albumsBoxLayout->addWidget(m_albumPasswordEdt, 3, 1, 1, 4); // ------------------------------------------------------------------------ QGroupBox* const uploadBox = new QGroupBox(i18n("Destination"), settingsBox); uploadBox->setWhatsThis(i18n("This is the location where SmugMug images will be downloaded.")); QVBoxLayout* const uploadBoxLayout = new QVBoxLayout(uploadBox); m_uploadWidget = iface->uploadWidget(uploadBox); uploadBoxLayout->addWidget(m_uploadWidget); // ------------------------------------------------------------------------ QGroupBox* const optionsBox = new QGroupBox(i18n("Options"), settingsBox); optionsBox->setWhatsThis(i18n("These are options that will be applied to images before upload.")); QGridLayout* const optionsBoxLayout = new QGridLayout(optionsBox); m_resizeChB = new QCheckBox(optionsBox); m_resizeChB->setText(i18n("Resize photos before uploading")); m_resizeChB->setChecked(false); m_dimensionSpB = new QSpinBox(optionsBox); m_dimensionSpB->setMinimum(0); m_dimensionSpB->setMaximum(5000); m_dimensionSpB->setSingleStep(10); m_dimensionSpB->setValue(600); m_dimensionSpB->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); m_dimensionSpB->setEnabled(false); QLabel* const dimensionLbl = new QLabel(i18n("Maximum dimension:"), optionsBox); m_imageQualitySpB = new QSpinBox(optionsBox); m_imageQualitySpB->setMinimum(0); m_imageQualitySpB->setMaximum(100); m_imageQualitySpB->setSingleStep(1); m_imageQualitySpB->setValue(85); m_imageQualitySpB->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); QLabel* const imageQualityLbl = new QLabel(i18n("JPEG quality:"), optionsBox); optionsBoxLayout->addWidget(m_resizeChB, 0, 0, 1, 5); optionsBoxLayout->addWidget(imageQualityLbl, 1, 1, 1, 1); optionsBoxLayout->addWidget(m_imageQualitySpB, 1, 2, 1, 1); optionsBoxLayout->addWidget(dimensionLbl, 2, 1, 1, 1); optionsBoxLayout->addWidget(m_dimensionSpB, 2, 2, 1, 1); optionsBoxLayout->setRowStretch(3, 10); optionsBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing); optionsBoxLayout->setSpacing(spacing); m_progressBar = new KIPIPlugins::KPProgressWidget(settingsBox); m_progressBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); m_progressBar->hide(); // ------------------------------------------------------------------------ settingsBoxLayout->addWidget(m_headerLbl); settingsBoxLayout->addWidget(accountBox); settingsBoxLayout->addWidget(albumsBox); settingsBoxLayout->addWidget(uploadBox); settingsBoxLayout->addWidget(optionsBox); settingsBoxLayout->addWidget(m_progressBar); settingsBoxLayout->setSpacing(spacing); settingsBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing); // ------------------------------------------------------------------------ mainLayout->addWidget(m_imgList); mainLayout->addWidget(settingsBox); mainLayout->setSpacing(spacing); mainLayout->setContentsMargins(QMargins()); updateLabels(); // use empty labels until login // ------------------------------------------------------------------------ connect(m_changeUserBtn, SIGNAL(clicked()), this, SLOT(slotChangeUserClicked())); connect(m_resizeChB, SIGNAL(clicked()), this, SLOT(slotResizeChecked())); connect(m_anonymousRBtn, SIGNAL(toggled(bool)), this, SLOT(slotAnonymousToggled(bool))); // ------------------------------------------------------------------------ if (import) { m_imgList->hide(); m_newAlbumBtn->hide(); optionsBox->hide(); } else { m_anonymousRBtn->hide(); m_accountRBtn->hide(); m_nickNameLbl->hide(); m_nickNameEdt->hide(); m_sitePasswordLbl->hide(); m_sitePasswordEdt->hide(); m_albumPasswordLbl->hide(); m_albumPasswordEdt->hide(); uploadBox->hide(); } } SmugWidget::~SmugWidget() { } KIPIPlugins::KPImagesList* SmugWidget::imagesList() const { return m_imgList; } KIPIPlugins::KPProgressWidget* SmugWidget::progressBar() const { return m_progressBar; } bool SmugWidget::isAnonymous() const { return m_anonymousRBtn->isChecked(); } void SmugWidget::setAnonymous(bool checked) { m_anonymousRBtn->setChecked(checked); m_accountRBtn->setChecked(!checked); } QString SmugWidget::getNickName() const { return m_nickNameEdt->text(); } QString SmugWidget::getSitePassword() const { return m_sitePasswordEdt->text(); } QString SmugWidget::getAlbumPassword() const { return m_albumPasswordEdt->text(); } QString SmugWidget::getDestinationPath() const { return m_uploadWidget->selectedImageCollection().uploadUrl().toLocalFile(); } void SmugWidget::setNickName(const QString& nick) { m_nickNameEdt->setText(nick); m_headerLbl->setText(QString::fromLatin1("

" "SmugMug" "

").arg(nick)); } void SmugWidget::updateLabels(const QString& email, const QString& name, const QString& nick) { m_email->setText(email); m_userName->setText(QString::fromLatin1("%1").arg(name)); QString web(QString::fromLatin1("www")); if (!nick.isEmpty()) web = nick; m_headerLbl->setText(QString::fromLatin1("

" "SmugMug" "

").arg(web)); } void SmugWidget::slotAnonymousToggled(bool checked) { m_emailLbl->setEnabled(!checked); m_email->setEnabled(!checked); m_userNameLbl->setEnabled(!checked); m_userName->setEnabled(!checked); m_changeUserBtn->setEnabled(!checked); emit signalUserChangeRequest(checked); } void SmugWidget::slotChangeUserClicked() { emit signalUserChangeRequest(false); } void SmugWidget::slotResizeChecked() { m_dimensionSpB->setEnabled(m_resizeChB->isChecked()); m_imageQualitySpB->setEnabled(m_resizeChB->isChecked()); } } // namespace KIPISmugPlugin