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
This commit is contained in:
drbob 2020-02-25 00:11:51 +11:00
parent be4d812df2
commit 5d0e2bb71e
10 changed files with 556 additions and 484 deletions

View File

@ -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;

View File

@ -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

View File

@ -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<PhotoItem*> photos;
@ -82,26 +88,59 @@ void AlbumDialog::updateAlbumPhotos(){
QSetIterator<PhotoItem*> 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<PhotoItem*>(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<RsGxsGroupId> 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<RsGxsGroupId, RsGxsMessageId> 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<RsPhotoPhoto>& photoV = mit->second;
std::vector<RsPhotoPhoto>::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 ************************/

View File

@ -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;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>725</width>
<height>427</height>
<width>795</width>
<height>597</height>
</rect>
</property>
<property name="windowTitle">
@ -16,354 +16,208 @@
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QFrame" name="frame">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="HeaderFrame" name="headerFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,10,0">
<item>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>10</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QWidget" name="layoutWidget_2">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QGroupBox" name="albumGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Album Thumbnail</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_thumbNail">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>10</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Summary</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Album Title:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_Title">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Category:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Category">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Caption</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_Caption">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Where:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_Where">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>When</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_When">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Description:</string>
</property>
</widget>
</item>
<item row="5" column="1" rowspan="2">
<widget class="QTextEdit" name="textEdit_description">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="2">
<widget class="QLineEdit" name="lineEdit_Title">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Category:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="lineEdit_Category">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="3">
<widget class="QFrame" name="albumGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>10</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
<widget class="QLabel" name="label_thumbNail">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="title">
<string>Share Options</string>
<property name="text">
<string>TextLabel</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_Visibility">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Comments</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Publish Identity</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_Identity">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Visibility</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Comments">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget_3">
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,10">
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="lineEdit_Caption">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Caption</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Album Title:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; font-weight:600;&quot;&gt; Drag &amp;amp; Drop to insert pictures. Click on a picture to edit details below.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollAreaPhotos">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<widget class="PhotoDrop" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>737</width>
<height>315</height>
</rect>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollAreaPhotos">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>true</bool>
<property name="styleSheet">
<string notr="true">QWidget#scrollAreaWidgetContents{border: none;}</string>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<widget class="PhotoDrop" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>701</width>
<height>69</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QWidget#scrollAreaWidgetContents{border: none;}</string>
</property>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_AddPhoto">
@ -418,16 +272,6 @@ p, li { white-space: pre-wrap; }
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="HeaderFrame" name="headerFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -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();
}

View File

@ -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;

View File

@ -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<PhotoItem*>(selection)) != NULL)
else if ((pItem = dynamic_cast<PhotoItem*>(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<RsGxsGroupId> 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<AlbumItem*> 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<AlbumItem*> 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<PhotoItem*> 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<RsGxsGroupId>& 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<RsGxsGroupId> albumIds;
rsPhoto->getGroupList(token, albumIds);
requestAlbumData(albumIds);
std::list<RsGxsGroupId>::iterator it;
for(it = albumIds.begin(); it != albumIds.end(); ++it)
{
requestPhotoList(*it);
}
}
void PhotoShare::requestAlbumData(std::list<RsGxsGroupId> &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<RsPhotoAlbum> albums;
rsPhoto->getAlbum(token, albums);
std::vector<RsPhotoAlbum>::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<RsGxsGroupId> 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<RsGxsGroupId> grpIds;
grpIds.push_back(grpId);
@ -560,29 +565,10 @@ void PhotoShare::acknowledgeMessage(const uint32_t &token)
{
std::pair<RsGxsGroupId, RsGxsMessageId> 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<RsGxsGroupId> 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<RsGxsGroupId>& 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<RsGxsGroupId>& 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<RsPhotoPhoto>& photoV = mit->second;
std::vector<RsPhotoPhoto>::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;

View File

@ -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<RsGxsGroupId> &ids);
void requestAlbumData(std::list<RsGxsGroupId> &ids);
/*!
@ -82,7 +82,6 @@ private:
void requestPhotoData(GxsMsgReq &photoIds);
void requestPhotoData(const std::list<RsGxsGroupId> &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);

View File

@ -20,7 +20,16 @@
<item>
<widget class="QFrame" name="toolBarFrame">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="margin">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
@ -47,9 +56,29 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_ViewAlbum">
<widget class="QToolButton" name="toolButton_ViewEditAlbum">
<property name="text">
<string>View Album</string>
<string>Edit Album Details</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/add_image24.png</normaloff>:/images/add_image24.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_EditAlbumPhotos">
<property name="text">
<string>Edit Album Photos</string>
</property>
<property name="icon">
<iconset resource="Photo_images.qrc">
@ -140,7 +169,16 @@
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -245,7 +283,7 @@
<x>0</x>
<y>0</y>
<width>804</width>
<height>208</height>
<height>197</height>
</rect>
</property>
<property name="styleSheet">
@ -281,13 +319,13 @@
<x>0</x>
<y>0</y>
<width>804</width>
<height>208</height>
<height>196</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QWidget#scrollAreaWidgetContents{border: none;}</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">