From 5d0e2bb71e1b4e78392cb48abfc2a3c3f3a84adb Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 25 Feb 2020 00:11:51 +1100 Subject: [PATCH] Add Album Editing (add / remove photos) Significant improvements to AlbumDialog - load Existing Photos to the Album - drag and drop add new Photos - mark photos for deletion - publish these changes - color photoitems depending on state Fixed up Top-Level Photo display. - only show latest version of photo (hide deleted) - fixup grouping by "Own / Subscribed / Other" Albums - added Album detail editing using GxsGroupDialog --- libretroshare/src/retroshare/rsgxscommon.h | 1 + libretroshare/src/services/p3gxscommon.cc | 5 + .../src/gui/PhotoShare/AlbumDialog.cpp | 194 ++++++- .../src/gui/PhotoShare/AlbumDialog.h | 18 +- .../src/gui/PhotoShare/AlbumDialog.ui | 510 ++++++------------ .../src/gui/PhotoShare/PhotoItem.cpp | 39 +- retroshare-gui/src/gui/PhotoShare/PhotoItem.h | 5 + .../src/gui/PhotoShare/PhotoShare.cpp | 211 ++++---- .../src/gui/PhotoShare/PhotoShare.h | 5 +- .../src/gui/PhotoShare/PhotoShare.ui | 52 +- 10 files changed, 556 insertions(+), 484 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxscommon.h b/libretroshare/src/retroshare/rsgxscommon.h index ad9d89ee2..126c2b51f 100644 --- a/libretroshare/src/retroshare/rsgxscommon.h +++ b/libretroshare/src/retroshare/rsgxscommon.h @@ -64,6 +64,7 @@ struct RsGxsImage : RsSerializable void copy(uint8_t *data, uint32_t size); // Allocates and Copies. void clear(); // Frees. void shallowClear(); // Clears Pointer. + bool empty() const; uint32_t mSize; uint8_t* mData; diff --git a/libretroshare/src/services/p3gxscommon.cc b/libretroshare/src/services/p3gxscommon.cc index 28d94e28c..a0682acd9 100644 --- a/libretroshare/src/services/p3gxscommon.cc +++ b/libretroshare/src/services/p3gxscommon.cc @@ -79,6 +79,11 @@ RsGxsImage &RsGxsImage::operator=(const RsGxsImage &a) } +bool RsGxsImage::empty() const +{ + return ((mData == NULL) || (mSize == 0)); +} + void RsGxsImage::take(uint8_t *data, uint32_t size) { #ifdef DEBUG_GXSCOMMON diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index c7f0991df..2115e5899 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -27,7 +27,7 @@ AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhoto* rs_Photo, QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), - ui(new Ui::AlbumDialog), mRsPhoto(rs_Photo), mPhotoQueue(photoQueue), mAlbum(album), mPhotoSelected(NULL) + ui(new Ui::AlbumDialog), mRsPhoto(rs_Photo), mPhotoShareQueue(photoQueue), mAlbum(album), mPhotoSelected(NULL) { ui->setupUi(this); @@ -39,13 +39,18 @@ AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPh mPhotoDrop = ui->scrollAreaWidgetContents; - if(!(mAlbum.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) + if (!(mAlbum.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) { ui->scrollAreaPhotos->setEnabled(false); ui->pushButton_DeletePhoto->setEnabled(false); } mPhotoDrop->setPhotoItemHolder(this); + // setup PhotoQueue for internal loading. + mPhotoQueue = new TokenQueue(rsPhoto->getTokenService(), this); + requestPhotoList(mAlbum.mMeta.mGroupId); + + // setup gui. setUp(); } @@ -55,13 +60,8 @@ void AlbumDialog::setUp() ui->lineEdit_Title->setText(QString::fromStdString(mAlbum.mMeta.mGroupName)); ui->lineEdit_Caption->setText(QString::fromStdString(mAlbum.mCaption)); ui->lineEdit_Category->setText(QString::fromStdString(mAlbum.mCategory)); - ui->lineEdit_Identity->setText(QString::fromStdString(mAlbum.mMeta.mAuthorId.toStdString())); - ui->lineEdit_Where->setText(QString::fromStdString(mAlbum.mWhere)); - ui->textEdit_description->setText(QString::fromStdString(mAlbum.mDescription)); - - - if(mAlbum.mThumbnail.mSize != 0) + if (mAlbum.mThumbnail.mSize != 0) { QPixmap qtn; GxsIdDetails::loadPixmapFromData(mAlbum.mThumbnail.mData, mAlbum.mThumbnail.mSize,qtn, GxsIdDetails::ORIGINAL); @@ -74,7 +74,13 @@ void AlbumDialog::setUp() } } -void AlbumDialog::updateAlbumPhotos(){ +void AlbumDialog::addPhoto(const RsPhotoPhoto &photo) +{ + mPhotoDrop->addPhotoItem(new PhotoItem(this, photo)); +} + +void AlbumDialog::updateAlbumPhotos() +{ QSet photos; @@ -82,26 +88,59 @@ void AlbumDialog::updateAlbumPhotos(){ QSetIterator sit(photos); - while(sit.hasNext()) + while (sit.hasNext()) { PhotoItem* item = sit.next(); uint32_t token; RsPhotoPhoto photo = item->getPhotoDetails(); + + // ensure GroupId, AuthorId match Album. photo.mMeta.mGroupId = mAlbum.mMeta.mGroupId; - mRsPhoto->submitPhoto(token, photo); - mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + photo.mMeta.mAuthorId = mAlbum.mMeta.mAuthorId; + + bool publish = true; + switch(item->getState()) + { + case PhotoItem::New: + { + // new photo will be published. + } + break; + case PhotoItem::Existing: + { + publish = false; + } + break; + case PhotoItem::Modified: + { + // update will be published. + } + break; + case PhotoItem::Deleted: + { + // flag image as Deleted. + // clear image. + // clear file URL (todo) + photo.mThumbnail.clear(); + } + break; + } + + if (publish) { + mRsPhoto->submitPhoto(token, photo); + mPhotoShareQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } } close(); } void AlbumDialog::deletePhoto(){ - if(mPhotoSelected) + if (mPhotoSelected) { mPhotoSelected->setSelected(false); - mPhotoDrop->deletePhoto(mPhotoSelected); + mPhotoSelected->markForDeletion(); } - } void AlbumDialog::editPhoto() @@ -116,12 +155,11 @@ AlbumDialog::~AlbumDialog() void AlbumDialog::notifySelection(PhotoShareItem *selection) { - PhotoItem* pItem = dynamic_cast(selection); - if(mPhotoSelected == NULL) + if (mPhotoSelected == NULL) { - return; + mPhotoSelected = pItem; } else { @@ -131,3 +169,123 @@ void AlbumDialog::notifySelection(PhotoShareItem *selection) mPhotoSelected->setSelected(true); } + + +/**************************** Request / Response Filling of Data ************************/ + +void AlbumDialog::requestPhotoList(GxsMsgReq& req) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); + return; +} + +void AlbumDialog::requestPhotoList(const RsGxsGroupId &albumId) +{ + std::list grpIds; + grpIds.push_back(albumId); + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, grpIds, 0); +} + +void AlbumDialog::acknowledgeMessage(const uint32_t &token) +{ + std::pair p; + rsPhoto->acknowledgeMsg(token, p); +} + +void AlbumDialog::loadPhotoList(const uint32_t &token) +{ + GxsMsgIdResult res; + + rsPhoto->getMsgList(token, res); + requestPhotoData(res); +} + +void AlbumDialog::requestPhotoData(GxsMsgReq &photoIds) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); +} + +void AlbumDialog::loadPhotoData(const uint32_t &token) +{ + PhotoResult res; + rsPhoto->getPhoto(token, res); + PhotoResult::iterator mit = res.begin(); + + + for (; mit != res.end(); ++mit) + { + std::vector& photoV = mit->second; + std::vector::iterator vit = photoV.begin(); + + for (; vit != photoV.end(); ++vit) + { + RsPhotoPhoto& photo = *vit; + + if (!photo.mThumbnail.empty()) { + addPhoto(photo); + } + } + } +} + + +/**************************** Request / Response Filling of Data ************************/ + +void AlbumDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + if (queue == mPhotoQueue) + { + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_MSGINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_LIST: + loadPhotoList(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeMessage(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + case TOKENREQ_MSGRELATEDINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} + +/**************************** Request / Response Filling of Data ************************/ + + diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h index 9949b7408..43bf36852 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h @@ -32,7 +32,7 @@ namespace Ui { class AlbumDialog; } -class AlbumDialog : public QDialog, public PhotoShareItemHolder +class AlbumDialog : public QDialog, public PhotoShareItemHolder, public TokenResponse { Q_OBJECT @@ -52,8 +52,24 @@ private slots: void deletePhoto(); void editPhoto(); private: + + void addPhoto(const RsPhotoPhoto &photo); + + // data request / response. + void requestPhotoList(GxsMsgReq& req); + void requestPhotoList(const RsGxsGroupId &albumId); + void requestPhotoData(GxsMsgReq &photoIds); + + void acknowledgeMessage(const uint32_t &token); + + void loadPhotoList(const uint32_t &token); + void loadPhotoData(const uint32_t &token); + + void loadRequest(const TokenQueue *queue, const TokenRequest &req); + Ui::AlbumDialog *ui; RsPhoto* mRsPhoto; + TokenQueue* mPhotoShareQueue; // external PhotoShare Queue. TokenQueue* mPhotoQueue; RsPhotoAlbum mAlbum; PhotoDrop* mPhotoDrop; diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index be8dbce14..b73f55d3d 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -6,8 +6,8 @@ 0 0 - 725 - 427 + 795 + 597 @@ -16,354 +16,208 @@ true - - - 0 - - - 0 - - - + + + QFrame::StyledPanel QFrame::Raised - - - - - Qt::Vertical + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 10 + 0 + - - - - - - - 0 - 1 - - - - Album Thumbnail - - - - - - TextLabel - - - - - - - - - - - 10 - 1 - - - - Summary - - - - - - Album Title: - - - - - - - false - - - - 0 - 0 - - - - - - - - Category: - - - - - - - false - - - - 0 - 0 - - - - - - - - Caption - - - - - - - false - - - - 0 - 0 - - - - - - - - Where: - - - - - - - false - - - - 0 - 0 - - - - - - - - When - - - - - - - false - - - - 0 - 0 - - - - - - - - Description: - - - - - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - + + + 6 + + + 2 + + + + + false + + + + 0 + 0 + + + + + + + + Category: + + + + + + + false + + + + 0 + 0 + + + + + + + + + 0 + 1 + + + - - - - 10 - 1 - + + + + 64 + 64 + - - Share Options + + TextLabel - - - - - false - - - - 0 - 0 - - - - - - - - Comments - - - - - - - Publish Identity - - - - - - - false - - - - 0 - 0 - - - - - - - - Visibility - - - - - - - false - - - - 0 - 0 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + + + + Qt::Vertical + + + + 20 + 40 + + + + - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + + + + + + false + + + + 0 + 0 + + + + + + + + Caption + + + + + + + Album Title: + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;"> Drag &amp; Drop to insert pictures. Click on a picture to edit details below.</span></p></body></html> + + + + + + + + 0 + 10 + + + + true + + + Qt::ScrollBarAsNeeded + + + true + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 737 + 315 + - - - - - + 0 10 - - true + + QWidget#scrollAreaWidgetContents{border: none;} - - Qt::ScrollBarAsNeeded - - - true - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - 0 - 0 - 701 - 69 - - - - QWidget#scrollAreaWidgetContents{border: none;} - - - + - - - + + + - + @@ -418,16 +272,6 @@ p, li { white-space: pre-wrap; } - - - - QFrame::StyledPanel - - - QFrame::Raised - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp index 56378467f..f98346e00 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp @@ -30,6 +30,7 @@ PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const RsPhotoPhoto &photo, QW QWidget(parent), ui(new Ui::PhotoItem), mHolder(holder), mPhotoDetails(photo) { + mState = State::Existing; ui->setupUi(this); setSelected(false); @@ -52,12 +53,20 @@ PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget QWidget(parent), ui(new Ui::PhotoItem), mHolder(holder) { + mState = State::New; + ui->setupUi(this); QPixmap qtn = QPixmap(path); - mThumbNail = qtn; - ui->label_Thumbnail->setPixmap(mThumbNail.scaled(120, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + // TODO need to scale qtn to something reasonable. + // shouldn't be call thumbnail... we can do a lowRes version. + // do we need to to workout what type of file to convert to? + // jpg, png etc. + // seperate fn should handle all of this. + mThumbNail = qtn.scaled(480,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); + + ui->label_Thumbnail->setPixmap(qtn.scaled(120, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation)); setSelected(false); getThumbnail(mPhotoDetails.mThumbnail); @@ -69,16 +78,38 @@ PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget } +void PhotoItem::markForDeletion() +{ + mState = State::Deleted; + setSelected(true); // to repaint with deleted scheme. +} + void PhotoItem::setSelected(bool selected) { mSelected = selected; + + QString bottomColor; + switch(mState) + { + case State::New: + bottomColor = "#FFFFFF"; + break; + case State::Existing: + bottomColor = "#888888"; + break; + default: + case State::Deleted: + bottomColor = "#EE5555"; + break; + } + if (mSelected) { - ui->photoFrame->setStyleSheet("QFrame#photoFrame{border: 2px solid #9562B8;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #55EE55, stop: 1 #CCCCCC);\nborder-radius: 10px}"); + ui->photoFrame->setStyleSheet("QFrame#photoFrame{border: 2px solid #9562B8;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #55EE55, stop: 1 " + bottomColor + ");\nborder-radius: 10px}"); } else { - ui->photoFrame->setStyleSheet("QFrame#photoFrame{border: 2px solid #CCCCCC;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC);\nborder-radius: 10px}"); + ui->photoFrame->setStyleSheet("QFrame#photoFrame{border: 2px solid #CCCCCC;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 " + bottomColor + ");\nborder-radius: 10px}"); } update(); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h index 8b5ca5a18..bdf03375e 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h @@ -36,6 +36,8 @@ class PhotoItem : public QWidget, public PhotoShareItem public: + enum State { New, Existing, Modified, Deleted }; + PhotoItem(PhotoShareItemHolder *holder, const RsPhotoPhoto& photo, QWidget* parent = 0); PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget* parent = 0); // for new photos. ~PhotoItem(); @@ -43,6 +45,8 @@ public: bool isSelected(){ return mSelected; } const RsPhotoPhoto& getPhotoDetails(); bool getThumbnail(RsGxsImage &image); + void markForDeletion(); + State getState() { return mState; } protected: void mousePressEvent(QMouseEvent *event); @@ -63,6 +67,7 @@ private: QPixmap getPixmap() { return mThumbNail; } bool mSelected; + State mState; PhotoShareItemHolder* mHolder; RsPhotoPhoto mPhotoDetails; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index 6b86e8a71..042430fa6 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -60,7 +60,7 @@ #define IS_ALBUM_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) #define IS_ALBUM_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) -#define IS_ALBUM_N_SUBSCR_OR_ADMIN(subscribeFlags) ((subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_MASK) == 0) +#define IS_ALBUM_N_SUBSCR_OR_ADMIN(subscribeFlags) (!IS_ALBUM_ADMIN(subscribeFlags) && !IS_ALBUM_SUBSCRIBED(subscribeFlags)) /** Constructor */ @@ -73,7 +73,8 @@ PhotoShare::PhotoShare(QWidget *parent) mPhotoSelected = NULL; connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(createAlbum())); - connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenAlbumDialog())); + connect( ui.toolButton_ViewEditAlbum, SIGNAL(clicked()), this, SLOT(OpenViewEditAlbumDialog())); + connect( ui.toolButton_EditAlbumPhotos, SIGNAL(clicked()), this, SLOT(OpenEditAlbumPhotosDialog())); connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); connect( ui.toolButton_subscribe, SIGNAL(clicked()), this, SLOT(subscribeToAlbum())); connect( ui.toolButton_ViewPhoto, SIGNAL(clicked()), this, SLOT(OpenPhotoDialog())); @@ -133,16 +134,33 @@ void PhotoShare::notifySelection(PhotoShareItem *selection) grpIds.push_back(mAlbumSelected->getAlbum().mMeta.mGroupId); requestPhotoData(grpIds); } + + /* update button status */ + /* if own album - Enable Edit Photos */ + if (IS_ALBUM_ADMIN(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + { + ui.toolButton_EditAlbumPhotos->setEnabled(true); + } + + /* is subscribed enable slideshow (includes own) */ + if (IS_ALBUM_SUBSCRIBED(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + { + ui.toolButton_SlideShow->setEnabled(true); + } + + /* enable view / subscribe - as all can use this (sub/unsub/delete) */ + ui.toolButton_ViewEditAlbum->setEnabled(true); + ui.toolButton_subscribe->setEnabled(true); } - else if((pItem = dynamic_cast(selection)) != NULL) + else if ((pItem = dynamic_cast(selection)) != NULL) { - if(mPhotoSelected == pItem) + if (mPhotoSelected == pItem) { mPhotoSelected->setSelected(true); } else { - if(mPhotoSelected == NULL) + if (mPhotoSelected == NULL) { mPhotoSelected = pItem; } @@ -174,7 +192,7 @@ void PhotoShare::checkUpdate() //insertAlbums(); std::list grpIds; rsPhoto->groupsChanged(grpIds); - if(!grpIds.empty()) + if (!grpIds.empty()) { RsTokReqOptions opts; uint32_t token; @@ -184,7 +202,7 @@ void PhotoShare::checkUpdate() GxsMsgIdResult res; rsPhoto->msgsChanged(res); - if(!res.empty()) + if (!res.empty()) requestPhotoList(res); } @@ -219,7 +237,21 @@ void PhotoShare::createAlbum() albumCreate.exec(); } -void PhotoShare::OpenAlbumDialog() +void PhotoShare::OpenViewEditAlbumDialog() +{ + if (mAlbumSelected) { + const RsPhotoAlbum &album = mAlbumSelected->getAlbum(); + GxsGroupDialog::Mode mode = GxsGroupDialog::MODE_SHOW; + bool canEdit = IS_ALBUM_ADMIN(album.mMeta.mSubscribeFlags); + if (canEdit) { + mode = GxsGroupDialog::MODE_EDIT; + } + AlbumGroupDialog agDialog(mPhotoQueue, rsPhoto->getTokenService(), mode, album.mMeta.mGroupId, this); + agDialog.exec(); + } +} + +void PhotoShare::OpenEditAlbumPhotosDialog() { if (mAlbumSelected) { AlbumDialog dlg(mAlbumSelected->getAlbum(), mPhotoQueue, rsPhoto); @@ -305,62 +337,64 @@ void PhotoShare::clearPhotos() void PhotoShare::updateAlbums() { - clearAlbums(); + // disable all buttons - as nothing is selected. + ui.toolButton_ViewEditAlbum->setEnabled(false); + ui.toolButton_EditAlbumPhotos->setEnabled(false); + ui.toolButton_subscribe->setEnabled(false); + ui.toolButton_SlideShow->setEnabled(false); + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); QSetIterator sit(mAlbumItems); - if(ui.pushButton_YourAlbums->isChecked()) + if (ui.pushButton_YourAlbums->isChecked()) { + ui.toolButton_ViewEditAlbum->setText("Edit Album Details"); + ui.toolButton_subscribe->setText("Delete Album"); + ui.toolButton_subscribe->setIcon(QIcon(":/images/album_unsubscribe.png")); - ui.toolButton_subscribe->setEnabled(false); - ui.toolButton_NewAlbum->setEnabled(true); - ui.toolButton_SlideShow->setEnabled(true); - - while(sit.hasNext()){ + while (sit.hasNext()) { AlbumItem* item = sit.next(); uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; if(IS_ALBUM_ADMIN(flags)) + { alayout->addWidget(item); + } } - }else if(ui.pushButton_SubscribedAlbums->isChecked()) + } else if (ui.pushButton_SubscribedAlbums->isChecked()) { - ui.toolButton_subscribe->setEnabled(true); + ui.toolButton_ViewEditAlbum->setText("View Album Details"); ui.toolButton_subscribe->setText("Unsubscribe From Album"); ui.toolButton_subscribe->setIcon(QIcon(":/images/album_unsubscribe.png")); - //ui.toolButton_NewAlbum->setEnabled(false); - ui.toolButton_SlideShow->setEnabled(true); - while(sit.hasNext()){ + while (sit.hasNext()) { AlbumItem* item = sit.next(); uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; - if(IS_ALBUM_SUBSCRIBED(flags)) + if(!IS_ALBUM_ADMIN(flags) && IS_ALBUM_SUBSCRIBED(flags)) { alayout->addWidget(item); + } } - }else if(ui.pushButton_SharedAlbums->isChecked()) + } else if (ui.pushButton_SharedAlbums->isChecked()) { - - ui.toolButton_subscribe->setEnabled(true); + ui.toolButton_ViewEditAlbum->setText("View Album Details"); ui.toolButton_subscribe->setText("Subscribe To Album"); ui.toolButton_subscribe->setIcon(QIcon(":/images/album_subscribe.png")); - //ui.toolButton_NewAlbum->setEnabled(false); - ui.toolButton_SlideShow->setEnabled(false); - while(sit.hasNext()){ + while (sit.hasNext()){ AlbumItem* item = sit.next(); uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; - if(IS_ALBUM_N_SUBSCR_OR_ADMIN(flags)) + if (IS_ALBUM_N_SUBSCR_OR_ADMIN(flags)) { alayout->addWidget(item); - + } } } } @@ -370,13 +404,13 @@ void PhotoShare::deleteAlbum(const RsGxsGroupId &grpId) QSetIterator sit(mAlbumItems); - while(sit.hasNext()) + while (sit.hasNext()) { AlbumItem* item = sit.next(); - if(item->getAlbum().mMeta.mGroupId == grpId){ + if (item->getAlbum().mMeta.mGroupId == grpId){ - if(mAlbumSelected == item) + if (mAlbumSelected == item) { item->setSelected(false); mAlbumSelected = NULL; @@ -394,8 +428,6 @@ void PhotoShare::deleteAlbum(const RsGxsGroupId &grpId) void PhotoShare::addAlbum(const RsPhotoAlbum &album) { - std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - deleteAlbum(album.mMeta.mGroupId); // remove from ui AlbumItem *item = new AlbumItem(album, this, this); mAlbumItems.insert(item); @@ -404,29 +436,36 @@ void PhotoShare::addAlbum(const RsPhotoAlbum &album) void PhotoShare::addPhoto(const RsPhotoPhoto &photo) { - std::cerr << "PhotoShare::addPhoto() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - - PhotoItem* item = new PhotoItem(this, photo, this); - mPhotoItems.insert(item); + if (!photo.mThumbnail.empty()) + { + PhotoItem* item = new PhotoItem(this, photo, this); + mPhotoItems.insert(item); + } } void PhotoShare::subscribeToAlbum() { - if(mAlbumSelected){ + if (mAlbumSelected){ RsGxsGroupId id = mAlbumSelected->getAlbum().mMeta.mGroupId; uint32_t token; - if(IS_ALBUM_SUBSCRIBED(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + if (IS_ALBUM_ADMIN(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + { + // TODO support delete. + return; + } + else if (IS_ALBUM_SUBSCRIBED(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + { rsPhoto->subscribeToAlbum(token, id, false); - else if(IS_ALBUM_ADMIN(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) - return; - else if(IS_ALBUM_N_SUBSCR_OR_ADMIN( - mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + } + else if (IS_ALBUM_N_SUBSCR_OR_ADMIN(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + { rsPhoto->subscribeToAlbum(token, id, true); + } else + { return; + } mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); } @@ -435,11 +474,11 @@ void PhotoShare::subscribeToAlbum() void PhotoShare::updatePhotos() { - if(mAlbumSelected) + if (mAlbumSelected) { QSetIterator sit(mPhotoItems); - while(sit.hasNext()) + while (sit.hasNext()) { QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); layout->addWidget(sit.next()); @@ -449,43 +488,16 @@ void PhotoShare::updatePhotos() /**************************** Request / Response Filling of Data ************************/ - -void PhotoShare::requestAlbumList(std::list& ids) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - uint32_t token; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); -} - void PhotoShare::requestPhotoList(GxsMsgReq& req) { RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); return; } - -void PhotoShare::loadAlbumList(const uint32_t &token) -{ - std::cerr << "PhotoShare::loadAlbumList()"; - std::cerr << std::endl; - - std::list albumIds; - rsPhoto->getGroupList(token, albumIds); - - requestAlbumData(albumIds); - - std::list::iterator it; - for(it = albumIds.begin(); it != albumIds.end(); ++it) - { - requestPhotoList(*it); - } -} - - void PhotoShare::requestAlbumData(std::list &ids) { RsTokReqOptions opts; @@ -504,20 +516,14 @@ void PhotoShare::requestAlbumData() bool PhotoShare::loadAlbumData(const uint32_t &token) { - std::cerr << "PhotoShare::loadAlbumData()"; - std::cerr << std::endl; - std::vector albums; rsPhoto->getAlbum(token, albums); std::vector::iterator vit = albums.begin(); - for(; vit != albums.end(); ++vit) + for (; vit != albums.end(); ++vit) { RsPhotoAlbum& album = *vit; - - std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - addAlbum(album); } @@ -528,7 +534,6 @@ bool PhotoShare::loadAlbumData(const uint32_t &token) void PhotoShare::requestPhotoList(const RsGxsGroupId &albumId) { - std::list grpIds; grpIds.push_back(albumId); RsTokReqOptions opts; @@ -544,7 +549,7 @@ void PhotoShare::acknowledgeGroup(const uint32_t &token) RsGxsGroupId grpId; rsPhoto->acknowledgeGrp(token, grpId); - if(!grpId.isNull()) + if (!grpId.isNull()) { std::list grpIds; grpIds.push_back(grpId); @@ -560,29 +565,10 @@ void PhotoShare::acknowledgeMessage(const uint32_t &token) { std::pair p; rsPhoto->acknowledgeMsg(token, p); - - // just acknowledge don't load it - // loading is only instigated by clicking an album (i.e. requesting photo data) - // but load it if the album is selected -// if(!p.first.empty()) -// { -// if(mAlbumSelected) -// { -// if(mAlbumSelected->getAlbum().mMeta.mGroupId == p.first) -// { -// std::list grpIds; -// grpIds.push_back(p.first); -// requestPhotoData(grpIds); -// } -// } -// } } void PhotoShare::loadPhotoList(const uint32_t &token) { - std::cerr << "PhotoShare::loadPhotoList()"; - std::cerr << std::endl; - GxsMsgIdResult res; rsPhoto->getMsgList(token, res); @@ -602,6 +588,7 @@ void PhotoShare::requestPhotoData(const std::list& grpIds) { RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); } @@ -609,9 +596,6 @@ void PhotoShare::requestPhotoData(const std::list& grpIds) void PhotoShare::loadPhotoData(const uint32_t &token) { - std::cerr << "PhotoShare::loadPhotoData()"; - std::cerr << std::endl; - clearPhotos(); PhotoResult res; @@ -619,18 +603,15 @@ void PhotoShare::loadPhotoData(const uint32_t &token) PhotoResult::iterator mit = res.begin(); - for(; mit != res.end(); ++mit) + for (; mit != res.end(); ++mit) { std::vector& photoV = mit->second; std::vector::iterator vit = photoV.begin(); - for(; vit != photoV.end(); ++vit) + for (; vit != photoV.end(); ++vit) { RsPhotoPhoto& photo = *vit; addPhoto(photo); - std::cerr << "PhotoShare::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; } } updatePhotos(); @@ -641,9 +622,6 @@ void PhotoShare::loadPhotoData(const uint32_t &token) void PhotoShare::loadRequest(const TokenQueue *queue, const TokenRequest &req) { - std::cerr << "PhotoShare::loadRequest()"; - std::cerr << std::endl; - if (queue == mPhotoQueue) { /* now switch on req */ @@ -652,9 +630,6 @@ void PhotoShare::loadRequest(const TokenQueue *queue, const TokenRequest &req) case TOKENREQ_GROUPINFO: switch(req.mAnsType) { - case RS_TOKREQ_ANSTYPE_LIST: - loadAlbumList(req.mToken); - break; case RS_TOKREQ_ANSTYPE_DATA: loadAlbumData(req.mToken); break; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h index 2462fea44..ea13e7669 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h @@ -61,7 +61,8 @@ public: private slots: void checkUpdate(); void createAlbum(); - void OpenAlbumDialog(); + void OpenViewEditAlbumDialog(); + void OpenEditAlbumPhotosDialog(); void OpenPhotoDialog(); void OpenSlideShow(); void updateAlbums(); @@ -70,7 +71,6 @@ private slots: private: /* Request Response Functions for loading data */ - void requestAlbumList(std::list &ids); void requestAlbumData(std::list &ids); /*! @@ -82,7 +82,6 @@ private: void requestPhotoData(GxsMsgReq &photoIds); void requestPhotoData(const std::list &grpIds); - void loadAlbumList(const uint32_t &token); bool loadAlbumData(const uint32_t &token); void loadPhotoList(const uint32_t &token); void loadPhotoData(const uint32_t &token); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index 78e3ed538..5a6204006 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -20,7 +20,16 @@ - + + 2 + + + 2 + + + 2 + + 2 @@ -47,9 +56,29 @@ - + - View Album + Edit Album Details + + + + :/images/add_image24.png:/images/add_image24.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + Edit Album Photos @@ -140,7 +169,16 @@ 6 - + + 0 + + + 0 + + + 0 + + 0 @@ -245,7 +283,7 @@ 0 0 804 - 208 + 197 @@ -281,13 +319,13 @@ 0 0 804 - 208 + 196 QWidget#scrollAreaWidgetContents{border: none;} - +